Merck / Mbed OS SmartCap_OS5

Dependencies:   nRF51822

Committer:
sgetz7908
Date:
Tue May 23 13:38:38 2017 +0000
Revision:
7:090f9eea7b3c
Parent:
4:1bfa16834dd4
Child:
9:0b017e956142
Initial SmartCap Code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sgetz7908 2:def2c045c43a 1 //**********************************************************************
sgetz7908 2:def2c045c43a 2 //
sgetz7908 2:def2c045c43a 3 // Hardware Routines
sgetz7908 2:def2c045c43a 4 //
sgetz7908 2:def2c045c43a 5 // SPG 12/13/2016
sgetz7908 2:def2c045c43a 6 //
sgetz7908 2:def2c045c43a 7 //**********************************************************************
sgetz7908 2:def2c045c43a 8
sgetz7908 2:def2c045c43a 9 /// @file hw.cpp
sgetz7908 2:def2c045c43a 10
sgetz7908 2:def2c045c43a 11 #include "mbed.h"
sgetz7908 2:def2c045c43a 12 #include "hw.h"
sgetz7908 2:def2c045c43a 13 #include "nrf_delay.h"
sgetz7908 2:def2c045c43a 14 #include "nrf_gpio.h"
sgetz7908 2:def2c045c43a 15
sgetz7908 2:def2c045c43a 16
sgetz7908 2:def2c045c43a 17 Ticker seconds_ticker;
sgetz7908 2:def2c045c43a 18 volatile uint32_t seconds = 0; // seconds clock, time since power up
sgetz7908 2:def2c045c43a 19 volatile uint32_t sec_offset = 0; // when the actual time is set, this will contain the difference between actual time and the above variable
sgetz7908 2:def2c045c43a 20
sgetz7908 2:def2c045c43a 21
sgetz7908 2:def2c045c43a 22 /// Software generate delay.
sgetz7908 2:def2c045c43a 23 /// Interrupt can increase the delay length.
sgetz7908 2:def2c045c43a 24 /// CPU runs at full power during delay.
sgetz7908 2:def2c045c43a 25 void delay_ms(uint32_t volatile number_of_ms)
sgetz7908 2:def2c045c43a 26 {
sgetz7908 2:def2c045c43a 27 while(number_of_ms != 0) {
sgetz7908 2:def2c045c43a 28 number_of_ms--;
sgetz7908 2:def2c045c43a 29 nrf_delay_us(999);
sgetz7908 2:def2c045c43a 30 }
sgetz7908 2:def2c045c43a 31 }
sgetz7908 2:def2c045c43a 32
sgetz7908 2:def2c045c43a 33 // RTC in seconds since boot
sgetz7908 2:def2c045c43a 34 static void seconds_ticker_interrupt(void)
sgetz7908 2:def2c045c43a 35 {
sgetz7908 2:def2c045c43a 36 seconds++;
sgetz7908 2:def2c045c43a 37 }
sgetz7908 2:def2c045c43a 38
sgetz7908 2:def2c045c43a 39 /// Initialize the seconds clock to 's' seconds
sgetz7908 2:def2c045c43a 40 void init_clock(uint32_t s)
sgetz7908 2:def2c045c43a 41 {
sgetz7908 2:def2c045c43a 42 seconds_ticker.detach();
sgetz7908 2:def2c045c43a 43 seconds_ticker.attach(seconds_ticker_interrupt, 1.00);
sgetz7908 2:def2c045c43a 44 seconds = s;
sgetz7908 2:def2c045c43a 45 }
sgetz7908 2:def2c045c43a 46
sgetz7908 2:def2c045c43a 47 /// Read the number of seconds since init_clock() was called
sgetz7908 2:def2c045c43a 48 uint32_t read_clock(void)
sgetz7908 2:def2c045c43a 49 {
sgetz7908 2:def2c045c43a 50 return seconds;
sgetz7908 2:def2c045c43a 51 }
sgetz7908 2:def2c045c43a 52
sgetz7908 2:def2c045c43a 53 /// Set sec_offset by passing the current time, so correct time/date can be be found by adding sec_offset to internal time
sgetz7908 2:def2c045c43a 54 void set_time_offset(uint32_t s)
sgetz7908 2:def2c045c43a 55 {
sgetz7908 2:def2c045c43a 56 sec_offset = s - read_clock();
sgetz7908 2:def2c045c43a 57 }
sgetz7908 2:def2c045c43a 58
sgetz7908 2:def2c045c43a 59 /// Return the time correction value, add this to the internal time to get real time
sgetz7908 2:def2c045c43a 60 uint32_t read_time_correction(void)
sgetz7908 2:def2c045c43a 61 {
sgetz7908 2:def2c045c43a 62 return sec_offset;
sgetz7908 2:def2c045c43a 63 }
sgetz7908 2:def2c045c43a 64
sgetz7908 2:def2c045c43a 65 /// 10-bit ADC reading of the requested channel
sgetz7908 2:def2c045c43a 66 /// Uses internal 1.2V reference, and 1/3 of the signal source.
sgetz7908 2:def2c045c43a 67 /// This provides a result = Voltage/3.6*1023
sgetz7908 2:def2c045c43a 68 /// @param chan is the channel to read
sgetz7908 2:def2c045c43a 69 /// @param times is the number of readings to take
sgetz7908 4:1bfa16834dd4 70 /// @return avg of all the readings
sgetz7908 2:def2c045c43a 71 uint16_t adc_read(int chan, int num_readings)
sgetz7908 2:def2c045c43a 72 {
sgetz7908 2:def2c045c43a 73 uint16_t result = 0;
sgetz7908 2:def2c045c43a 74 int times = num_readings;
sgetz7908 2:def2c045c43a 75
sgetz7908 2:def2c045c43a 76 NRF_ADC->INTENCLR = ADC_INTENCLR_END_Clear; // turn off ADC interrupts
sgetz7908 2:def2c045c43a 77 //NRF_ADC->EVENTS_END = 0;
sgetz7908 2:def2c045c43a 78
sgetz7908 2:def2c045c43a 79 switch(chan) {
sgetz7908 2:def2c045c43a 80 case ADC_CHAN_BATTERY:
sgetz7908 2:def2c045c43a 81 NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
sgetz7908 2:def2c045c43a 82 (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
sgetz7908 2:def2c045c43a 83 (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
sgetz7908 2:def2c045c43a 84 (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) |
sgetz7908 2:def2c045c43a 85 (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
sgetz7908 2:def2c045c43a 86 break;
sgetz7908 2:def2c045c43a 87
sgetz7908 7:090f9eea7b3c 88 case ADC_CHAN_CAP_SENSE:
sgetz7908 2:def2c045c43a 89 NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
sgetz7908 2:def2c045c43a 90 (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
sgetz7908 2:def2c045c43a 91 (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
sgetz7908 2:def2c045c43a 92 (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos) |
sgetz7908 2:def2c045c43a 93 (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
sgetz7908 2:def2c045c43a 94 break;
sgetz7908 2:def2c045c43a 95
sgetz7908 2:def2c045c43a 96 default:
sgetz7908 2:def2c045c43a 97 return 0;
sgetz7908 2:def2c045c43a 98 }
sgetz7908 2:def2c045c43a 99
sgetz7908 2:def2c045c43a 100 NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled; // enable ADC
sgetz7908 2:def2c045c43a 101
sgetz7908 2:def2c045c43a 102 while(times--) {
sgetz7908 2:def2c045c43a 103 NRF_ADC->TASKS_START = 1; // start ADC conversion
sgetz7908 2:def2c045c43a 104
sgetz7908 2:def2c045c43a 105 // wait for conversion to end
sgetz7908 2:def2c045c43a 106 while (!NRF_ADC->EVENTS_END) {
sgetz7908 2:def2c045c43a 107 ;
sgetz7908 2:def2c045c43a 108 }
sgetz7908 2:def2c045c43a 109
sgetz7908 2:def2c045c43a 110 NRF_ADC->EVENTS_END = 0;
sgetz7908 2:def2c045c43a 111 result += NRF_ADC->RESULT; //Save your ADC result
sgetz7908 2:def2c045c43a 112 NRF_ADC->TASKS_STOP = 1; //Use the STOP task to save current.
sgetz7908 2:def2c045c43a 113 }
sgetz7908 2:def2c045c43a 114
sgetz7908 2:def2c045c43a 115 //NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled;
sgetz7908 2:def2c045c43a 116 return (uint16_t)result/num_readings; // 10 bit
sgetz7908 2:def2c045c43a 117 }
sgetz7908 2:def2c045c43a 118
sgetz7908 2:def2c045c43a 119 /// Reads the battery voltage
sgetz7908 2:def2c045c43a 120 /// Returns the voltage as an int * 100. 3V = 300
sgetz7908 2:def2c045c43a 121 uint16_t read_battery_voltage(void)
sgetz7908 2:def2c045c43a 122 {
sgetz7908 2:def2c045c43a 123 return ((float)adc_read(ADC_CHAN_BATTERY,4)*3.6)/1023.0*100.0;
sgetz7908 2:def2c045c43a 124 }
sgetz7908 2:def2c045c43a 125
sgetz7908 2:def2c045c43a 126 char str_buf[21];
sgetz7908 2:def2c045c43a 127
sgetz7908 2:def2c045c43a 128 /// Convert unsigned int to string
sgetz7908 2:def2c045c43a 129 /// @returns pointer to string
sgetz7908 2:def2c045c43a 130 char * uli2a(uint32_t num)
sgetz7908 2:def2c045c43a 131 {
sgetz7908 2:def2c045c43a 132 char * buf = str_buf;
sgetz7908 2:def2c045c43a 133 //int n=0;
sgetz7908 2:def2c045c43a 134 unsigned long d=1;
sgetz7908 2:def2c045c43a 135 while (num/d >= 10)
sgetz7908 2:def2c045c43a 136 d*=10;
sgetz7908 2:def2c045c43a 137 while (d!=0) {
sgetz7908 2:def2c045c43a 138 int dgt = num / d;
sgetz7908 2:def2c045c43a 139 num%=d;
sgetz7908 2:def2c045c43a 140 d/=10;
sgetz7908 2:def2c045c43a 141 *buf++ = dgt+'0';
sgetz7908 2:def2c045c43a 142 //n++;
sgetz7908 2:def2c045c43a 143 }
sgetz7908 2:def2c045c43a 144 *buf=0;
sgetz7908 2:def2c045c43a 145
sgetz7908 2:def2c045c43a 146 return str_buf;
sgetz7908 2:def2c045c43a 147 }
sgetz7908 2:def2c045c43a 148
sgetz7908 2:def2c045c43a 149 char hexdig(char c)
sgetz7908 2:def2c045c43a 150 {
sgetz7908 2:def2c045c43a 151 if(c<10) return c+'0';
sgetz7908 2:def2c045c43a 152 return c-10+'a';
sgetz7908 2:def2c045c43a 153 }
sgetz7908 2:def2c045c43a 154
sgetz7908 2:def2c045c43a 155 /// Convert unsigned char to string, 2 digit hex
sgetz7908 2:def2c045c43a 156 /// @returns pointer to string
sgetz7908 2:def2c045c43a 157 char * char2hex(char c)
sgetz7908 2:def2c045c43a 158 {
sgetz7908 2:def2c045c43a 159 char * buf = str_buf;
sgetz7908 2:def2c045c43a 160
sgetz7908 2:def2c045c43a 161 *buf++ = hexdig(c>>4);
sgetz7908 2:def2c045c43a 162 *buf++ = hexdig(c&0x0f);
sgetz7908 2:def2c045c43a 163 *buf=0;
sgetz7908 2:def2c045c43a 164
sgetz7908 2:def2c045c43a 165 return str_buf;
sgetz7908 2:def2c045c43a 166 }
sgetz7908 2:def2c045c43a 167
sgetz7908 2:def2c045c43a 168 /// Converts an unsigned 32 bit int to a hex string,
sgetz7908 2:def2c045c43a 169 /// 'digits' specifies the number of hex digits to output
sgetz7908 2:def2c045c43a 170 /// output string is null terminated
sgetz7908 2:def2c045c43a 171 char * char2hex(uint32_t n, int digits)
sgetz7908 2:def2c045c43a 172 {
sgetz7908 2:def2c045c43a 173 char * buf = str_buf+digits;
sgetz7908 2:def2c045c43a 174 *buf-- = 0; // null terminator
sgetz7908 2:def2c045c43a 175
sgetz7908 2:def2c045c43a 176 if(digits>0 && digits<20) {
sgetz7908 2:def2c045c43a 177 while(digits-->0) {
sgetz7908 2:def2c045c43a 178 *buf-- = hexdig(n & 0x0f);
sgetz7908 2:def2c045c43a 179 n = n>>4;
sgetz7908 2:def2c045c43a 180 }
sgetz7908 2:def2c045c43a 181 }
sgetz7908 2:def2c045c43a 182 else
sgetz7908 2:def2c045c43a 183 {
sgetz7908 2:def2c045c43a 184 return "";
sgetz7908 2:def2c045c43a 185 }
sgetz7908 2:def2c045c43a 186
sgetz7908 2:def2c045c43a 187 return str_buf;
sgetz7908 2:def2c045c43a 188 }