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.
Revision 0:99e31762ab2f, committed 2019-05-29
- 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
--- /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