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
Diff: Source/hw.cpp
- Revision:
- 23:7ca590427f0e
- Parent:
- 10:b3553e75eee0
- Child:
- 24:761c30334cf4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/hw.cpp Tue Mar 19 19:25:39 2019 +0000
@@ -0,0 +1,198 @@
+//**********************************************************************
+//
+// Hardware Routines
+//
+// SPG 12/13/2016
+//
+//**********************************************************************
+
+/// @file hw.cpp
+
+#include "mbed.h"
+#include "hw.h"
+#include "nrf_delay.h"
+#include "nrf_gpio.h"
+
+
+Ticker seconds_ticker;
+volatile uint32_t seconds = 0; // seconds clock, time since power up
+volatile uint32_t sec_offset = 0; // when the actual time is set, this will contain the difference between actual time and the above variable
+
+
+/// Software generate delay.
+/// Interrupt can increase the delay length.
+/// CPU runs at full power during delay.
+void delay_ms(uint32_t volatile number_of_ms)
+{
+ while(number_of_ms != 0) {
+ number_of_ms--;
+ nrf_delay_us(999);
+ }
+}
+
+void set_rtc(uint32_t s)
+{
+ seconds = s;
+}
+
+void update_rtc(uint32_t s)
+{
+ seconds += s;
+}
+
+// RTC in seconds since boot
+static void seconds_ticker_interrupt(void)
+{
+ seconds += 1;
+}
+
+/// Initialize the seconds clock to 's' seconds
+void init_clock(uint32_t s)
+{
+ seconds_ticker.detach();
+ seconds_ticker.attach(seconds_ticker_interrupt, 1.00);
+ seconds = s;
+}
+
+/// Read the number of seconds since init_clock() was called
+uint32_t read_clock(void)
+{
+ return seconds;
+}
+
+/// Set sec_offset by passing the current time, so correct time/date can be be found by adding sec_offset to internal time
+void set_time_offset(uint32_t s)
+{
+ sec_offset = s - read_clock();
+}
+
+/// Return the time correction value, add this to the internal time to get real time
+uint32_t read_time_correction(void)
+{
+ return sec_offset;
+}
+
+/// 10-bit ADC reading of the requested channel
+/// Uses internal 1.2V reference, and 1/3 of the signal source.
+/// This provides a result = Voltage/3.6*1023
+/// @param chan is the channel to read
+/// @param times is the number of readings to take
+/// @return avg of all the readings
+int adc_read(int chan, int num_readings)
+{
+ int result = 0;
+ int times = num_readings;
+
+ NRF_ADC->INTENCLR = ADC_INTENCLR_END_Clear; // turn off ADC interrupts
+ //NRF_ADC->EVENTS_END = 0;
+
+ switch(chan) {
+ case ADC_CHAN_BATTERY:
+ NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
+ (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
+ (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
+ (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) |
+ (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
+ break;
+
+ case ADC_CHAN_CAP_SENSE:
+ NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
+ (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
+ (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
+ (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos) |
+ (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
+ break;
+
+ default:
+ return 0;
+ }
+
+ NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled; // enable ADC
+
+ while(times--) {
+ NRF_ADC->TASKS_START = 1; // start ADC conversion
+
+ // wait for conversion to end
+ while (!NRF_ADC->EVENTS_END) {
+ ;
+ }
+
+ NRF_ADC->EVENTS_END = 0;
+ result += NRF_ADC->RESULT; //Save your ADC result
+ NRF_ADC->TASKS_STOP = 1; //Use the STOP task to save current.
+ }
+
+ //NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled;
+ return (int)result/num_readings; // 10 bit
+}
+
+/// Reads the battery voltage
+/// Returns the voltage as an int * 100. 3V = 300
+int read_battery_voltage(void)
+{
+ return ((float)adc_read(ADC_CHAN_BATTERY,4)*3.6)/1023.0*100.0;
+}
+
+char str_buf[21];
+
+/// Convert unsigned int to string
+/// @returns pointer to string
+char * uli2a(uint32_t num)
+{
+ char * buf = str_buf;
+ //int n=0;
+ unsigned long d=1;
+ while (num/d >= 10)
+ d*=10;
+ while (d!=0) {
+ int dgt = num / d;
+ num%=d;
+ d/=10;
+ *buf++ = dgt+'0';
+ //n++;
+ }
+ *buf=0;
+
+ return str_buf;
+}
+
+char hexdig(char c)
+{
+ if(c<10) return c+'0';
+ return c-10+'a';
+}
+
+/// Convert unsigned char to string, 2 digit hex
+/// @returns pointer to string
+char * char2hex(char c)
+{
+ char * buf = str_buf;
+
+ *buf++ = hexdig(c>>4);
+ *buf++ = hexdig(c&0x0f);
+ *buf=0;
+
+ return str_buf;
+}
+
+/// Converts an unsigned 32 bit int to a hex string,
+/// 'digits' specifies the number of hex digits to output
+/// output string is null terminated
+char * char2hex(uint32_t n, int digits)
+{
+ char * buf = str_buf+digits;
+ *buf-- = 0; // null terminator
+
+ if(digits>0 && digits<20) {
+ while(digits-->0) {
+ *buf-- = hexdig(n & 0x0f);
+ n = n>>4;
+ }
+ }
+ else
+ {
+ return "";
+ }
+
+ return str_buf;
+}