Confirming SPI data rate

Discussion in 'Embedded Systems and Microcontrollers' started by Samyukta Ramnath, May 27, 2015.

  1. Samyukta Ramnath

    Thread Starter New Member

    May 21, 2015
    12
    0
    Besides filling a large array with data and running the program to send data at a particular data rate (say 2khz), and seeing whether in 2 seconds I get around 2000 data samples, is there any other way to actually verify the number of samples of data that I receive?
     
  2. Papabravo

    Expert

    Feb 24, 2006
    10,179
    1,800
    Yes. Look at the SCLK signal from the falling edge of chip select to the rising edge of chip select. Measuring throughput is really a very crude way to measure what you are after. 100% error would not surprise me.
     
  3. Samyukta Ramnath

    Thread Starter New Member

    May 21, 2015
    12
    0
    But the SCLK signal is what I have given from the master. So I am expecting 12 words, each 32 bits, and 2000 of these 12 word frames in 1 second. So the minimum clock I give from the master is 12*32*2000 = 768kHz. I gave around 1000kHz. If I measure SCLK now I'll be getting 1000 kHz, right?
     
  4. Papabravo

    Expert

    Feb 24, 2006
    10,179
    1,800
    You can only relate clock rate to throughput if the transfer is synchronous and continuous In most SPI applications there is a chip select going active, several bytes of data transfer, and chip select goes inactive. As you can see there is some amount of time that is not devoted to data transfer. You can measure clock rate or throughput but it is a mistake to conflate the two measurements.
     
    Last edited: May 27, 2015
  5. JWHassler

    Member

    Sep 25, 2013
    201
    33
    The SPI data-rate is the rate at which the master sends/receives.
    You're the master, so you know the data-rate already.
     
  6. Samyukta Ramnath

    Thread Starter New Member

    May 21, 2015
    12
    0
    I am commanding the slave to send me 2000 frames of twelve 32 bit words per second. I am giving sufficient SCLK as the master to sample this - but how do I confirm that the slave is indeed sending data at the rate it is supposed to, apart from checking throughput?


    Yes, that was my doubt. I know the SCLK rate - I want to confirm that the slave is sending that much data in 1 second.
     
  7. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,913
    2,187
    It's always byte sent/byte received. The actual contents of that data from the slave is up the slave to produce. You can embed check bits or bytes into the expected slave stream to check for correct data format and sequencing.
     
  8. Papabravo

    Expert

    Feb 24, 2006
    10,179
    1,800
    SPI is not a robust protocol. At the physical layer you have no idea if the slave device is sending valid data at all. If the MISO line is stuck at '1' or stuck at '0' the master would never know because it has no way to check for valid data from the slave device. At a higher layer in the stack you can embed such information but most slave devices don't do this. It's just data.
     
  9. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,913
    2,187
    Correct. I usually have a 'special' DUMMY byte that's loaded in the slave send buffer at reset/after each command sequence waiting to be clocked out by the first master receive byte.

    A simple dummy with config data.
    Code (Text):
    1.  
    2. /*
    3. * bit 7 high for commands sent from the MASTER
    4. * bit 6 0 send lower or 1 send upper byte ADC result first
    5. * bits 3..0 port address
    6. *
    7. * bit 7 low  for config data sent in CMD_DUMMY per uC type
    8. * bits 6 config bit code always 1
    9. * bit   5 0=ADC ref VDD, 1=ADC rec FVR=2.048
    10. * bit  4 0=10bit adc, 1=12bit adc
    11. * bits 3..0 number of ADC channels
    12. *
    13. */
    14.  
    15. #ifdef P8722
    16. #define CMD_DUMMY  0b01001100   /* 12 channels VDD */
    17. #define NUM_AI_CHAN  12
    18. #define SPI_BUF     SSP2BUF    
    19. #endif
    20. #ifdef P25K22
    21. #define CMD_DUMMY   0b01101110   /* 14 channels 2.048 but only 13 are ADC */
    22. #define NUM_AI_CHAN  14
    23. #define SPI_BUF     SSP2BUF
    24. #endif
    25. #ifdef P45K80
    26. #define CMD_DUMMY   0b00111010   /* 10 channels 2.048 but only 9 are ADC,bit 6 set for rs232 data waiting */
    27. #define NUM_AI_CHAN  10
    28. #define UART_TX_MASK   0b10000000
    29. #define UART_RX_MASK   0b01000000
    30. #define SPI_BUF     SSPBUF
    31. #endif
     
    Papabravo likes this.
  10. Samyukta Ramnath

    Thread Starter New Member

    May 21, 2015
    12
    0
    So the dummy byte is to confirm whether the correct data is sent ... am I right?
    So in my code, whenever I write to a particular address, I get back that address location in the first byte along with the data in the next three bytes, to form one four byte word, while writing the next word. So I know that I am getting the correct data. The only issue is the data rate.
    Is there something like a timestamp that I can add along with the data variable when it is being stored, to give me even an approximate idea that what I am receiving is close to what I should be?
    What about a USB-I2C converter to print data on to my computer screen at the rate it is being stored (popped from the rx fifo)?
     
  11. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,913
    2,187
    I don't see much of a problem doing that(timestamp). You know exactly what the data rate is because you control the master and know the data format sent by the slave in response.
     
  12. Samyukta Ramnath

    Thread Starter New Member

    May 21, 2015
    12
    0
    Thank you for your responses!
    I tried using the RTC to read the number of clock cycles. I used the RTC_TPR register. I Initialized the RTC and then read the value of the RTC_TPR register before loading the data variables and after loading the data variables.

    I have given a clock of 1000 kHz from the master for SPI communication, and I should be getting data at a rate of 2000 words per second from the slave. Now to achieve the timestamping, I have read the RTC clock at the event of receiving a word in the code. If the RTC clock is 32kHz, I should be able to correctly detect a data rate of 2000 words per second, right?
    However, the time interval according to the RTC to get 500 data variables is much less than 0.25 seconds. It is around 0.0175 seconds.
    Am I doing something wrong, either in using an RTC clock less than the SPI master clock (even though I need to detect the event as received word, not received byte), or in the way I am using the RTC clock?
    The code I have used is below:

    to initialize the RTC

    Code (Text):
    1. void rtc_init(uint32 seconds, uint32 alarm, uint8 c_interval, uint8 c_value, uint8 interrupt)
    2.  
    3. {
    4.  
    5.   int i;
    6.  
    7.  
    8.  
    9.   /*enable the clock to SRTC module register space*/
    10.  
    11.   SIM_SCGC6 |= SIM_SCGC6_RTC_MASK;
    12.  
    13.  
    14.  
    15.   /*Only VBAT_POR has an effect on the SRTC, RESET to the part does not, so you must manually reset the SRTC to make sure everything is in a known state*/
    16.  
    17.   /*clear the software reset bit*/
    18.  
    19.   RTC_CR  = RTC_CR_SWR_MASK;
    20.  
    21.   RTC_CR  &= ~RTC_CR_SWR_MASK;
    22.  
    23.  
    24.  
    25.   /*Enable the interrupt*/
    26.  
    27.   if(interrupt)
    28.  
    29.   enable_irq(66);
    30.  
    31.  
    32.  
    33.   /*Enable the oscillator*/
    34.  
    35.   RTC_CR |= RTC_CR_OSCE_MASK;
    36.  
    37.  
    38.  
    39.   /*Wait to all the 32 kHz to stabilize, refer to the crystal startup time in the crystal datasheet*/
    40.  
    41.   for(i=0;i<0x600000;i++);
    42.  
    43.  
    44.  
    45.   /*Set time compensation parameters*/
    46.  
    47.   RTC_TCR = RTC_TCR_CIR(c_interval) | RTC_TCR_TCR(c_value);
    48.  
    49.  
    50.  
    51.   /*Configure the timer seconds and alarm registers*/
    52.  
    53.   RTC_TSR = seconds;
    54.  
    55.   RTC_TAR = alarm;
    56.  
    57.   RTC_TPR = 0;
    58.  
    59.   /*Enable the counter*/
    60.  
    61.   RTC_SR |= RTC_SR_TCE_MASK;
    62.  
    63. }



    In main module, after SPI initialization:
    Code (Text):
    1.  
    2.  
    3.   time_initial= RTC_TPR;
    4.  
    5.   time_initial_sec = RTC_TSR;
    6.  
    7.   // test single byte transmission
    8.  
    9.   while(j<500){
    10.  
    11.   //for (j=0;j<4;j++){
    12.  
    13.   for (i=0;i<=11;i++){
    14.  
    15.   data[j] = reg_read(0x00000000);
    16.  
    17.   //I2C0_D = data;
    18.  
    19.   //I2C0_A1 = datain;
    20.  
    21.   time = RTC_TPR;
    22.  
    23.   time_sec = RTC_TSR;
    24.  
    25.   // printf("dataout: %x\ndatain: %x\ntime: %x\nTimeDirect: %x\n\n",data,datain,*ticky,time);
    26.  
    27.   j++;
    28.  
    29.   //  if(j==500)
    30.  
    31.   // printf("500!\n");
    32.  
    33.   }
    34.  
    35.   //printf("%d\n",j);
    36.  
    37.   reg_Write(0x40000000);
    38.  
    39.   }
    40.  
    41.   printf("initial time = %d\nintial sec = %d\nFinal Time =%d\nFinalTimeSec = %d\n\n",time_initial,time_initial_sec, time,time_sec);
    42.  
    43. }
    44.  



    Where reg_read and reg_Write are used to read and write from and to 32 bit words respectively.
     
  13. RamaD

    Active Member

    Dec 4, 2009
    254
    33
    As members have clarified, the master defines the data rate with its clock. On each clock, whatever is present on MISO pin is going to be taken in.
    So the simple way is, measure clock period with a scope. Should be 1uS.
    My wild guess is, given your measurment times, either the SPI clock is 10MHz., or your time period is 0.175s.
    Check your RTC clock reading, with a long time of, say 10s with a couple of start stop events. Sorry about being cryptic, but you get the idea.
     
Loading...