Incorrect Data sent/received through SPI

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

  1. Samyukta Ramnath

    Thread Starter New Member

    May 21, 2015
    12
    0
    I am trying to get a K53 Kinetis Freescale microcontroller and an ADAS1000SDZ Analog Front End microcontroller to talk to each other. I have the setup for sending words done and I can see the TX FIFO correctly being updated with the words I must send to the AFE (slave) to set control registers in the AFE and to send commands to the AFE to send back data.
    I am able to get some data received only in debug mode. When I run the program normally, I just get zeros.
    Moreover, the data that I am receiving in debug mode is not correct. I know this because If I must read the data at an address 0x11, I should get a 32 bit word whos MS bytes should be 0x11. i.e, 0x11abcdefg. This is not happening, or is happening too sporadically to say that I've succeeded.
    One issue I had initially was timining. I've configured the ADE to output data at 2kHz and I should be having a minimum SCLK (master clock) of 768kHz. I had it too high, initially, and was receiving no data at all. Having lowered the SCLK to about 1500 kHz, I am receiving this incorrect data.

    I have attached my code for writing to registers and the initializations. Any suggestions would be much appreciated as I have spent quite a bit of time trying to get the correct data in, trying out different combinations of clock polarity and so.

    My Initializations are like so:

    Code (Text):
    1.  
    2.       SPI0_MCR = ((SPI_MCR_HALT_MASK) | //halts transfers
    3.                   (SPI_MCR_MDIS_MASK & 0x00)); //enables module clocks
    4.       SPI0_MCR = (SPI_MCR_MSTR_MASK )| //master mode
    5.                  (SPI_MCR_ROOE_MASK)| // incoming data shifted into shift register
    6.                                       //overwriting previous data
    7.                                       //when RX FIFO is full
    8.                   (SPI_MCR_DCONF(0x00))| // SPI
    9.                     (SPI_MCR_PCSIS(1))| // determines inactive state of PC(X):
    10.                                          // 0 : inactive PC(x) is low
    11.                       (SPI_MCR_DIS_TXF_MASK)|
    12.                         (SPI_MCR_DIS_RXF_MASK)|
    13.                           (SPI_MCR_CONT_SCKE_MASK && 0x00); //continuous SKE enable
    14.                  
    15.  
    16.     SPI0_CTAR0 = (SPI_CTAR_DBR_MASK & 0x00) |
    17.                 (SPI_CTAR_FMSZ(0x07)) | //frame size = 8bits
    18.                   (SPI_CTAR_PDT(0x00)) |
    19.                     (SPI_CTAR_BR(0x04)) | //was 0x07  //baud rate prescaler
    20.                       (SPI_CTAR_CPOL_MASK & 0x00) |
    21.                         (SPI_CTAR_CPHA_MASK & 0x00) |
    22.                           (SPI_CTAR_PBR(0x02)) | //was 0x02  /pre baud prescaler
    23.                             (SPI_CTAR_PCSSCK(0x02) |
    24.                              (SPI_CTAR_PASC(0x00)) |
    25.                                (SPI_CTAR_CSSCK(0x06)) |
    26.                                  (SPI_CTAR_ASC(0)) |
    27.                                    (SPI_CTAR_PDT(0x00)) |
    28.                                      (SPI_CTAR_DT(0))) ; // mode 0 operation
    29.  
    30.     SPI0_MCR &= 0xfffffffe ; //start transfers again
    31.  
    And the way I write to registers is byte by byte, so for 32 bit word I must push 4 times for one word.

    Code (Text):
    1.  
    2. int register_configure(int address)
    3. {
    4.      //int data[5];
    5.      int data;
    6.      unsigned int data1,data2,data3,data4;
    7.      int address1, address2, address3,address4;
    8.      address1 = address & 0x000000ff;
    9.      address2=address & 0x0000ff00;
    10.      address2 = address2>>8;
    11.      address3 = address & 0x00ff0000;
    12.      address3 = address3>>16;
    13.      address4 = address & 0xff000000;
    14.      address4 = address4>>24;
    15.      address4 = address4 & 0x000000ff;
    16.      SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | //The CTAR0 is selected
    17.                    (SPI_PUSHR_CONT_MASK) | //Chip select is continuous through transfers
    18.                      SPI_PUSHR_TXDATA(address4))|
    19.                        SPI_PUSHR_PCS(1) ; //Pushes the required data
    20.                      
    21.    
    22.      while((SPI0_SR & SPI_SR_TCF_MASK)==0){}//wait till the transfer is complete
    23.      data1 = SPI0_POPR; // the latest data in the RX FIFO is transferred to data1
    24.      while((SPI0_SR & SPI_SR_TFFF_MASK)==0); //wait till the TX FIFO is not empty
    25.      while((SPI0_SR & SPI_SR_RFDF_MASK)==0); //wait till the RX FIFO is not empty
    26.    
    27.    
    28.      SPI0_SR |= SPI_SR_TFFF_MASK; // TX FIFO is not empty set
    29.      SPI0_SR |= SPI_SR_RFDF_MASK; //sets the RX FIFO is not empty flag  
    30.      SPI0_SR |= SPI_SR_TCF_MASK; //Transfer is complete flag set
    31.    
    32.      SPI0_PUSHR = (SPI_PUSHR_CTAS(0x00)) |
    33.                    (SPI_PUSHR_CONT_MASK) |
    34.                        SPI_PUSHR_TXDATA(address3)|
    35.                           SPI_PUSHR_PCS(1); //CS is asserted
    36.      while((SPI0_SR & SPI_SR_TCF_MASK)==0){}//wait till the transfer is complete
    37.      while((SPI0_SR & SPI_SR_TFFF_MASK)==0); //wait till the TX FIFO is not empty
    38.      while((SPI0_SR & SPI_SR_RFDF_MASK)==0); //wait till the RX FIFO is not empty
    39.      data2 = SPI0_POPR; // the latest data in the RX FIFO is transferred to data1
    40.  
    41.  
    42.      SPI0_SR |= SPI_SR_TFFF_MASK; // TX FIFO is not empty set
    43.      SPI0_SR |= SPI_SR_RFDF_MASK; //sets the RX FIFO is not empty flag  
    44.      SPI0_SR |= SPI_SR_RFOF_MASK;
    45.      SPI0_SR |= SPI_SR_TCF_MASK; //Transfer is complete flag set
    46.        
    47.    
    48.      SPI0_PUSHR = (SPI_PUSHR_CTAS(0x00)) |
    49.                     (SPI_PUSHR_CONT_MASK) |
    50.                       SPI_PUSHR_TXDATA(address2)|
    51.                         SPI_PUSHR_PCS(1);
    52.      while((SPI0_SR & SPI_SR_TCF_MASK)==0){}//wait till the transfer is complete
    53.      while((SPI0_SR & SPI_SR_TFFF_MASK)==0); //wait till the TX FIFO is not empty
    54.      while((SPI0_SR & SPI_SR_RFDF_MASK)==0); //wait till the RX FIFO is not empty
    55.      data3 = SPI0_POPR; // the latest data in the RX FIFO is transferred to data1
    56.  
    57.  
    58.      SPI0_SR |= SPI_SR_TFFF_MASK; // TX FIFO is not empty set
    59.      SPI0_SR |= SPI_SR_RFDF_MASK; //sets the RX FIFO is not empty flag  
    60.      SPI0_SR |= SPI_SR_RFOF_MASK;
    61.      SPI0_SR |= SPI_SR_TCF_MASK; //Transfer is complete flag set
    62.    
    63.    
    64.      SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) |
    65.                    (SPI_PUSHR_CONT_MASK) |
    66.                      SPI_PUSHR_TXDATA(address1)|
    67.                        SPI_PUSHR_PCS(1));
    68.      while((SPI0_SR & SPI_SR_TCF_MASK)==0){}//wait till the transfer is complete
    69.      while((SPI0_SR & SPI_SR_TFFF_MASK)==0); //wait till the TX FIFO is not empty
    70.      while((SPI0_SR & SPI_SR_RFDF_MASK)==0); //wait till the RX FIFO is not empty
    71.      data4 = SPI0_POPR; // the latest data in the RX FIFO is transferred to data1
    72.  
    73.  
    74.      SPI0_SR |= SPI_SR_TFFF_MASK; // TX FIFO is not empty set
    75.      SPI0_SR |= SPI_SR_RFDF_MASK; //sets the RX FIFO is not empty flag  
    76.    
    77.      SPI0_SR |= SPI_SR_TCF_MASK; //Transfer is complete flag set
    78.      data = (((data1<<24) & 0xff000000)|((data2<<16)&0x00ff0000)|((data3<<8)&0x0000ff00)|(data4 &  0x000000ff));
    79.    
    80.      return data;
    81. }
    82.  
    Moderators note : Please use code tags for pieces of code
     
  2. Samyukta Ramnath

    Thread Starter New Member

    May 21, 2015
    12
    0
    So after scoping out the SCLK, MISO, MOSI and CS, I have seen that the CS, MOSI and SCLK are actually as I expect them to be and they are going into the ADAS1000 (slave) correctly. However the ADAS1000 is giving out a signal on the MISO line that is very noisy. Since the commands sent were correct, I am unable to find the problem.
     
  3. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    One thing might be to check what size int is for your compiler, it may not be a 32-bit number.

    As far as the noise, are the grounds connected between the two? A schematic might help...
     
  4. Samyukta Ramnath

    Thread Starter New Member

    May 21, 2015
    12
    0
    That was actually the whole problem. The grounds weren't connected, and the noise hence caused the garbage. I have never had to connect boards because they are usually connected to the PC, but this time the ADAS isn't connected to the PC. Thanks!
     
Loading...