Elmaddin Guliyev / Mbed 2 deprecated ADS1299

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
eguliyev
Date:
Wed May 29 03:43:46 2019 +0000
Commit message:
how to read texas instrument adc1299 using nucleo f4

Changed in this revision

ads1299.cpp Show annotated file Show diff for this revision Revisions of this file
ads1299.h 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.bld Show annotated file Show diff for this revision Revisions of this file
spi_slave.cpp Show annotated file Show diff for this revision Revisions of this file
spi_slave.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ads1299.cpp	Wed May 29 03:43:46 2019 +0000
@@ -0,0 +1,222 @@
+#include "mbed.h"
+#include "ads1299.h"
+
+SPI spi(SPI_MOSI,SPI_MISO,SPI_SCK);
+DigitalOut  CS(PA_4);
+InterruptIn DRDY(PA_2);  
+
+long ADS129X_data[9];
+bool ADS129X_newData;
+void ADS129X_dataReadyISR();
+ 
+void SPI_INIT(void){
+    spi.format(8,1);
+    spi.frequency(1000000);
+    }
+
+void WAKEUP() {
+    CS = 0;
+    spi.write(ADS129X_CMD_WAKEUP);
+    wait_us(2);
+    CS = 1;  
+    wait_us(2);   
+    }
+
+void STANDBY() {
+    CS = 0;
+    spi.write(ADS129X_CMD_STANDBY);
+    wait_us(2);
+    CS = 1;
+    }
+
+void RSET() {
+    CS = 0;
+    spi.write(ADS129X_CMD_RESET);
+    wait_us(2);
+    CS =1;
+    wait_ms(10);  
+    }
+
+void START() {
+  //  CS = 0;
+    //spi.write(ADS129X_CMD_START);
+  //  wait_us(2);
+  //  CS = 1;
+    RDATA();
+    DRDY.fall(&ADS129X_dataReadyISR);
+}
+    
+ 
+void RDATAC() {
+    CS =0;;
+    spi.write(ADS129X_CMD_RDATAC);
+    wait_us(2);
+    CS = 1;
+    wait_us(2); //must way at least 4 tCLK cycles before sending another command (Datasheet, pg. 39)
+    }
+    
+void SDATAC() {
+    CS = 0;
+    spi.write(ADS129X_CMD_SDATAC); //SDATAC
+    wait_us(2);
+    CS=1;
+}
+
+void RDATA() {
+    CS =0;
+    spi.write(ADS129X_CMD_RDATA);
+    wait_us(2);
+    CS=1;
+    }
+
+char RREG(char _address) {
+    char opcode1 = ADS129X_CMD_RREG | (_address & 0x1F); //001rrrrr; _RREG = 00100000 and _address = rrrrr
+    CS = 0; //Low to communicate
+    spi.write(opcode1); //RREG
+    spi.write(0x00); //opcode2
+    wait_us(1);
+    char data = spi.write(0x00); // read (Datasheet, pg.39)
+    wait_us(2);
+    CS =1; //High to end communication
+    return data;
+}
+
+void RREG(char _address, char _numRegisters, char *_data) {
+    char opcode1 = ADS129X_CMD_RREG | (_address & 0x1F); //001rrrrr; _RREG = 00100000 and _address = rrrrr
+    CS = 0;  
+    spi.write(ADS129X_CMD_SDATAC); //SDATAC
+    spi.write(opcode1); //RREG
+    spi.write(_numRegisters-1); //opcode2
+    for(char i = 0; i < _numRegisters; i++){
+        *(_data+i) = spi.write(0x00);  
+    }
+    wait_us(2);
+    CS = 1;  
+}
+
+void WREG(char _address, char _value) {
+    char opcode1 = ADS129X_CMD_WREG | (_address & 0x1F); //001rrrrr; _RREG = 00100000 and _address = rrrrr ds
+    CS=0; //Low to communicate
+    spi.write(opcode1);
+    spi.write(0x00); // opcode2; only write one register
+    spi.write(_value);
+    wait_us(2);
+    CS = 1; //Low to communicate
+}
+
+char getDeviceId() {
+    CS=0; //Low to communicate
+    spi.write(ADS129X_CMD_RREG); //RREG
+    spi.write(0x00); 
+    char data = spi.write(0x00); // byte to read (hopefully 0b???11110)
+    wait_us(2);
+    CS=1; //Low to communicate
+    return data;
+}
+
+void Set_IRQ(){
+   // DRDY.fall(&ADS129X_dataReadyISR);
+    }
+
+void ADS129X_dataReadyISR() {
+
+    CS = 0;
+    
+    // status
+    ((char*) ADS129X_data)[0*4+3] = 0;
+    ((char*) ADS129X_data)[0*4+2] = spi.write(0x00);
+    ((char*) ADS129X_data)[0*4+1] = spi.write(0x00);
+    ((char*) ADS129X_data)[0*4+0] = spi.write(0x00);
+    // channel 1
+    ((char*) ADS129X_data)[1*4+3] = 0;
+    ((char*) ADS129X_data)[1*4+2] = spi.write(0x00);
+    ((char*) ADS129X_data)[1*4+1] = spi.write(0x00);
+    ((char*) ADS129X_data)[1*4+0] = spi.write(0x00);
+    // channel 2
+    ((char*) ADS129X_data)[2*4+3] = 0;
+    ((char*) ADS129X_data)[2*4+2] = spi.write(0x00);
+    ((char*) ADS129X_data)[2*4+1] = spi.write(0x00);
+    ((char*) ADS129X_data)[2*4+0] = spi.write(0x00);
+    // channel 3
+    ((char*) ADS129X_data)[3*4+3] = 0;
+    ((char*) ADS129X_data)[3*4+2] = spi.write(0x00);
+    ((char*) ADS129X_data)[3*4+1] = spi.write(0x00);
+    ((char*) ADS129X_data)[3*4+0] = spi.write(0x00);
+    // channel 4
+    ((char*) ADS129X_data)[4*4+3] = 0;
+    ((char*) ADS129X_data)[4*4+2] = spi.write(0x00);
+    ((char*) ADS129X_data)[4*4+1] = spi.write(0x00);
+    ((char*) ADS129X_data)[4*4+0] = spi.write(0x00);
+    // channel 5
+    ((char*) ADS129X_data)[5*4+3] = 0;
+    ((char*) ADS129X_data)[5*4+2] = spi.write(0x00);
+    ((char*) ADS129X_data)[5*4+1] = spi.write(0x00);
+    ((char*) ADS129X_data)[5*4+0] = spi.write(0x00);
+    // channel 6
+    ((char*) ADS129X_data)[6*4+3] = 0;
+    ((char*) ADS129X_data)[6*4+2] = spi.write(0x00);
+    ((char*) ADS129X_data)[6*4+1] = spi.write(0x00);
+    ((char*) ADS129X_data)[6*4+0] = spi.write(0x00);
+    // channel 7
+    ((char*) ADS129X_data)[7*4+3] = 0;
+    ((char*) ADS129X_data)[7*4+2] = spi.write(0x00);
+    ((char*) ADS129X_data)[7*4+1] = spi.write(0x00);
+    ((char*) ADS129X_data)[7*4+0] = spi.write(0x00);
+    // channel 8
+    ((char*) ADS129X_data)[8*4+3] = 0;
+    ((char*) ADS129X_data)[8*4+2] = spi.write(0x00);
+    ((char*) ADS129X_data)[8*4+1] = spi.write(0x00);
+    ((char*) ADS129X_data)[8*4+0] = spi.write(0x00);
+    CS = 1;
+    ADS129X_newData = true;
+}
+ 
+bool getData(long *buffer) {
+    if(ADS129X_newData) {
+       ADS129X_newData = false;
+       for (int i = 0; i < 9; i++) {
+            buffer[i] = ADS129X_data[i];
+        }
+        return true;
+    }
+    return false;
+}
+
+
+
+void configChannel(char _channel, bool _powerDown, char _gain, char _mux) {
+    char value = ((_powerDown & 1)<<7) | ((_gain & 7)<<4) | (_mux & 7);
+    WREG(ADS129X_REG_CH1SET + (_channel-1), value);
+}
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ads1299.h	Wed May 29 03:43:46 2019 +0000
@@ -0,0 +1,223 @@
+#ifndef _ADS1299_h
+#define _ADS1299_h
+
+#define ADS129X_CMD_WAKEUP  0x02 // Wake-up from standby mode
+#define ADS129X_CMD_STANDBY 0x04 // Enter Standby mode
+#define ADS129X_CMD_RESET   0x06 // Reset the device
+#define ADS129X_CMD_START   0x08 // Start and restart (synchronize) conversions
+#define ADS129X_CMD_STOP    0x0A // Stop conversion
+#define ADS129X_CMD_RDATAC  0x10 // Enable Read Data Continuous mode (default mode at power-up)
+#define ADS129X_CMD_SDATAC  0x11 // Stop Read Data Continuous mode
+#define ADS129X_CMD_RDATA   0x12 // Read data by command; supports multiple read back
+#define ADS129X_CMD_RREG    0x20 // (also = 00100000) is the first opcode that the address must be added to for RREG communication
+#define ADS129X_CMD_WREG    0x40 // 01000000 in binary (Datasheet, pg. 35)
+
+// Register Addresses
+#define ADS129X_REG_ID         0x00 // ID Control Register
+#define ADS129X_REG_CONFIG1    0x01 // Configuration Register 1
+#define ADS129X_REG_CONFIG2    0x02 // Configuration Register 2
+#define ADS129X_REG_CONFIG3    0x03 // Configuration Register 3
+#define ADS129X_REG_LOFF       0x04 // Lead-Off Control Register
+#define ADS129X_REG_CH1SET     0x05 // Individual Channel Settings 1-8
+#define ADS129X_REG_CH2SET     0x06 // ---
+#define ADS129X_REG_CH3SET     0x07 // ---
+#define ADS129X_REG_CH4SET     0x08 // ---
+#define ADS129X_REG_CH5SET     0x09 // ---
+#define ADS129X_REG_CH6SET     0x0A // ---
+#define ADS129X_REG_CH7SET     0x0B // ---
+#define ADS129X_REG_CH8SET     0x0C // ---
+#define ADS129X_REG_RLD_SENSP  0x0D // Right Leg Drive, positive side
+#define ADS129X_REG_RLD_SENSN  0x0E // Right Leg Drive, negative side
+#define ADS129X_REG_LOFF_SENSP 0x0F // Lead-Off Detection, positive side
+#define ADS129X_REG_LOFF_SENSN 0x10 // Lead-Off Detection, negative side
+#define ADS129X_REG_LOFF_FLIP  0x11 // Lead-Off Detection, current direction
+#define ADS129X_REG_LOFF_STATP 0x12 // Electrode Status, positive (read-only)
+#define ADS129X_REG_LOFF_STATN 0x13 // Electrode Status, negative (read-only)
+#define ADS129X_REG_GPIO       0x14 // General-Purpose I/O Register
+#define ADS129X_REG_PACE       0x15 // PACE Detect Register
+#define ADS129X_REG_RESP       0x16 // Respiration Control Register
+#define ADS129X_REG_CONFIG4    0x17 // Configuration Register 4
+#define ADS129X_REG_WCT1       0x18 // Wilson Central Terminal and Augmented Lead Control Register
+#define ADS129X_REG_WCT2       0x19 // Wilson Central Terminal Control Register
+
+// IDs
+#define ADS129X_ID_ADS1294  0x90
+#define ADS129X_ID_ADS1296  0x91
+#define ADS129X_ID_ADS1298  0x92
+#define ADS129X_ID_ADS1294R 0xD0
+#define ADS129X_ID_ADS1296R 0xD1
+#define ADS129X_ID_ADS1298R 0xD2
+
+// Configuration Register 1
+#define ADS129X_BIT_HR       0x7
+#define ADS129X_BIT_DAISY_EN 0x6
+#define ADS129X_BIT_CLK_EN   0x5
+ 
+#define ADS129X_BIT_DR2      0x2
+#define ADS129X_BIT_DR1      0x1
+#define ADS129X_BIT_DR0      0x0
+
+// Configuration Register 2
+ 
+#define ADS129X_BIT_WCT_CHOP   0x5
+#define ADS129X_BIT_INT_TEST   0x4
+// always 0
+#define ADS129X_BIT_TEST_AMP   0x2
+#define ADS129X_BIT_TEST_FREQ1 0x1
+#define ADS129X_BIT_TEST_FREQ0 0x0
+#define ADS129X_TEST_FREQ_1HZ  0x0
+#define ADS129X_TEST_FREQ_2HZ  0x1
+#define ADS129X_TEST_FREQ_DC   0x3
+
+// Configuration Register 3
+#define ADS129X_BIT_PD_REFBUF     0x7
+// always 1
+#define ADS129X_BIT_VREF_4V       0x5
+#define ADS129X_BIT_RLD_MEAS      0x4
+#define ADS129X_BIT_RLDREF_INT    0x3
+#define ADS129X_BIT_PD_RLD        0x2
+#define ADS129X_BIT_RLD_LOFF_SENS 0x1
+#define ADS129X_BIT_RLD_STAT      0x0
+
+// Lead-Off Control Register
+#define ADS129X_BIT_COMP_TH2     0x7
+#define ADS129X_BIT_COMP_TH1     0x6
+#define ADS129X_BIT_COMP_TH0     0x5
+#define ADS129X_BIT_VLEAD_OFF_EN 0x4
+#define ADS129X_BIT_ILEAD_OFF1   0x3
+#define ADS129X_BIT_ILEAD_OFF0   0x2
+#define ADS129X_BIT_FLEAD_OFF1   0x1
+#define ADS129X_BIT_FLEAD_OFF0   0x0
+
+// Individual Channel Settings
+#define ADS129X_BIT_PD    0x7
+#define ADS129X_BIT_GAIN2 0x6
+#define ADS129X_BIT_GAIN1 0x5
+#define ADS129X_BIT_GAIN0 0x4
+// always 0
+#define ADS129X_BIT_MUX2  0x2
+#define ADS129X_BIT_MUX1  0x1
+#define ADS129X_BIT_MUX0  0x0
+
+// Channel Select
+#define ADS129X_BIT_CH8 0x7
+#define ADS129X_BIT_CH7 0x6
+#define ADS129X_BIT_CH6 0x5
+#define ADS129X_BIT_CH5 0x4
+#define ADS129X_BIT_CH4 0x3
+#define ADS129X_BIT_CH3 0x2
+#define ADS129X_BIT_CH2 0x1
+#define ADS129X_BIT_CH1 0x0
+
+// General-Purpose I/O Register
+#define ADS129X_BIT_GPIOD4 0x7
+#define ADS129X_BIT_GPIOD3 0x6
+#define ADS129X_BIT_GPIOD2 0x5
+#define ADS129X_BIT_GPIOD1 0x4
+#define ADS129X_BIT_GPIOC4 0x3
+#define ADS129X_BIT_GPIOC3 0x2
+#define ADS129X_BIT_GPIOC2 0x1
+#define ADS129X_BIT_GPIOC1 0x0
+
+// PACE Detect Register
+ 
+#define ADS129X_BIT_PACEE1  0x4
+#define ADS129X_BIT_PACEE0  0x3
+#define ADS129X_BIT_PACEO1  0x2
+#define ADS129X_BIT_PACEO0  0x1
+#define ADS129X_BIT_PD_PACE 0x0
+
+// Respiration Control Register
+#define ADS129X_BIT_RESP_DEMOD_EN1 0x7
+#define ADS129X_BIT_RESP_MOD_EN1   0x6
+// always 1
+#define ADS129X_BIT_RESP_PH2       0x4
+#define ADS129X_BIT_RESP_PH1       0x3
+#define ADS129X_BIT_RESP_PH0       0x2
+#define ADS129X_BIT_RESP_CTRL1     0x1
+#define ADS129X_BIT_RESP_CTRL0     0x0
+
+// Configuration Register 4
+#define ADS129X_BIT_RESP_FREQ2   0x7
+#define ADS129X_BIT_RESP_FREQ1   0x6
+#define ADS129X_BIT_RESP_FREQ0   0x5
+// always 0
+#define ADS129X_BIT_SINGLE_SHOT  0x3
+#define ADS129X_BIT_WCT_TO_RLD   0x2
+#define ADS129X_BIT_PD_LOFF_COMP 0x1
+// always 0
+
+// Wilson Central Terminal and Augmented Lead Control Register
+#define ADS129X_BIT_aVF_CH6 0x7
+#define ADS129X_BIT_aVF_CH5 0x6
+#define ADS129X_BIT_aVF_CH7 0x5
+#define ADS129X_BIT_aVF_CH4 0x4
+#define ADS129X_BIT_PD_WCTA 0x3
+#define ADS129X_BIT_WCTA2   0x2
+#define ADS129X_BIT_WCTA1   0x1
+#define ADS129X_BIT_WCTA0   0x0
+
+// Wilson Central Terminal Control Register
+#define ADS129X_BIT_PD_WCTC 0x7
+#define ADS129X_BIT_PD_WCTB 0x6
+#define ADS129X_BIT_WCTB2   0x5
+#define ADS129X_BIT_WCTB1   0x4
+#define ADS129X_BIT_WCTB0   0x3
+#define ADS129X_BIT_WCTC2   0x2
+#define ADS129X_BIT_WCTC1   0x1
+#define ADS129X_BIT_WCTC0   0x0
+
+// Gain Configuration
+#define ADS129X_GAIN_6X     0x0
+#define ADS129X_GAIN_1X     0x1
+#define ADS129X_GAIN_2X     0x2
+#define ADS129X_GAIN_3X     0x3
+#define ADS129X_GAIN_4X     0x4
+#define ADS129X_GAIN_8X     0x5
+#define ADS129X_GAIN_12X    0x6
+
+// Mux Configuration
+#define ADS129X_MUX_NORMAL      0x0 // Normal electrode input (default)
+#define ADS129X_MUX_SHORT       0x1 // Input shorted (for offset or noise measurements)
+#define ADS129X_MUX_RLD_MEAS    0x2 // Used in conjunction with RLD_MEAS bit for RLD measurements
+#define ADS129X_MUX_MVDD        0x3 // MVDD for supply measurement
+#define ADS129X_MUX_TEMP        0x4 // Temperature sensor
+#define ADS129X_MUX_TEST        0x5 // Test signal
+#define ADS129X_MUX_RLD_DRP     0x6 // RLD_DRP (positive electrode is the driver)
+#define ADS129X_MUX_RLD_DRN     0x7 // RLD_DRN (negative electrode is the driver)
+
+// Sample-rate Configuration
+#define ADS129X_SAMPLERATE_1024 0x6
+#define ADS129X_SAMPLERATE_512  0x5
+#define ADS129X_SAMPLERATE_256  0x4
+#define ADS129X_SAMPLERATE_128  0x3
+#define ADS129X_SAMPLERATE_64   0x2
+#define ADS129X_SAMPLERATE_32   0x1
+#define ADS129X_SAMPLERATE_16   0x0
+
+void ADS_INIT();
+void SPI_INIT();
+void WAKEUP();
+void STANDBY();
+void RSET();
+void START();
+void STOP();
+// Data Read Commands
+void RDATAC();
+void SDATAC();
+void RDATA();
+void SETUP();
+void Set_IRQ();
+
+        // Register Read/Write Commands
+char RREG(char _address);
+void RREG(char _address, char _numRegisters, char *_data); //to read multiple consecutive registers (Datasheet, pg. 38)
+void WREG(char _address, char _value);
+
+        // Functions for setup and data retrieval
+char getDeviceId();
+bool getData(long *buffer);
+
+void configChannel(char _channel, bool _powerDown, char _gain, char _mux);
+ 
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed May 29 03:43:46 2019 +0000
@@ -0,0 +1,90 @@
+#include "ads1299.h"
+#include "spi_slave.h"
+#include "mbed.h"
+
+DigitalOut  CLKSEL(PB_0);
+//DigitalOut  STRT(PA_3);
+//DigitalOut  PWDN(PC_0);
+//DigitalOut  RST(PA_0);
+DigitalOut LED(PC_6);
+Serial pc(USBTX, USBRX);
+
+int main() {
+     
+     SPI_INIT();
+     RSET();
+     wait_ms(1000);
+     SDATAC();
+     wait_us(20);
+     WREG(ADS129X_REG_CONFIG3,0x00);
+     wait_us(20);
+     WREG(ADS129X_REG_CONFIG1,0x94);
+     wait_us(20);
+     WREG(ADS129X_REG_CONFIG4,0x08);
+     wait_us(20);
+     WREG(0x14,0x80);
+     wait_us(20);
+     WREG(ADS129X_REG_CONFIG1,0x2);
+     wait_us(20);
+     for (int i = 1; i <= 9; i++) {
+             configChannel(i, false, ADS129X_GAIN_1X, ADS129X_MUX_SHORT);
+         }
+     
+     
+     /*SLV_INIT();
+     wait_us(1);
+       */
+       /*
+     CLKSEL = 1;
+     wait_us(5);
+     
+     STRT = 0;
+     PWDN = 1;
+     RST = 1;
+     wait_ms(100);
+     
+     RST = 0;
+     RST = 1;
+     
+     wait_ms(1); 
+     //SDATAC(); // device wakes up in RDATAC mode, so send stop signal
+     */
+     //WREG(ADS129X_REG_CONFIG1, ADS129X_SAMPLERATE_512);   
+   //  WREG(ADS129X_REG_CONFIG3, (1<<ADS129X_BIT_PD_REFBUF) | (1<<6));
+  //   WREG(0x14,0x80);  
+    // WREG(ADS129X_REG_CONFIG2, (1<<ADS129X_BIT_INT_TEST) | ADS129X_TEST_FREQ_1HZ);
+     
+  //  for (int i = 1; i <= 9; i++) {
+  //        configChannel(i, false, ADS129X_GAIN_1X, ADS129X_MUX_NORMAL);
+  //   }
+     
+   wait_ms(1);
+   //STRT = 1;
+  // RDATAC();
+  // START();
+   
+    LED=1;
+   
+while(1){
+    
+char value[3];
+long buffer[9];
+    START();
+    if(getData(buffer)){
+     for(int channel = 1; channel < 9; channel++) {
+           
+                value[0] = (char) (buffer[channel]>>16);
+                value[1] = (char) (buffer[channel]>>8);
+                value[2] = (char) (buffer[channel]);
+               // SLV_SEND(value[0],value[1],value[2]);
+                   
+         }
+       
+      }
+      
+  }
+   
+   
+   }
+   
+      
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed May 29 03:43:46 2019 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/7c328cabac7e
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spi_slave.cpp	Wed May 29 03:43:46 2019 +0000
@@ -0,0 +1,21 @@
+#include "mbed.h"
+#include "spi_slave.h"
+
+SPISlave slave(PC_1,PC_2,PB_10,PB_12);
+ 
+void SLV_INIT(){
+    slave.format(8,0);
+    slave.frequency(1000000);
+    }
+
+
+void SLV_SEND(char msb_data, char mib_data, char lsb_data){
+    
+    if(slave.receive()){
+       slave.reply(msb_data);
+       slave.reply(mib_data);
+       slave.reply(lsb_data);
+      }
+ }
+    
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spi_slave.h	Wed May 29 03:43:46 2019 +0000
@@ -0,0 +1,10 @@
+#ifndef _SPI_SLAVE_h
+#define _SPI_SLAVE_h
+
+
+
+void SLV_INIT();
+void SLV_SEND(char a, char b, char c);
+
+
+#endif
\ No newline at end of file