Priliminary

Dependencies:   DS1307 MAX17048 MODSERIAL SSD1308_128x64_I2C WatchDog mbed-rpc mbed

Fork of ECGAFE_copy by Zainul Charbiwala

Files at this revision

API Documentation at this revision

Comitter:
zainulcharbiwala
Date:
Wed Sep 30 11:30:56 2015 +0000
Commit message:
Priliminary

Changed in this revision

ADS1298.cpp Show annotated file Show diff for this revision Revisions of this file
ADS1298.h Show annotated file Show diff for this revision Revisions of this file
DS1307.lib Show annotated file Show diff for this revision Revisions of this file
DebouncedIn.cpp Show annotated file Show diff for this revision Revisions of this file
DebouncedIn.h Show annotated file Show diff for this revision Revisions of this file
MAX17048.lib Show annotated file Show diff for this revision Revisions of this file
MODSERIAL.lib Show annotated file Show diff for this revision Revisions of this file
SSD1308_128x64_I2C.lib Show annotated file Show diff for this revision Revisions of this file
WatchDog.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rpc.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
oledicons.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADS1298.cpp	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,250 @@
+#include "ADS1298.h"
+
+
+ADS1298::ADS1298(PinName mosi, 
+                     PinName miso, 
+                     PinName sck, 
+                     PinName csn,
+                     PinName reset,
+                     PinName drdy,
+                     PinName start) : spi_(mosi, miso, sck), cs_(csn), reset_(reset), drdy_(drdy), start_(start) {
+}
+
+void ADS1298::sendCommand(uint8_t cmd)
+{
+    // Select the device by seting chip select low
+    cs_ = 0;
+    wait_us(TCSSC);
+ 
+    // Send SDATAC, as device comes up in RDATAC
+    spi_.write(cmd);
+    wait_us(TCMD);
+ 
+    // Deselect the device
+    wait_us(TSCCS);
+    cs_ = 1;
+    // Wait between commands
+    wait_us(TCSH);
+}
+
+void ADS1298::writeRegister(uint8_t reg, uint8_t val)
+{
+    // Select the device by seting chip select low
+    cs_ = 0;
+    wait_us(TCSSC);
+ 
+    // Write register address
+    spi_.write(WREG|reg);
+    wait_us(TCMD);
+
+    // Writing one register
+    spi_.write(0x00);
+    wait_us(TCMD);
+ 
+    // Write the value
+    spi_.write(val);
+    wait_us(TCMD);
+ 
+    // Deselect the device
+    wait_us(TSCCS);
+    cs_ = 1;
+
+    // Wait between commands
+    wait_us(TCSH);
+}
+
+uint8_t ADS1298::readRegister(uint8_t reg)
+{
+    uint8_t res;
+    // Select the device by seting chip select low
+    cs_ = 0;
+    wait_us(TCSSC);
+ 
+    // Write register address
+    spi_.write(RREG|reg);
+    wait_us(TCMD);
+
+    // Reading one register
+    spi_.write(0x00);
+    wait_us(TCMD);
+ 
+    // Write a dummy value to read the register
+    res = spi_.write(0x00);
+    wait_us(TCMD);
+ 
+    // Deselect the device
+    wait_us(TSCCS);
+    cs_ = 1;
+
+    // Wait between commands
+    wait_us(TCSH);
+    return res;
+}
+ 
+void ADS1298::readData(uint8_t *data)
+{
+    // Select the device by seting chip select low
+    cs_ = 0;
+    wait_us(TCSSC);
+ 
+    for (int i=0; i<27; i++) {
+        // Write a dummy value to read the register
+        *(data+i) = spi_.write(0x00);
+    }
+    wait_us(TCMD);
+ 
+    // Deselect the device
+    wait_us(TSCCS);
+    cs_ = 1;
+
+    // Wait between commands
+    wait_us(TCSH);
+}
+
+void ADS1298::initialize(void (*dataReady)(void))
+{
+    // Initialize signals
+    cs_ = 1;
+    start_ = 0;
+    reset_ = 1;
+    drdy_.fall(dataReady);
+
+    // Set up SPI
+    spi_.format(8,1);
+    // Choosing 1MHz arbitrarily for now
+    spi_.frequency(1000000);
+
+
+    // Power on reset
+    wait_us(TPOR);
+    
+    // Reset the device
+    reset_ = 0;
+    wait_us(TRST);
+    reset_ = 1;
+    wait_us(TRST2);
+    
+    // Send SDATAC, as device comes up in RDATAC
+    sendCommand(SDATAC);
+
+    //pc.printf("ID = 0x%02X\r\n", readRegister(ID));
+    //pc.printf("CONFIG1 = 0x%02X\r\n", readRegister(CONFIG1));
+    //pc.printf("CONFIG2 = 0x%02X\r\n", readRegister(CONFIG2));
+    //pc.printf("CONFIG3 = 0x%02X\r\n", readRegister(CONFIG3));
+
+    // Turn on internal reference and wait for it to settle
+    writeRegister(CONFIG3, CONFIG3_DEFAULT | CONFIG3_PD_REFBUF);
+    wait_us(TINTREF);
+    //pc.printf("CONFIG3 = 0x%02X\r\n", readRegister(CONFIG3));
+    
+    /*    
+    // Set up device
+    writeRegister(CONFIG1, CONFIG1_HR | CONFIG1_DR2 | CONFIG1_DR1);    
+    pc.printf("CONFIG1 = 0x%02X\r\n", readRegister(CONFIG1));
+    writeRegister(CONFIG2, CONFIG2_DEFAULT);    
+    pc.printf("CONFIG2 = 0x%02X\r\n", readRegister(CONFIG2));
+    
+    // Input short on all channels
+    writeRegister(CH1SET, CHNSET_MUXN0);    
+    writeRegister(CH2SET, CHNSET_MUXN0);    
+    writeRegister(CH3SET, CHNSET_MUXN0);    
+    writeRegister(CH4SET, CHNSET_MUXN0);    
+    writeRegister(CH5SET, CHNSET_MUXN0);    
+    writeRegister(CH6SET, CHNSET_MUXN0);    
+    writeRegister(CH7SET, CHNSET_MUXN0);    
+    writeRegister(CH8SET, CHNSET_MUXN0);    
+    pc.printf("CH1SET = 0x%02X\r\n", readRegister(CH1SET));
+    pc.printf("CH2SET = 0x%02X\r\n", readRegister(CH2SET));
+    pc.printf("CH3SET = 0x%02X\r\n", readRegister(CH3SET));
+    pc.printf("CH4SET = 0x%02X\r\n", readRegister(CH4SET));
+    pc.printf("CH5SET = 0x%02X\r\n", readRegister(CH5SET));
+    pc.printf("CH6SET = 0x%02X\r\n", readRegister(CH6SET));
+    pc.printf("CH7SET = 0x%02X\r\n", readRegister(CH7SET));
+    pc.printf("CH8SET = 0x%02X\r\n", readRegister(CH8SET));
+    */
+
+    /*
+    // Set up device
+    writeRegister(CONFIG1, CONFIG1_HR | CONFIG1_DR2 | CONFIG1_DR1);    
+    writeRegister(CONFIG2, CONFIG2_DEFAULT | CONFIG2_INTTEST);    
+    
+    // Input test on all channels
+    writeRegister(CH1SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
+    writeRegister(CH2SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
+    writeRegister(CH3SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
+    writeRegister(CH4SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
+    writeRegister(CH5SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
+    writeRegister(CH6SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
+    writeRegister(CH7SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
+    writeRegister(CH8SET, CHNSET_MUXN2 | CHNSET_MUXN0);    
+    */
+
+    // Set up device
+    writeRegister(CONFIG1, CONFIG1_HR | CONFIG1_DR2 | CONFIG1_DR1);    
+    writeRegister(CONFIG2, CONFIG2_DEFAULT);
+    writeRegister(CONFIG3, CONFIG3_DEFAULT | CONFIG3_PD_REFBUF |
+                            CONFIG3_RLDREF_INT | CONFIG3_PD_RLD);
+    writeRegister(CONFIG4, CONFIG4_PD_LOFF_COMP);
+    writeRegister(LOFF, LOFF_VLEAD_OFF_EN | LOFF_FLEAD_OFF1 | LOFF_FLEAD_OFF0);    
+    writeRegister(LOFF_SENSP, 0xFF); // for V6, LA, LL, V2, V3, V4, V5, V1
+    writeRegister(LOFF_SENSN, 0x02); // for RA only
+    writeRegister(RLD_SENSP, 0x06); // for LA, LL
+    writeRegister(RLD_SENSN, 0x02); // for RA
+    writeRegister(WCT1, WCT1_PD_WCTA | WCT1_WCTA1); // WCTA to CH2P = LA
+    writeRegister(WCT2, WCT2_PD_WCTC | WCT2_PD_WCTB | 
+                        WCT2_WCTB2 | WCT2_WCTC1 | 
+                        WCT2_WCTC0); // WCTB to CH3P = LL, WCTC to CH2N = RA
+    
+    // Input test on all channels
+    writeRegister(CH1SET, CHNSET_DEFAULT);    
+    writeRegister(CH2SET, CHNSET_DEFAULT);    
+    writeRegister(CH3SET, CHNSET_DEFAULT);    
+    writeRegister(CH4SET, CHNSET_DEFAULT);    
+    writeRegister(CH5SET, CHNSET_DEFAULT);    
+    writeRegister(CH6SET, CHNSET_DEFAULT);    
+    writeRegister(CH7SET, CHNSET_DEFAULT);    
+    writeRegister(CH8SET, CHNSET_DEFAULT);    
+    
+}
+
+void ADS1298::startCapture() {
+    //Start conversion
+    start_ = 1;
+    
+    // Send RDATAC to start data collection
+    sendCommand(RDATAC);
+}
+
+void ADS1298::stopCapture() {
+    //Stop conversion
+    start_ = 0;
+    
+    // Send SDATAC to stop data collection
+    sendCommand(SDATAC);
+}
+
+int ADS1298::updateLeadOff(uint8_t *buf) {
+
+  // Buffer contains 9 fields of 24 bits each
+  // First field contains an identifier and the status bits
+  // First nibble of first byte is always 0b1100
+  // Second nibble of third byte is always 0x00 because GPIO are not used
+  if ((buf[0] & 0xf0) != 0xc0 || (buf[2] & 0x0f) != 0x00)
+    return -1;
+
+  // Second nibble of first byte has IN8P_OFF (V1), IN7P_OFF (V5), IN6P_OFF (V4), IN5P_OFF (V3)
+  lOff_ = 0;
+  lOff_ |= (buf[0] & 0x08) ? (1 << LOFFV1) : 0;
+  lOff_ |= (buf[0] & 0x04) ? (1 << LOFFV5) : 0;
+  lOff_ |= (buf[0] & 0x02) ? (1 << LOFFV4) : 0;
+  lOff_ |= (buf[0] & 0x01) ? (1 << LOFFV3) : 0;
+  // First nibble of second byte has IN4P_OFF (V2), IN3P_OFF (LL), IN2P_OFF (LA), IN1P_OFF (V6)
+  lOff_ |= (buf[1] & 0x80) ? (1 << LOFFV2) : 0;
+  lOff_ |= (buf[1] & 0x40) ? (1 << LOFFLL) : 0;
+  lOff_ |= (buf[1] & 0x20) ? (1 << LOFFLA) : 0;
+  lOff_ |= (buf[1] & 0x10) ? (1 << LOFFV6) : 0;
+  // First nibble of third byte has IN2N_OFF (RA)
+  lOff_ |= (buf[2] & 0x20) ? (1 << LOFFRA) : 0;
+
+  return 0;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADS1298.h	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,221 @@
+// Copyright 2013, Zainul Charbiwala
+
+#ifndef _ADS1298_h_
+#define _ADS1298_h_
+
+#include "mbed.h"
+
+#define TCSSC   1 // 6 ns
+#define TSCCS   2 // 4 TCLKs
+#define TPOR    32768 // 2^16 TCLKs
+#define TRST    1 // 2 TCLKs 
+#define TRST2   9 // 18 TCLKs
+#define TINTREF 150000 // 150ms
+#define TCMD    2 // 4 TCLKs
+#define TCSH    1 // 2 TCLKs
+
+#define RDATA   0x12
+#define RDATAC  0x10
+#define SDATAC  0x11
+#define WREG    0x40
+#define RREG    0x20
+
+#define ID      0x00
+#define CONFIG1 0x01
+#define CONFIG2 0x02
+#define CONFIG3 0x03
+#define LOFF    0x04
+#define CH1SET  0x05
+#define CH2SET  0x06
+#define CH3SET  0x07
+#define CH4SET  0x08
+#define CH5SET  0x09
+#define CH6SET  0x0A
+#define CH7SET  0x0B
+#define CH8SET  0x0C
+#define RLD_SENSP 0x0D
+#define RLD_SENSN 0x0E
+#define LOFF_SENSP 0x0F
+#define LOFF_SENSN 0x10
+#define LOFF_FLIP 0x11
+#define LOFF_STATP 0x12
+#define LOFF_STATN 0x13
+#define GPIO    0x14
+#define PACE    0x15
+#define RESP    0x16
+#define CONFIG4 0x17
+#define WCT1    0x18
+#define WCT2    0x19
+
+
+#define CONFIG1_HR          0x80
+#define CONFIG1_DAISYEN     0x40
+#define CONFIG1_CLKEN       0x20
+#define CONFIG1_DR2         0x04
+#define CONFIG1_DR1         0x02
+#define CONFIG1_DR0         0x01
+
+#define CONFIG2_WCTCHOP     0x20
+#define CONFIG2_INTTEST     0x10
+#define CONFIG2_TESTAMP     0x04
+#define CONFIG2_TESTFREQ1   0x02
+#define CONFIG2_TESTFREQ0   0x01
+#define CONFIG2_DEFAULT     0x00
+
+#define CONFIG3_PD_REFBUF   0x80
+#define CONFIG3_VREF_4V     0x20
+#define CONFIG3_RLD_MEAS    0x10
+#define CONFIG3_RLDREF_INT  0x08
+#define CONFIG3_PD_RLD      0x04
+#define CONFIG3_RLD_LOFF_SENS 0x02
+#define CONFIG3_RLD_STAT    0x01
+#define CONFIG3_DEFAULT     0x40
+
+#define LOFF_COMP_TH2       0x80      
+#define LOFF_COMP_TH1       0x40
+#define LOFF_COMP_TH0       0x20
+#define LOFF_VLEAD_OFF_EN   0x10
+#define LOFF_ILEAD_OFF1     0x08
+#define LOFF_ILEAD_OFF0     0x04
+#define LOFF_FLEAD_OFF1     0x02
+#define LOFF_FLEAD_OFF0     0x01
+
+#define CHNSET_PD           0x80
+#define CHNSET_GAIN2        0x40
+#define CHNSET_GAIN1        0x20
+#define CHNSET_GAIN0        0x10
+#define CHNSET_MUXN2        0x04
+#define CHNSET_MUXN1        0x02
+#define CHNSET_MUXN0        0x01
+#define CHNSET_DEFAULT      0x00
+
+#define GPIO_GPIOD4         0x80
+#define GPIO_GPIOD3         0x40
+#define GPIO_GPIOD2         0x20
+#define GPIO_GPIOD1         0x10
+#define GPIO_GPIOC4         0x08
+#define GPIO_GPIOC3         0x04
+#define GPIO_GPIOC2         0x02
+#define GPIO_GPIOC1         0x01
+
+#define PACE_PACEE1         0x10
+#define PACE_PACEE0         0x08
+#define PACE_PACEO1         0x04
+#define PACE_PACEO0         0x02
+#define PACE_PD_PACE        0x01
+
+#define RESP_DEMOD_EN1      0x80
+#define RESP_MOD_EN1        0x40
+#define RESP_DEFAULT        0x20
+#define RESP_PH2            0x10
+#define RESP_PH1            0x08
+#define RESP_PH0            0x04
+#define RESP_CTRL1          0x02
+#define RESP_CTRL0          0x01
+
+#define CONFIG4_RESP_FREQ2  0x80
+#define CONFIG4_RESP_FREQ1  0x40
+#define CONFIG4_RESP_FREQ0  0x20
+#define CONFIG4_SINGLE_SHOT 0x08
+#define CONFIG4_WCT_TO_RLD  0x04
+#define CONFIG4_PD_LOFF_COMP 0x02
+
+#define WCT1_AVF_CH6        0x80
+#define WCT1_AVL_CH5        0x40
+#define WCT1_AVR_CH7        0x20
+#define WCT1_AVR_CH4        0x10
+#define WCT1_PD_WCTA        0x08
+#define WCT1_WCTA2          0x04
+#define WCT1_WCTA1          0x02
+#define WCT1_WCTA0          0x01
+
+#define WCT2_PD_WCTC        0x80
+#define WCT2_PD_WCTB        0x40
+#define WCT2_WCTB2          0x20
+#define WCT2_WCTB1          0x10
+#define WCT2_WCTB0          0x08
+#define WCT2_WCTC2          0x04
+#define WCT2_WCTC1          0x02
+#define WCT2_WCTC0          0x01
+
+// Bit positions of the lead off status bits
+#define LOFFRA 15
+#define LOFFLA 14
+#define LOFFLL 13
+#define LOFFRL 12
+#define LOFFV1 11
+#define LOFFV2 10
+#define LOFFV3 9
+#define LOFFV4 8
+#define LOFFV5 7
+#define LOFFV6 6
+
+/** Class to control an ADS1298 AFE
+ *
+ * Example:
+ * @code
+ *
+ * @endcode
+ */
+class ADS1298 {
+  public:
+    
+ /**
+  * @brief Constructor
+  * @param mosi mbed pin to use for MOSI line of SPI interface.
+  * @param miso mbed pin to use for MISO line of SPI interface.
+  * @param sck mbed pin to use for SCK line of SPI interface.
+  * @param csn mbed pin to use for not chip select line of SPI interface.
+  * @param reset mbed pin to use for the reset line.
+  * @param drdy mbed pin to use for the data ready line.
+  * @param start mbed pin to use for the start conversion line.
+  */    
+    ADS1298(PinName mosi, PinName miso, PinName sck, PinName csn, PinName reset, PinName drdy, PinName start);
+    
+
+// High Level methods
+
+ /** 
+  * @brief High level Init, most settings remain at Power-On reset value
+  */
+    void initialize(void (*dataready)(void));
+
+ /** 
+  * @brief Start capturing data
+  */
+    void startCapture();
+
+ /** 
+  * @brief Stop capturing data
+  */
+    void stopCapture();
+
+ /** 
+  * @brief Read data from the ADS1298
+  */
+    void readData(uint8_t *buf);
+
+ /** 
+  * @brief Update the lead off status
+  */
+    int updateLeadOff(uint8_t *buf);
+
+  private:
+
+    SPI spi_; // mosi, miso, sclk
+    DigitalOut cs_;
+    DigitalOut reset_;
+    InterruptIn drdy_;
+    DigitalOut start_;
+    uint16_t lOff_;
+
+// Low Level methods
+    void sendCommand(uint8_t cmd);
+    void writeRegister(uint8_t reg, uint8_t val);
+    uint8_t readRegister(uint8_t reg);
+
+};
+
+
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DS1307.lib	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/harrypowers/code/DS1307/#c3e4da8feb10
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DebouncedIn.cpp	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,96 @@
+#include "DebouncedIn.h"
+#include "mbed.h"
+
+/*
+ * Constructor
+ */
+DebouncedIn::DebouncedIn(PinName in) 
+    : _in(in) {    
+        
+    // reset all the flags and counters    
+    _samples = 0;
+    _output = 0;
+    _output_last = 0;
+    _releasing_flag = 0;
+    _pressing_flag = 0;
+    _press_counter = 0;
+    
+    // Switch is assumed to go to ground 
+    _in.mode(PullUp);
+    
+    // Attach ticker
+    _ticker.attach(this, &DebouncedIn::_sample, 0.005);     
+}
+  
+void DebouncedIn::_sample() {
+
+    // take a sample
+    _samples = _samples >> 1; // shift left
+      
+    if (_in) {
+        _samples |= 0x80;
+    }  
+      
+    // examine the sample window, look for steady state
+    if (_samples == 0x00) {
+        _output = 0;
+    } 
+    else if (_samples == 0xFF) {
+        _output = 1;
+    }
+
+
+    // Release detection
+    if ((_output == 1) && (_output_last == 0)) {
+        _releasing_flag++;
+    }
+
+    // Press detection
+    else if ((_output == 0) && (_output_last == 1)) {
+        _pressing_flag++;
+        _press_counter = 0;
+    }
+    
+    // pressed state
+    else if (_output == 0) {
+        _press_counter++;
+    }
+    
+   // update the output
+    _output_last = _output;
+    
+    //printf("%d %d\n", _press_counter, _releasing_flag);
+}
+
+
+
+// return number of releasing events
+int DebouncedIn::releasing(void) {
+    int return_value = _releasing_flag; 
+    _releasing_flag = 0;
+    return(return_value);
+}
+
+// return number of pressing events
+int DebouncedIn::pressing(void) {
+    int return_value = _pressing_flag; 
+    _pressing_flag = 0;
+    return(return_value);
+}
+
+// return number of ticks we've bene steady for
+int DebouncedIn::pressed(void) {
+return(_press_counter);
+}
+
+// return the debounced status
+int DebouncedIn::read(void) {
+    return(_output);
+}
+
+// shorthand for read()
+DebouncedIn::operator int() {
+    return read();
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DebouncedIn.h	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,31 @@
+#include "mbed.h"
+
+    class DebouncedIn {
+        public:      
+             DebouncedIn(PinName in);
+
+             int read (void);
+             operator int();
+              
+             int releasing(void);
+             int pressing(void);
+             int pressed(void);
+              
+        private :    
+               // objects
+               DigitalIn _in;    
+               Ticker _ticker;
+
+               // function to take a sample, and update flags
+               void _sample(void);
+
+               // counters and flags
+               int _samples;
+               int _output;
+               int _output_last;
+               int _releasing_flag;
+               int _pressing_flag;
+               int _press_counter;
+
+    };
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX17048.lib	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/neilt6/code/MAX17048/#e61b2723d2cf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MODSERIAL.lib	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/AjK/code/MODSERIAL/#ae0408ebdd68
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SSD1308_128x64_I2C.lib	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/wim/code/SSD1308_128x64_I2C/#fa18169dd7e6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WatchDog.lib	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/Lerche/code/WatchDog/#a6661a79bf7b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,306 @@
+// Copyright 2013, Zainul Charbiwala
+
+/* Includes */
+#include "mbed.h"
+#include "ADS1298.h"
+#include "SSD1308.h"
+#include "ds1307.h"
+#include "MAX17048.h"
+#include "WatchDog.h"
+#include "oledicons.h"
+#include "mbed_rpc.h"
+#include "DebouncedIn.h"
+#include "MODSERIAL.h"
+
+/* mbed Objects */
+DigitalOut myled(LED1);
+DigitalOut lWatchdog(LED4);
+WatchDog_ms wdt(10000);
+Ticker wdtTicker;
+MODSERIAL pc(USBTX, USBRX);
+Timer tt;
+I2C i2c(p28, p27); // sda, scl
+SSD1308 oled = SSD1308(i2c, SSD1308_SA0);
+ADS1298 ads = ADS1298(p5, p6, p7, p24, p23, p22, p21); //mosi, miso, sclk, cs, reset, drdy, start
+DS1307 rtc(p28,p27); // start DS1307 class and give it pins for connections of the DS1307 device
+MAX17048 gauge(p28, p27);
+DigitalIn battChging(p14);           
+DebouncedIn button(p20);
+
+/* Constants */
+#define OLEDPAGEMAX 14
+// Page 0 for general use
+// Page 1-12 for signals
+// Page 13 for network status
+// Page 14 for something else
+
+/* Global Variables */
+uint8_t buf[27];
+char rpcInBuf[256], rpcOutBuf[256];
+int vCapturing;
+
+static char oledstr[16];
+static int vOledPage;
+
+/* External Functions */
+
+/* Local Functions */
+static void dataReady(void);
+static void wdtKicker();
+static void oledBattery(uint8_t percentage, uint8_t charging);
+static void oledNetwork(uint8_t percentage, const char *mode);
+static void oledTime();
+static void fCaptureStart(Arguments *arg, Reply *r);
+static void fCaptureStop(Arguments *arg, Reply *r);
+static void fButtonLongPress();
+static void fButtonShortPress();
+static void fOledPage0();
+static void fOledPageSignal();
+static void fOledPageNetwork();
+static void fOledPageSomethingElse();
+
+
+/* RPC Variables */
+RPCVariable<int> rpc_vCapturing(&vCapturing, "vCapturing");
+
+/* RPC Functions */
+RPCFunction rpc_fCaptureStart(&fCaptureStart, "fCaptureStart");
+RPCFunction rpc_fCaptureStop(&fCaptureStop, "fCaptureStop");
+
+
+static void wdtKicker() {
+        wdt.feed();
+}
+
+static void fCaptureStart(Arguments *arg, Reply *r){
+  vCapturing = 1;                                                 
+  ads.startCapture();
+  oled.writeString(7, 0, "Capture started.");
+}
+
+static void fCaptureStop(Arguments *arg, Reply *r){
+  vCapturing = 0;                                                 
+  ads.stopCapture();
+  oled.writeString(7, 0, "Capture stopped.");                                                 
+}
+
+static void fOledPage0() {
+  oled.writeString(5, 0, "  HR:  xxx bpm  ");
+  oled.writeString(6, 0, "  LO:           ");
+
+  sprintf(oledstr, "Display Page: %02d", vOledPage); 
+  oled.writeString(7, 0, oledstr);
+  
+}
+
+static void fOledPageSignal() {
+  sprintf(oledstr, "Display Page: %02d", vOledPage); 
+  oled.writeString(7, 0, oledstr);
+  
+}
+
+static void fOledPageNetwork() {
+  sprintf(oledstr, "Display Page: %02d", vOledPage); 
+  oled.writeString(7, 0, oledstr);
+  
+}
+
+static void fOledPageSomethingElse() {
+  sprintf(oledstr, "Display Page: %02d", vOledPage); 
+  oled.writeString(7, 0, oledstr);
+  
+}
+
+static void fButtonShortPress()
+{
+  // Scroll to the next page of the oled display
+  vOledPage++;
+  if (vOledPage > OLEDPAGEMAX) {
+    vOledPage = 0;
+  }
+  if (vOledPage == 0) {
+    fOledPage0();
+  }
+  if (vOledPage >= 1 && vOledPage <= 12) {
+    fOledPageSignal();
+  }
+  if (vOledPage == 13) {
+    fOledPageNetwork();
+  }
+  if (vOledPage == 0) {
+    fOledPageSomethingElse();
+  }
+}
+
+static void fButtonLongPress()
+{
+  // If in capture mode, stop capture
+  // If not in capture mode, start capture 
+  if (vCapturing) {
+    oled.writeString(7, 0, "Capture Stopping");
+    fCaptureStop(NULL, NULL);
+  } else {
+    oled.writeString(7, 0, "Capture Starting");
+    fCaptureStart(NULL, NULL);
+  }
+}
+
+
+static void oledBattery(uint8_t percentage, uint8_t charging)
+{
+    // Hardcoded a 24 column, 1 page high battery meter icon
+    // It has 18 columns that can be set
+    uint8_t battimg[24];
+    uint8_t i;
+    percentage=(percentage>100?100:percentage);
+    memcpy((uint8_t *)battimg, (uint8_t *)iconBattery, 24);
+    for (i=2; i<2+(18*percentage)/100; i++) {
+        battimg[i] |= 0x3C;
+    }
+    
+    if (charging) {
+        for (i=0; i<20; i++) {
+            battimg[i+2] ^= iconBattChg[i];
+        }
+    } 
+    oled.writeBitmap((uint8_t*) battimg, 0, 0, 104, 127);
+}
+
+static void oledNetwork(uint8_t percentage, const char *mode)
+{
+    // Hardcoded a 16 column, 1 page high network meter icon
+    // It has 6 columns that can be set
+    uint8_t netwimg[16];
+    percentage=(percentage>100?100:percentage);
+    memcpy((uint8_t *)netwimg, (uint8_t *)iconNetwork, 16);
+    
+    if (percentage > 0)
+        netwimg[1] = 0xF0;
+    if (percentage > 16)
+        netwimg[2] = 0xF0;
+    if (percentage > 33)
+        netwimg[6] = 0xFC;
+    if (percentage > 49)
+        netwimg[7] = 0xFC;
+    if (percentage > 66)
+        netwimg[11] = 0xFF;
+    if (percentage > 83)
+        netwimg[12] = 0xFF;
+   
+    oled.writeBitmap((uint8_t*) netwimg, 0, 0, 0, 15);
+    oled.writeString(0, 2, mode);
+}
+
+static void oledTime()
+{
+    int sec = 0, min = 0, hours = 0;
+    int day = 0, date = 0, month = 0, year = 0;
+    int ret = 0;
+
+    char timestr[7];
+    ret = rtc.gettime( &sec, &min, &hours, &day, &date, &month, &year);
+    if (ret == 0) {
+        if (hours == 0) {
+            sprintf(timestr, "%02d:%02da", hours+12, min);
+        } else if (hours == 12) {
+            sprintf(timestr, "%02d:%02dp", hours, min);        
+        } else if (hours>12) {
+            sprintf(timestr, "%02d:%02dp", hours-12, min);
+        } else {
+            sprintf(timestr, "%02d:%02da", hours, min);
+        }
+        oled.writeString(0, 5, timestr);
+    } else {
+        oled.writeString(0, 5, "00:00!");
+    }
+    
+}
+
+static void fSetTime()
+{
+}
+
+void dataReady()
+{
+  ads.readData(buf);
+  ads.updateLeadOff(buf);
+    
+  if (vCapturing) {
+    // Send it to the serial port
+    // How much time does this take ?
+    // We have 2ms until the next interrupt comes
+    //pc.printf("\r\n%d", tt.read_ms());
+    for (int i=0; i<27; i++) {
+        //if (!(i%3)) pc.printf(" ");
+        //pc.printf("%02x", buf[i]);
+        pc.putc(buf[i]);
+    }
+  }
+  myled = !myled;
+}
+
+
+
+int main() {
+    uint8_t lev=0;
+    char ch;
+
+    vOledPage = 0;
+    vCapturing = 0;
+    i2c.frequency(400000); // according to the spec the max bitrate for the SSD1308 is 400 kbit/s
+    battChging.mode(PullUp);
+    pc.baud(921600);
+    pc.printf("starting\r\n");
+
+    wdtTicker.attach(&wdtKicker, 5);
+
+    myled=1;
+    oled.setDisplayOn();
+    oled.writeString(7, 0, "Initializing... ");
+    ads.initialize(&dataReady);
+    if (!gauge.open()) {
+        oled.writeString(7, 0, "Gauge Error !!!");
+        wait(5);
+    }
+    
+    fCaptureStart(NULL, NULL);
+    
+    while(1) {
+      wait(0.1);
+      
+      // Check if there's a command over RPC
+      if (pc.readable()) {
+        pc.gets(rpcInBuf, 256);
+        RPC::call(rpcInBuf, rpcOutBuf); 
+        //pc.printf("%s", rpcOutBuf);
+      }
+      
+      // Check if there's a user event
+      if (button.releasing()) {
+        // Short press
+        if (button.pressed() < 50) {
+          fButtonShortPress();
+        } 
+        // Long press
+        if (button.pressed() > 100) {
+          fButtonLongPress();
+        }
+      }
+      
+      // Update battery status icon
+      oledBattery(gauge.socInt(), !battChging);
+      // Update time
+      oledTime();
+      // Update network
+      if (++lev > 100) lev = 0;
+      oledNetwork(lev, "H");
+    
+      //Print the current state of charge
+      sprintf(oledstr, "VCell = %.2fV\n", gauge.vcell());
+      oled.writeString(3, 0, oledstr);
+    
+      //myled = !myled;
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rpc.lib	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rpc/#4490a0d9cb2a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/f37f3b9c9f0b
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/oledicons.h	Wed Sep 30 11:30:56 2015 +0000
@@ -0,0 +1,26 @@
+#ifndef _oledicons_h_
+#define _oledicons_h_
+
+const uint8_t iconNetwork[] = {
+   0xF0, 0x90, 0x90, 0xF0,
+   0x00, 0xFC, 0x84, 0x84,
+   0xFC, 0x00, 0xFF, 0x81,
+   0x81, 0xFF, 0x00, 0x00
+};
+const uint8_t iconBattery[] = {
+   0x7E, 0x81, 0x81, 0x81,
+   0x81, 0x81, 0x81, 0x81,
+   0x81, 0x81, 0x81, 0x81,
+   0x81, 0x81, 0x81, 0x81,
+   0x81, 0x81, 0x81, 0x81,
+   0x81, 0x7E, 0x3C, 0x3C
+};
+const uint8_t iconBattChg[] = {
+   0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x10, 0x10,
+   0x20, 0x30, 0x0C, 0x04,
+   0x04, 0x08, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00
+};
+
+#endif
\ No newline at end of file