Merck / Mbed OS SmartCap_OS5

Dependencies:   nRF51822

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;
+}