Other Parts Discussed in Thread: ADS1292
Tool/software: Code Composer Studio
Hello friends,
I have a problem with the ADS1292R sensor, after several months of working around this device, I finally see a small light at the end of the tunnel.
I have created all of the spi drivers and device registers, I began to create the main, but now I'm in a dead end.Someone can help me?!
#include <msp.h> #include "ADS1292_R.h" #include "main.h" /****************************************************************/ /* PROTOTYPES */ /****************************************************************/ /****************************************************************/ /* GLOBAL VARIABLES */ /****************************************************************/ unsigned char ADC_Read_Data[16]; unsigned char ADS1292_R_SPI_CMD_F = 0, ADS1292_R_SPI_DATA_F = 0, SPI_SEND_COUNT = 0, SPI_Tx_COUNT = 0, SPI_Tx_BUF[10]; unsigned char SPI_Rx_DATA_F = 0, SPI_Rx_BUF[12], SPI_Rx_COUNT = 0, SPI_Rx_EXP_COUNT = 0; unsigned char ECG_DATA_RDY; long ADS1292R_ECG_DATA_BUF[6]; extern struct ADS1292x_STATE ecgState; unsigned char ECG_RECORDER_DATA_BUF[256], RECORDER_HEAD, RECORDER_TAIL; unsigned char STORE_DATA_RDY; #define DELAY_COUNT 2 /*ADS1292_R REGISTER VALUE*/ unsigned char ADS1292R_REG_VALUE[16] = { 0x00, /*DEVICE ID READ ONLY*/ 0x02, /*CONFIG_1*/ 0xE0, /*CONFIG_2*/ 0xF0, /*LEAD_OFF*/ 0x00, /*CH1_SET*/ 0x00, /*CH2_SET*/ 0x2C, /*RLD_SENS*/ 0x0F, /*LED_OFF_SENS*/ 0x00, /*LED_OFF_STAT*/ 0xEA, /*RESP_1*/ 0x03, /*RESP_2*/ 0x0C /*GPIO*/ }; unsigned char ADS1292R_DEFAULT_REGISTER_SETTINGS[15] = { 0x00, /*DEVICE ID READ ONLY*/ 0x02, /*CONFIG_1*/ 0xE0, /*CONFIG_2*/ 0xF0, /*LEAD_OFF*/ 0x00, /*CH1_SET*/ 0x00, /*CH2_SET*/ 0x2C, /*RLD_SENS*/ 0x0F, /*LED_OFF_SENS*/ 0x00, /*LED_OFF_STAT*/ 0xEA, /*RESP_1*/ 0x03, /*RESP_2*/ 0x0C /*GPIO*/ }; /****************************************************************/ /* VARIABLES TO SPI INTERACTION */ /****************************************************************/ /*ADS1292R CLOCK SELECT*/ void ADS1292R_CLOCK_SELECT(unsigned char clock_in){ if(clock_in == 1){ P4->OUT |= (enum PORT4_ADC_CONTROL)ADC_CLK_SEL; /*CHOOSE INTERNAL CLOCK INPUT - 1*/ }else{ P4->OUT &= ~(enum PORT4_ADC_CONTROL)ADC_CLK_SEL; /*CHOOSE EXTERNAL CLOCK INPUT - 0*/ } } /*ADS1292R RESET*/ void ADS1292R_RESET(void){ unsigned short i; P3->OUT |= (enum PORT3_ADC_CONTROL)RESET; /*SET HIGH*/ /*PROVIDE SUFICIENT DELAY*/ for(i = 0; i < 5000; i++); /*WAIT 1 mSEC*/ P3->OUT &= ~(enum PORT3_ADC_CONTROL)ADC_RESET; /*SET LOW*/ for(i = 0; i < 5000; i++); /*WAIT 1 mSEC*/ P3->OUT |= (enum PORT3_ADC_CONTROL)ADC_RESET; for(i = 0; i < 35000; i++); } /*ADS1292R DISABLE START*/ void ADS1292R_DISABLE_START(void){ unsigned short i; P3->OUT &= ~(enum PORT3_ADC_CONTROL)ADC_START; /*SET LOW*/ for(i = 0; i < 35000; i++); /*SMALL DELAY TO SETTLE*/ } /*ADS1292R ENABLE START*/ void ADS1292R_ENABLE_START(void){ unsigned short i; P3->OUT |= (enum PORT3_ADC_CONTROL)ADC_START; /*SET HIGH*/ for(i = 0; i < 35000; i++); /*SMALL DELAY TO SETTLE*/ } /*ADS1292R CHIP ENABLE*/ void ADS1292R_CHIP_ENABLE(void){ /*ADS1292R CS IS ACTIVE LOW*/ P3->OUT &= ~(enum PORT3_ADC_CONTROL)ADC_START; /*SET LOW*/ } /*CLEAR CHIP ENABLE*/ void CLEAR_ADS1292R_CHIP_ENABLE(void){ unsigned char csDelay; for(csDelay = 0; csDelay < 100; csDelay++); /*ADS1292R CS IS ACTIVE LOW*/ P3->OUT |= (enum PORT3_ADC_CONTROL)ADC_START; /*SET HIGH*/ } /*INIT ADS1292R DRDY INTERRUPT*/ void INIT_ADS1292R_DRDY_INTERRUPT(void){ P2->DIR &= ~(0x02); P2->REN |= BIT5; /*ENABLE P2.5 INTERNAL RESISTENCE*/ P2->OUT |= BIT5; /*SET P2.5 AS PULL-UP RESISTENCE*/ P2->IES |= BIT5; /*P2.5 LO/HI EDGE*/ P2->IFG &= ~(BIT5); /*P2.5 IFG CLEARED*/ P2->IE &= ~(BIT5); /*P2.5 INTERRUPT DISABLE*/ } /*ENABLE ADS1292R DRDY INTERRUPT*/ void ENABLE_ADS1292R_DRDY_INTERRUPT(void){ P2->IFG &= ~(BIT5); /*P2.5 IFG CLEARED*/ P2->IE |= BIT5; /*P2.5 INTERRUPT ENABLE*/ } /*DISABLE ADS1292R DRDY INTERRUPT*/ void DISABLE_ADS1292R_DRDY_INTERRUPT(void){ P2->IFG &= ~(BIT5); /*P2.5 IFG CLEARED*/ P2->IE &= ~(BIT5); /*P2.5 INTERRUPT DISABLE*/ } /*SET GPIO*/ void SET_GPIO(void){ P4->SEL0 = 0x00; P4->DIR |= 0x8F; P4->OUT |= (enum PORT4_ADC_CONTROL)POW_CE; P3->DIR |= 0x07; P3->OUT &= 0xF8; P3->OUT |= (enum PORT3_ADC_CONTROL)ADC_CS; /*SET RESET, START TO LOW AND CS TO HIGH*/ P3->OUT |= (enum PORT3_ADC_CONTROL)ADC_RESET; /*SET RESET, START TO LOW AND CS TO HIGH*/ P1->OUT |= P4->OUT = 0x03; } /*SET EUSCI_B0 SP1*/ void SET_EUSCI_SPI(void){ P3->SEL0 |= BIT5 | BIT6 | BIT7; /*SET 3 PIN SPI PERIPHERAL BITS*/ P3->DIR |= BIT5 | BIT6; /*CLOCK AND DIROUT AS OUTPUT*/ P3->DIR &= ~(BIT7); /*DIN AS INPUT*/ EUSCI_B0->CTLW1 |= EUSCI_B_CTLW0_SWRST; /*ENABLE SW RESET*/ EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_MSB | /*MSB FIRST*/ EUSCI_B_CTLW0_MST | /*MASTER MODE*/ EUSCI_B_CTLW0_SYNC; /**/ EUSCI_B0->CTLW1 |= EUSCI_B_CTLW0_SSEL__ACLK; UCB0BR0 = 24; UCB0BR1 = 0; EUSCI_B0->CTLW1 &= ~(EUSCI_B_CTLW0_SWRST); } /*SET DMA SPI*/ void SET_DMA_SPI(void){ } /*ADS1292R SPI COMMAND DATA*/ void ADS1292R_SPI_COMMAND_DATA(unsigned char Data){ unsigned char delayVar; ADS1292R_CHIP_ENABLE(); for(delayVar = 0; delayVar < 50; delayVar++); CLEAR_ADS1292R_CHIP_ENABLE(); ADS1292R_CHIP_ENABLE(); EUSCI_B0->TXBUF = Data; while ((EUSCI_B0->STATW & EUSCI_B_STATW_BBUSY)); delayVar = EUSCI_B0->RXBUF; for(delayVar = 0; delayVar < 150; delayVar++); } /*ADS1292R INIT RESOURCE*/ void INIT_ADS1292R_RESOURCE(void){ SET_GPIO(); /*INITIALIZE ADS1292R INPUT CONTROL LINES*/ SET_EUSCI_SPI(); /*INITIALIZE SPI REGISTER*/ } /****************************************************************/ /* ADS1292R CONTROL REGISTERS */ /****************************************************************/ /*WAKE UO ADS1292R*/ void WAKE_UP_ADS1292R(void){ ADS1292R_SPI_COMMAND_DATA(WAKE_UP); } /*PUT ADS1292R IN SLEEP*/ void PUT_ADS1292R_IN_SLEEP(void){ ADS1292R_SPI_COMMAND_DATA(STAND_BY); } /*SOFT RESET ADS1292R*/ void SOFT_RESET_ADS1292R(void){ ADS1292R_SPI_COMMAND_DATA(RESET); } /*SOFT START RESTART ADS1292R*/ void SOFT_START_RESTART_ADS1292R(void){ ADS1292R_SPI_COMMAND_DATA(START); CLEAR_ADS1292R_CHIP_ENABLE(); } /*HARD START RESTART ADS1292R*/ void HARD_START_RESTART_ADS1292R(void){ P3->OUT |= (enum PORT3_ADC_CONTROL)ADC_START; /*SET START PIN TO HIGH*/ } /*SOFT START ADS12P2R*/ void SOFT_START_ADS1292R(void){ ADS1292R_SPI_COMMAND_DATA(START); } /*SOFT STOP ADS1292R*/ void SOFT_STOP_ADS1292R(void){ ADS1292R_SPI_COMMAND_DATA(STOP); } /*######################################################################*/ /*HARD STOP ADS1292R*/ void HARD_STOP_ADS1292R(void){ unsigned short i, j; P3->OUT &= ~(enum PORT3_ADC_CONTROL)ADC_START; /*SET START PIN TO LOW*/ for(j=0; j < DELAY_COUNT;j++ ){ for(i= 0; i < 35000; i++); } } /*STOP READ DATA CONTINUOUS*/ void STOP_READ_DATA_CONTINUOUS(void){ ADS1292R_SPI_COMMAND_DATA(S_DATA_C); } /*START READ DATA CONTINUOUS*/ void START_READ_DATA_CONTINUOUS(void){ ADS1292R_SPI_COMMAND_DATA(R_DATA_C); } /*START DATA CONVERTION COMMAND*/ void START_DATA_CONVERTION_COMMAND(void){ ADS1292R_SPI_COMMAND_DATA(START); } /*INITIALIZE ADS1292R*/ void INIT_ADS1292R(void){ ADS1292R_RESET(); ADS1292R_DISABLE_START(); ADS1292R_ENABLE_START(); } /*ENABLE ADS1292R CONVERTION*/ void ENABLE_ADS1292R_CONVERTION(void){ START_READ_DATA_CONTINUOUS(); /*R_DATA_C COMMAND*/ HARD_START_RESTART_ADS1292R(); } /*ADS1292R REGISTER WRITE*/ void ADS1292R_REGISTER_WRITE(unsigned char READ_WRITE_ADDRESS, unsigned char DATA){ short i; switch(READ_WRITE_ADDRESS){ case 1: DATA = DATA & 0x87; break; case 2: DATA = DATA & 0x87; DATA|= 0x80; break; case 3: DATA = DATA & 0xFD; DATA|= 0x10; break; case 7: DATA = DATA & 0x3F; break; case 8: DATA = DATA & 0x5F; break; case 9: DATA |= 0x02; break; case 10: DATA = DATA & 0x87; DATA |= 0x01; break; case 11: DATA = DATA & 0x0F; break; default: break; } SPI_Tx_BUF[0] = READ_WRITE_ADDRESS | W_REG; SPI_Tx_BUF[1] = 0; SPI_Tx_BUF[2] = DATA; ADS1292R_CHIP_ENABLE(); for(i=0; i < 50; i++); EUSCI_B0->TXBUF = SPI_Tx_BUF[0]; while ((EUSCI_B0->STATW & EUSCI_B_STATW_BBUSY)); i = EUSCI_B0->RXBUF; EUSCI_B0->TXBUF = SPI_Tx_BUF[1]; while ((EUSCI_B0->STATW & EUSCI_B_STATW_BBUSY)); i = EUSCI_B0->RXBUF; EUSCI_B0->TXBUF = SPI_Tx_BUF[2]; while ((EUSCI_B0->STATW & EUSCI_B_STATW_BBUSY)); i = EUSCI_B0->RXBUF; } /*ADS1292R REGISTER READ*/ unsigned char ADS1292R_REGISTER_READ(unsigned char REGISTER_ADDRESS){ unsigned char retVal; SPI_Tx_BUF[0] = REGISTER_ADDRESS | R_REG; SPI_Tx_BUF[1] = 0; ADS1292R_CHIP_ENABLE(); EUSCI_B0->TXBUF = SPI_Tx_BUF[0]; while ((EUSCI_B0->STATW & EUSCI_B_STATW_BBUSY)); EUSCI_B0->TXBUF = SPI_Tx_BUF[1]; while ((EUSCI_B0->STATW & EUSCI_B_STATW_BBUSY)); retVal = EUSCI_B0->RXBUF; EUSCI_B0->TXBUF = 0x00; while ((EUSCI_B0->STATW & EUSCI_B_STATW_BBUSY)); retVal = EUSCI_B0->RXBUF; CLEAR_ADS1292R_CHIP_ENABLE(); return retVal; } /*ADS1292R DEFAULT REGISTER INITIALIZATION*/ void ADS1292R_DEFAULT_REGISTER_INIT(void){ unsigned char regInit_i; ADS1292R_CHIP_ENABLE(); for(regInit_i = 0; regInit_i < 100; regInit_i++); CLEAR_ADS1292R_CHIP_ENABLE(); if((ADS1292R_REG_VALUE[0] & 0x20) == 0x20){ for(regInit_i = 1; regInit_i < 12; regInit_i ++){ ADS1292R_REGISTER_WRITE(regInit_i,ADS1292R_DEFAULT_REGISTER_SETTINGS[regInit_i]); } }else{ for(regInit_i = 1; regInit_i < 12; regInit_i ++){ ADS1292R_REGISTER_WRITE(regInit_i,ADS1292R_DEFAULT_REGISTER_SETTINGS[regInit_i]); } } } /*ADS1292R READ ALL REGISTERS*/ void ADS1292_READ_ALL_REGISTERS(unsigned char ADS1292R_REG_BUF[]){ unsigned char regs_I; ADS1292R_CHIP_ENABLE(); for(regs_I = 0; regs_I < 200; regs_I++); CLEAR_ADS1292R_CHIP_ENABLE(); for(regs_I = 0; regs_I < 200; regs_I++){ ADS1292R_REG_BUF[regs_I] = ADS1292R_REGISTER_READ(regs_I); } } /*ADS1292R POWER ON INIT*/ void ADS1292R_POWER_ON_INIT(void){ volatile unsigned short init_I, j; INIT_ADS1292R_RESOURCE(); ADS1292R_RESET(); for(j = 0; j < DELAY_COUNT; j++){ for(init_I = 0; init_I < 20000; init_I++); for(init_I = 0; init_I < 20000; init_I++); for(init_I = 0; init_I < 20000; init_I++); } INIT_ADS1292R_DRDY_INTERRUPT(); ADS1292R_CLOCK_SELECT(1); /*SET INTERNAL CLOCK*/ for(init_I = 0; init_I < 20000; init_I++); for(init_I = 0; init_I < 20000; init_I++); for(init_I = 0; init_I < 20000; init_I++); ADS1292R_DISABLE_START(); ADS1292R_ENABLE_START(); HARD_STOP_ADS1292R(); START_DATA_CONVERTION_COMMAND(); SOFT_STOP_ADS1292R(); for(j = 0; j < DELAY_COUNT; j++){ for(init_I = 0; init_I < 20000; init_I++); } STOP_READ_DATA_CONTINUOUS(); /*S_DATA_C COMMAND*/ for(j = 0; j < DELAY_COUNT; j++){ for(init_I = 0; init_I < 35000; init_I++); } for(j = 0; j < DELAY_COUNT; j++){ for(init_I = 0; init_I < 35000; init_I++); } ADS1292_READ_ALL_REGISTERS(ADS1292R_REG_VALUE); ADS1292R_DEFAULT_REGISTER_INIT(); ADS1292_READ_ALL_REGISTERS(ADS1292R_REG_VALUE); } /*ECG PACKET*/ void ADS1292R_PARSE_DATA_PACKET(void){ unsigned char ecgChanNum; switch(ecgState.state){ case DATA_STREAMING_STATE: { for(ecgChanNum = 0; ecgChanNum < 3; ecgChanNum++){ ADS1292R_ECG_DATA_BUF[ecgChanNum] = ( signed long)SPI_Rx_BUF[3 * ecgChanNum]; ADS1292R_ECG_DATA_BUF[ecgChanNum] = ADS1292R_ECG_DATA_BUF[ecgChanNum] << 8; ADS1292R_ECG_DATA_BUF[ecgChanNum]|= SPI_Rx_BUF[3 * ecgChanNum + 1]; ADS1292R_ECG_DATA_BUF[ecgChanNum] = ADS1292R_ECG_DATA_BUF[ecgChanNum] << 8; ADS1292R_ECG_DATA_BUF[ecgChanNum]|= SPI_Rx_BUF[3 * ecgChanNum + 2]; } } break; case ACQUIRE_DATA_STATE: break; case ECG_RECORDING_STATE: { unsigned char *ptr; ptr = &ECG_RECORDER_DATA_BUF[RECORDER_HEAD << 3]; *ptr++ = SPI_Rx_BUF[0]; *ptr++ = SPI_Rx_BUF[1]; *ptr++ = SPI_Rx_BUF[3]; *ptr++ = SPI_Rx_BUF[4]; *ptr++ = SPI_Rx_BUF[5]; *ptr++ = SPI_Rx_BUF[6]; *ptr++ = SPI_Rx_BUF[7]; *ptr++ = SPI_Rx_BUF[8]; RECORDER_HEAD++; if(RECORDER_HEAD == 32) RECORDER_HEAD = 0; } break; default: break; } } /**/ void ADS1x92R_PARSE_DATA_PACKET (void){ switch(ADS1292R_REG_VALUE[0] & 0x03){ case ADS1292R_24BIT: ADS1292R_PARSE_DATA_PACKET(); break; } ECG_DATA_RDY = 1; } void SET_DEVICE_OUT_BYTES(void){ switch(ADS1292R_REG_VALUE[0] & 0x03){ case ADS1292R_24BIT: SPI_Rx_EXP_COUNT = 9; break; } } /*SPI INTERRUPT SERVICE ROUTINE*/ void EUSCIB0_IRQHandler(void){ SPI_Rx_BUF[SPI_Rx_COUNT] = EUSCI_B0->RXBUF; SPI_Rx_COUNT++; if(SPI_Rx_COUNT == SPI_Rx_EXP_COUNT){ EUSCI_B0->IE &= ~(EUSCI_B_IE_RXIE); /*DISABLE RX INTERRUPT*/ ADS1292R_PARSE_DATA_PACKET(); }else{ EUSCI_B0->TXBUF = 0; } } /*PORT x INTERRUPT SERVICE ROUTINE*/ void PORT2_IRQHandler(void){ if(P2->IFG &= BIT5){ P2->IFG &= ~(BIT5); SPI_Rx_COUNT =EUSCI_B0->RXBUF; SPI_Rx_COUNT = 0; EUSCI_B0->TXBUF = 0; EUSCI_B0->IE |= EUSCI_B_IE_RXIE; } }
#include <msp.h> //#include <intrinsics.h> #include <string.h> #include "main.h" #include "ADS1292_R.h" extern unsigned char ADS1292R_REG_VALUE[16]; extern unsigned char SPI_Rx_BUF[]; extern unsigned char ECG_DATA_RDY; extern long ADS1292R_ECG_DATA_BUF[6]; extern unsigned char ECG_RECORDER_DATA_BUF[256], RECORDER_HEAD, RECORDER_TAIL; struct ADS1292x_STATE ecgState; void main(void){ volatile unsigned short i, j; WATCHDOGHOLD(); init_Start_Up(); ADS1292R_POWER_ON_INIT(); START_READ_DATA_CONTINUOUS(); for(i = 0; i < 10000; i++); for(i = 0; i < 10000; i++); for(i = 0; i < 10000; i++); ADS1292R_DISABLE_START(); ADS1292R_ENABLE_START(); for(i = 0; i < 10000; i++); for(i = 0; i < 10000; i++); for(i = 0; i < 10000; i++); ecgState.state = IDLE_STATE; ecgState.command = 0; while(1){ if((ecgState.state == IDLE_STATE)){ /**/ ADS1292R_DISABLE_START(); ADS1292R_ENABLE_START(); ADS1292R_DISABLE_START(); ADS1292R_CHIP_ENABLE(); CLEAR_ADS1292R_CHIP_ENABLE(); ADS1292R_CHIP_ENABLE(); START_READ_DATA_CONTINUOUS(); ENABLE_ADS1292R_DRDY_INTERRUPT(); ADS1292R_ENABLE_START(); ecgState.state = ECG_RECORDING_STATE; }else if((ecgState.state == ECG_RECORDING_STATE)){ ecgState.state = IDLE_STATE; DISABLE_ADS1292R_DRDY_INTERRUPT(); STOP_READ_DATA_CONTINUOUS(); } switch(ecgState.state){ case IDLE_STATE: if(ecgState.command!= 0){ ecgState.command = 0; } break; case DATA_STREAMING_STATE: break; case ACQUIRE_DATA_STATE: break; case ECG_RECORDING_STATE: if(RECORDER_HEAD!=RECORDER_TAIL){ RECORDER_TAIL++; if((RECORDER_TAIL % 4) == 0){ /*AFTER EVERY 8 SAMPLES STORE ECG DATA TO MEMORY*/ if(RECORDER_TAIL == 32) /*RESET TAIL AFTER 32 SAMPLES*/ RECORDER_TAIL = 0; } } break; default: break; } }/*while*/ }/*main*/ void init_Start_Up(void){ __disable_interrupt(); //init_Clock(); __enable_interrupt(); } void WATCHDOGHOLD(void){ WDTCTL = WDTPW + WDTHOLD; /*STOP WATCHDOG TIMER*/ }