2

I would like to ask you for an explanation about this part of my code. I am not sure what it really does. This is example code and I would like to understand it. The purpose of the original code should be acquiring the data from ADC in the streaming mode. This should be about forming the raw data. Thank you.

#define CH_DATA_SIZE 6
uint8_t read_buf[CH_DATA_SIZE];
uint32_t adc_data;

TI_ADS1293_SPIStreamReadReg(read_buf, count);                            

adc_data = ((uint32_t) read_buf[0] << 16) | ((uint16_t) read_buf[1] << 8) 
| read_buf[2];
Dan
  • 33
  • 3

1 Answers1

1

I will skip the variable declaration, because I will refer to it in the rest of the description.

The code begins at this line:

TI_ADS1293_SPIStreamReadReg(read_buf, count);

From a Google search, I assume you have this function from this file. If it is this function, it will read three register from this module (see 8.6 Register Maps, the data registers DATA_CHx_ECG are three bytes long, which is what should be in the count variable).

Once this function executed, you have the ECG data in the first three bytes of the read_buf variable, but you want a 24-bit value since the quantified value is a 24-bit value.

Since we don't have uint24_t in C (and no other language I know of), we take the next possible size, which is uint32_t to declare the adc_data variable.

Now the following code does rebuild a single 24-bit value from the 3 bytes we read from the ADC:

adc_data = ((uint32_t) read_buf[0] << 16) | ((uint16_t) read_buf[1] << 8) 
| read_buf[2];

From the datasheet and the TI_ADS1293_SPIStreamReadReg, we know that the function does read the values in the order their addresses come, in this case high-byte, middle-byte and low-byte in this order (respectively in read_but[0], read_buf[1] and read_buf[2]).

To rebuild the 24-bit value, the code shifts the value with the appropriate offset: read_buf[0] goes from bits 23 to 16 thus shifted 16 bits, read_buf[1] from bits 15 to 8 thus shifted 8 bits and read_buf[2] from 7 to 0 thus shifted 0 bits (this shift is not represented). We will represent them as such (the 0xAA, 0xBB and 0xCC are example values to show what happens):

read_buf[0] = 0xAA => read_buf[0] << 16 = 0xAA0000
read_buf[1] = 0xBB => read_buf[0] << 8  = 0x00BB00
read_buf[2] = 0xCC => read_buf[0] << 0  = 0x0000CC

To combine the three shifted values, the code uses a bitwise-or | which results in this:

0xAA0000 | 0x00BB00 | 0x0000CC = 0xAABBCC

And you now have a 24-bit value of you ADC reading.

Simon Doppler
  • 1,918
  • 8
  • 26
  • Firstly, thank you for your very good explanation. Actually, the code is from the link [1]. Especially from demo 3, main.c. So now I can obtain an array of samples when interrupt from data ready arrived. I would like to read these data continuously or with any circular buffer. Do you have any advice about how to proceed? [1] http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=snac054&fileType=zip – Dan Apr 20 '19 at 14:10
  • @DanielVolný the code you used is different but performs the same function as I described, so my exaplanation still works. With the code in the demo 3, the data is read as soon as it is available (see [here](https://www.microchip.com/forums/m976413.aspx) why SPI should not occur in an interrupt routine). We would need more information as to what you want to do, but I think this would warrant another question regarding how to store the data in a circular buffer. – Simon Doppler Apr 20 '19 at 15:50