Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: nRF51822
Source/hw.cpp@24:761c30334cf4, 2019-03-21 (annotated)
- Committer:
- sgetz7908
- Date:
- Thu Mar 21 19:28:22 2019 +0000
- Revision:
- 24:761c30334cf4
- Parent:
- 23:7ca590427f0e
- Child:
- 43:7a9cfb57f9e8
Test mode added; needs testing and DATA flag; Needs EOL stuff
Who changed what in which revision?
| User | Revision | Line number | New 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 | 9:0b017e956142 | 33 | void set_rtc(uint32_t s) |
| sgetz7908 | 9:0b017e956142 | 34 | { |
| sgetz7908 | 9:0b017e956142 | 35 | seconds = s; |
| sgetz7908 | 9:0b017e956142 | 36 | } |
| sgetz7908 | 9:0b017e956142 | 37 | |
| sgetz7908 | 9:0b017e956142 | 38 | void update_rtc(uint32_t s) |
| sgetz7908 | 9:0b017e956142 | 39 | { |
| sgetz7908 | 9:0b017e956142 | 40 | seconds += s; |
| sgetz7908 | 9:0b017e956142 | 41 | } |
| sgetz7908 | 9:0b017e956142 | 42 | |
| sgetz7908 | 2:def2c045c43a | 43 | // RTC in seconds since boot |
| sgetz7908 | 2:def2c045c43a | 44 | static void seconds_ticker_interrupt(void) |
| sgetz7908 | 2:def2c045c43a | 45 | { |
| sgetz7908 | 9:0b017e956142 | 46 | seconds += 1; |
| sgetz7908 | 2:def2c045c43a | 47 | } |
| sgetz7908 | 2:def2c045c43a | 48 | |
| sgetz7908 | 2:def2c045c43a | 49 | /// Initialize the seconds clock to 's' seconds |
| sgetz7908 | 2:def2c045c43a | 50 | void init_clock(uint32_t s) |
| sgetz7908 | 2:def2c045c43a | 51 | { |
| sgetz7908 | 2:def2c045c43a | 52 | seconds_ticker.detach(); |
| sgetz7908 | 2:def2c045c43a | 53 | seconds_ticker.attach(seconds_ticker_interrupt, 1.00); |
| sgetz7908 | 2:def2c045c43a | 54 | seconds = s; |
| sgetz7908 | 2:def2c045c43a | 55 | } |
| sgetz7908 | 2:def2c045c43a | 56 | |
| sgetz7908 | 2:def2c045c43a | 57 | /// Read the number of seconds since init_clock() was called |
| sgetz7908 | 2:def2c045c43a | 58 | uint32_t read_clock(void) |
| sgetz7908 | 2:def2c045c43a | 59 | { |
| sgetz7908 | 2:def2c045c43a | 60 | return seconds; |
| sgetz7908 | 2:def2c045c43a | 61 | } |
| sgetz7908 | 2:def2c045c43a | 62 | |
| sgetz7908 | 2:def2c045c43a | 63 | /// 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 | 64 | void set_time_offset(uint32_t s) |
| sgetz7908 | 2:def2c045c43a | 65 | { |
| sgetz7908 | 2:def2c045c43a | 66 | sec_offset = s - read_clock(); |
| sgetz7908 | 2:def2c045c43a | 67 | } |
| sgetz7908 | 2:def2c045c43a | 68 | |
| sgetz7908 | 2:def2c045c43a | 69 | /// Return the time correction value, add this to the internal time to get real time |
| sgetz7908 | 2:def2c045c43a | 70 | uint32_t read_time_correction(void) |
| sgetz7908 | 2:def2c045c43a | 71 | { |
| sgetz7908 | 2:def2c045c43a | 72 | return sec_offset; |
| sgetz7908 | 2:def2c045c43a | 73 | } |
| sgetz7908 | 2:def2c045c43a | 74 | |
| sgetz7908 | 2:def2c045c43a | 75 | /// 10-bit ADC reading of the requested channel |
| sgetz7908 | 2:def2c045c43a | 76 | /// Uses internal 1.2V reference, and 1/3 of the signal source. |
| sgetz7908 | 2:def2c045c43a | 77 | /// This provides a result = Voltage/3.6*1023 |
| sgetz7908 | 2:def2c045c43a | 78 | /// @param chan is the channel to read |
| sgetz7908 | 2:def2c045c43a | 79 | /// @param times is the number of readings to take |
| sgetz7908 | 4:1bfa16834dd4 | 80 | /// @return avg of all the readings |
| sgetz7908 | 10:b3553e75eee0 | 81 | int adc_read(int chan, int num_readings) |
| sgetz7908 | 2:def2c045c43a | 82 | { |
| sgetz7908 | 10:b3553e75eee0 | 83 | int result = 0; |
| sgetz7908 | 2:def2c045c43a | 84 | int times = num_readings; |
| sgetz7908 | 2:def2c045c43a | 85 | |
| sgetz7908 | 2:def2c045c43a | 86 | NRF_ADC->INTENCLR = ADC_INTENCLR_END_Clear; // turn off ADC interrupts |
| sgetz7908 | 2:def2c045c43a | 87 | //NRF_ADC->EVENTS_END = 0; |
| sgetz7908 | 2:def2c045c43a | 88 | |
| sgetz7908 | 2:def2c045c43a | 89 | switch(chan) { |
| sgetz7908 | 2:def2c045c43a | 90 | case ADC_CHAN_BATTERY: |
| sgetz7908 | 2:def2c045c43a | 91 | NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) | |
| sgetz7908 | 2:def2c045c43a | 92 | (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) | |
| sgetz7908 | 2:def2c045c43a | 93 | (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) | |
| sgetz7908 | 2:def2c045c43a | 94 | (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) | |
| sgetz7908 | 2:def2c045c43a | 95 | (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); |
| sgetz7908 | 2:def2c045c43a | 96 | break; |
| sgetz7908 | 2:def2c045c43a | 97 | |
| sgetz7908 | 7:090f9eea7b3c | 98 | case ADC_CHAN_CAP_SENSE: |
| sgetz7908 | 2:def2c045c43a | 99 | NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) | |
| sgetz7908 | 2:def2c045c43a | 100 | (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) | |
| sgetz7908 | 2:def2c045c43a | 101 | (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) | |
| sgetz7908 | 2:def2c045c43a | 102 | (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos) | |
| sgetz7908 | 2:def2c045c43a | 103 | (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); |
| sgetz7908 | 2:def2c045c43a | 104 | break; |
| sgetz7908 | 24:761c30334cf4 | 105 | |
| sgetz7908 | 24:761c30334cf4 | 106 | case ADC_CHAN_LIGHT_SENSE: |
| sgetz7908 | 24:761c30334cf4 | 107 | NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) | |
| sgetz7908 | 24:761c30334cf4 | 108 | (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) | |
| sgetz7908 | 24:761c30334cf4 | 109 | (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) | |
| sgetz7908 | 24:761c30334cf4 | 110 | (ADC_CONFIG_PSEL_AnalogInput4 << ADC_CONFIG_PSEL_Pos) | |
| sgetz7908 | 24:761c30334cf4 | 111 | (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); |
| sgetz7908 | 24:761c30334cf4 | 112 | break; |
| sgetz7908 | 2:def2c045c43a | 113 | |
| sgetz7908 | 2:def2c045c43a | 114 | default: |
| sgetz7908 | 2:def2c045c43a | 115 | return 0; |
| sgetz7908 | 2:def2c045c43a | 116 | } |
| sgetz7908 | 2:def2c045c43a | 117 | |
| sgetz7908 | 2:def2c045c43a | 118 | NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled; // enable ADC |
| sgetz7908 | 2:def2c045c43a | 119 | |
| sgetz7908 | 2:def2c045c43a | 120 | while(times--) { |
| sgetz7908 | 2:def2c045c43a | 121 | NRF_ADC->TASKS_START = 1; // start ADC conversion |
| sgetz7908 | 2:def2c045c43a | 122 | |
| sgetz7908 | 2:def2c045c43a | 123 | // wait for conversion to end |
| sgetz7908 | 2:def2c045c43a | 124 | while (!NRF_ADC->EVENTS_END) { |
| sgetz7908 | 2:def2c045c43a | 125 | ; |
| sgetz7908 | 2:def2c045c43a | 126 | } |
| sgetz7908 | 2:def2c045c43a | 127 | |
| sgetz7908 | 2:def2c045c43a | 128 | NRF_ADC->EVENTS_END = 0; |
| sgetz7908 | 2:def2c045c43a | 129 | result += NRF_ADC->RESULT; //Save your ADC result |
| sgetz7908 | 2:def2c045c43a | 130 | NRF_ADC->TASKS_STOP = 1; //Use the STOP task to save current. |
| sgetz7908 | 2:def2c045c43a | 131 | } |
| sgetz7908 | 2:def2c045c43a | 132 | |
| sgetz7908 | 2:def2c045c43a | 133 | //NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled; |
| sgetz7908 | 10:b3553e75eee0 | 134 | return (int)result/num_readings; // 10 bit |
| sgetz7908 | 2:def2c045c43a | 135 | } |
| sgetz7908 | 2:def2c045c43a | 136 | |
| sgetz7908 | 2:def2c045c43a | 137 | /// Reads the battery voltage |
| sgetz7908 | 2:def2c045c43a | 138 | /// Returns the voltage as an int * 100. 3V = 300 |
| sgetz7908 | 10:b3553e75eee0 | 139 | int read_battery_voltage(void) |
| sgetz7908 | 2:def2c045c43a | 140 | { |
| sgetz7908 | 2:def2c045c43a | 141 | return ((float)adc_read(ADC_CHAN_BATTERY,4)*3.6)/1023.0*100.0; |
| sgetz7908 | 2:def2c045c43a | 142 | } |
| sgetz7908 | 2:def2c045c43a | 143 | |
| sgetz7908 | 2:def2c045c43a | 144 | char str_buf[21]; |
| sgetz7908 | 2:def2c045c43a | 145 | |
| sgetz7908 | 2:def2c045c43a | 146 | /// Convert unsigned int to string |
| sgetz7908 | 2:def2c045c43a | 147 | /// @returns pointer to string |
| sgetz7908 | 2:def2c045c43a | 148 | char * uli2a(uint32_t num) |
| sgetz7908 | 2:def2c045c43a | 149 | { |
| sgetz7908 | 2:def2c045c43a | 150 | char * buf = str_buf; |
| sgetz7908 | 2:def2c045c43a | 151 | //int n=0; |
| sgetz7908 | 2:def2c045c43a | 152 | unsigned long d=1; |
| sgetz7908 | 2:def2c045c43a | 153 | while (num/d >= 10) |
| sgetz7908 | 2:def2c045c43a | 154 | d*=10; |
| sgetz7908 | 2:def2c045c43a | 155 | while (d!=0) { |
| sgetz7908 | 2:def2c045c43a | 156 | int dgt = num / d; |
| sgetz7908 | 2:def2c045c43a | 157 | num%=d; |
| sgetz7908 | 2:def2c045c43a | 158 | d/=10; |
| sgetz7908 | 2:def2c045c43a | 159 | *buf++ = dgt+'0'; |
| sgetz7908 | 2:def2c045c43a | 160 | //n++; |
| sgetz7908 | 2:def2c045c43a | 161 | } |
| sgetz7908 | 2:def2c045c43a | 162 | *buf=0; |
| sgetz7908 | 2:def2c045c43a | 163 | |
| sgetz7908 | 2:def2c045c43a | 164 | return str_buf; |
| sgetz7908 | 2:def2c045c43a | 165 | } |
| sgetz7908 | 2:def2c045c43a | 166 | |
| sgetz7908 | 2:def2c045c43a | 167 | char hexdig(char c) |
| sgetz7908 | 2:def2c045c43a | 168 | { |
| sgetz7908 | 2:def2c045c43a | 169 | if(c<10) return c+'0'; |
| sgetz7908 | 2:def2c045c43a | 170 | return c-10+'a'; |
| sgetz7908 | 2:def2c045c43a | 171 | } |
| sgetz7908 | 2:def2c045c43a | 172 | |
| sgetz7908 | 2:def2c045c43a | 173 | /// Convert unsigned char to string, 2 digit hex |
| sgetz7908 | 2:def2c045c43a | 174 | /// @returns pointer to string |
| sgetz7908 | 2:def2c045c43a | 175 | char * char2hex(char c) |
| sgetz7908 | 2:def2c045c43a | 176 | { |
| sgetz7908 | 2:def2c045c43a | 177 | char * buf = str_buf; |
| sgetz7908 | 2:def2c045c43a | 178 | |
| sgetz7908 | 2:def2c045c43a | 179 | *buf++ = hexdig(c>>4); |
| sgetz7908 | 2:def2c045c43a | 180 | *buf++ = hexdig(c&0x0f); |
| sgetz7908 | 2:def2c045c43a | 181 | *buf=0; |
| sgetz7908 | 2:def2c045c43a | 182 | |
| sgetz7908 | 2:def2c045c43a | 183 | return str_buf; |
| sgetz7908 | 2:def2c045c43a | 184 | } |
| sgetz7908 | 2:def2c045c43a | 185 | |
| sgetz7908 | 2:def2c045c43a | 186 | /// Converts an unsigned 32 bit int to a hex string, |
| sgetz7908 | 2:def2c045c43a | 187 | /// 'digits' specifies the number of hex digits to output |
| sgetz7908 | 2:def2c045c43a | 188 | /// output string is null terminated |
| sgetz7908 | 2:def2c045c43a | 189 | char * char2hex(uint32_t n, int digits) |
| sgetz7908 | 2:def2c045c43a | 190 | { |
| sgetz7908 | 2:def2c045c43a | 191 | char * buf = str_buf+digits; |
| sgetz7908 | 2:def2c045c43a | 192 | *buf-- = 0; // null terminator |
| sgetz7908 | 2:def2c045c43a | 193 | |
| sgetz7908 | 2:def2c045c43a | 194 | if(digits>0 && digits<20) { |
| sgetz7908 | 2:def2c045c43a | 195 | while(digits-->0) { |
| sgetz7908 | 2:def2c045c43a | 196 | *buf-- = hexdig(n & 0x0f); |
| sgetz7908 | 2:def2c045c43a | 197 | n = n>>4; |
| sgetz7908 | 2:def2c045c43a | 198 | } |
| sgetz7908 | 2:def2c045c43a | 199 | } |
| sgetz7908 | 2:def2c045c43a | 200 | else |
| sgetz7908 | 2:def2c045c43a | 201 | { |
| sgetz7908 | 2:def2c045c43a | 202 | return ""; |
| sgetz7908 | 2:def2c045c43a | 203 | } |
| sgetz7908 | 2:def2c045c43a | 204 | |
| sgetz7908 | 2:def2c045c43a | 205 | return str_buf; |
| sgetz7908 | 2:def2c045c43a | 206 | } |