S32K SPI RX not able to retrieve Data from RDR register

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

S32K SPI RX not able to retrieve Data from RDR register

Jump to solution
3,105 Views
christianhdz
Contributor II

I am trying to setup the SPI for the s32K142. I am trying to communicate with the SBC (NXP UJA1167).  I do a transmit of 16 bits (8 bit address + 8 dummy bits) message  to do the RX. I can see in my oscilloscope the slave is answering. I also see the information in the LPSPI0 RDR register however when I try to copy the info from the LPSPI0_RDR, the info I get is 0x00, though I see in the debugger something different (i.e. 0xFDD8).

I call   " SBC_readout= SBC_read(0x7E); "

and I see in the oscilloscope the TX and RX signals being correctly shown. However, the LPSPI0 RDR register cannot be copied to a variable, as the result it is wiped to 0's, and only zeros are copied to the variable ('receive' variable).

I used the functions and header files from the S32K142 cookbook as a reference, since I am using LPSPI0 with different pins.

void LPSPI0_init_master (void){      
/*!       * LPSPI0 Clocking:       
* ===================================================       */
     PCC->PCCn[PCC_LPSPI0_INDEX] = 0;                    /* Disable clocks to modify PCS ( default)      */
     PCC->PCCn[PCC_LPSPI0_INDEX] = PCC_PCCn_PR_MASK     /* (default) Peripheral is present.               */
                                  |PCC_PCCn_CGC_MASK     /* Enable PCS=SPLL_DIV2 (40 MHz func'l clock)      */ 
                                  |PCC_PCCn_PCS(6);      

/*!       * LPSPI0 Initialization:      
 * =================================================== 
  */ 
 LPSPI0->CR    = 0x00000000;                  /* IMPORTANT: Disable LPSPI module for configuration       */  
LPSPI0->IER   = 0x00000000;                  /* Interrupts not used                               */  
LPSPI0->DER   = 0x00000000;                  /* DMA not used                                         */  
LPSPI0->CFGR0 = 0x00000000;                  /* Defaults:                                              */             
                                  /* RDM0=0: rec'd data to FIFO as normal           */                   
                            /* CIRFIFO=0; Circular FIFO is disabled           */                     
                          /* HRSEL, HRPOL, HREN=0: Host request disabled */   
LPSPI0->CFGR1 = LPSPI_CFGR1_MASTER_MASK;  /* Configurations: master mode                                             */
                                                       /* PCSCFG=0: PCS[3:2] are enabled                           */    
                                                   /* OUTCFG=0: Output data retains last value when CS negated     */       
                          /* PINCFG=0: SIN is input, SOUT is output                               */                    
/* MATCFG=0: Match disabled                                              */                                                       
/* PCSPOL=0: PCS is active low                                         */                                                       
/* NOSTALL=0: Stall if Tx FIFO empty or Rx FIFO full                */                                                       
/* AUTOPCS=0: does not apply for master mode                          */                                                      
 /* SAMPLE=0: input data sampled on SCK edge                          */                                                       
/* MASTER=1: Master mode                                                   */   
LPSPI0->TCR   = LPSPI_TCR_CPHA_MASK                       |LPSPI_TCR_PRESCALE(2)
                       |LPSPI_TCR_PCS(0)                       |LPSPI_TCR_FRAMESZ(15);   /* Transmit cmd: PCS3, 16 bits, prescale func'l clk by 4, etc     */                           
                            /* CPOL=0: SCK inactive state is low                                    */                                        
               /* CPHA=1: Change data on SCK lead'g, capture on trail'g edge     */                                
                       /* PRESCALE=2: Functional clock divided by 2**2 = 4                */                               
                        /* PCS=0: Transfer using PCS0                                              */                        
                               /* LSBF=0: Data is transfered MSB first                               */                                
                       /* BYSW=0: Byte swap disabled                                              */                            
                           /* CONT, CONTC=0: Continuous transfer disabled                     */                                 
                      /* RXMSK=0: Normal transfer: rx data stored in rx FIFO           */                             
                          /* TXMSK=0: Normal transfer: data loaded from tx FIFO                */                     
                                  /* WIDTH=0: Single bit transfer                                         */                      
                                 /* FRAMESZ=15: # bits in frame = 15+1=16                               */   
LPSPI0->CCR   = LPSPI_CCR_SCKPCS(4)                       |LPSPI_CCR_PCSSCK(4)                       
|LPSPI_CCR_DBT(8)                       |LPSPI_CCR_SCKDIV(8);        /* Clock dividers based on prescaled func'l clk of 100 nsec      */                         
                              /* SCKPCS=4: SCK to PCS delay = 4+1 = 5 (500 nsec)                */                           
                            /* PCSSCK=4: PCS to SCK delay = 9+1 = 10 (1 usec)                     */                           
                            /* DBT=8: Delay between Transfers = 8+2 = 10 (1 usec)                */                             
                          /* SCKDIV=8: SCK divider =8+2 = 10 (1 usec: 1 MHz baud rate)      */   
LPSPI0->FCR   = LPSPI_FCR_TXWATER(3);        /* RXWATER=0: Rx flags set when Rx FIFO >0      */                        
                       /* TXWATER=3: Tx flags set when Tx FIFO <= 3      */   
LPSPI0->CR    = LPSPI_CR_MEN_MASK |LPSPI_CR_DBGEN_MASK;        /* Enable module for operation                */                        
                               /* DBGEN=1: module enabled in debug mode      */                                     
                  /* DOZEN=0: module enabled in Doze mode      */                                                       
/* RST=0: Master logic not reset                */                                                       
/* MEN=1: Module is enabled                     */ 
}

SyntaxEditor Code Snippet
void LPSPI0_PORT_init (void){      {           
/*!            
* Pins definitions            
* ===================================================            
*            
* Pin number        | Function            
* ----------------- |------------------           
 * PTD15             | LPSPI0_SCK            
* PTD16             | LPSPI0_SIN            
* PTB4                | LPSPI0_SOUT            
* PTB5                | LPSPI0_PCS0            
*/      // PCC->PCCn[PCC_PORTB_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTB */       
PORTD->PCR[15]|=PORT_PCR_MUX(4); /* Port D15: MUX = ALT4, LPSPI0_SCK */       
PORTD->PCR[16]|=PORT_PCR_MUX(4); /* Port D16: MUX = ALT4, LPSPI0_SIN */       
PORTB->PCR[4]|=PORT_PCR_MUX(3); /* Port B4: MUX = ALT3, LPSPI0_SOUT */       
PORTB->PCR[5]|=PORT_PCR_MUX(4); /* Port B5: MUX = ALT4, LPSPI0_PCS0 */     
}   
}    // writes 16 bits...     
void LPSPI0_transmit_16bits (uint16_t send)      {        
while((LPSPI0->SR & LPSPI_SR_TDF_MASK)>>LPSPI_SR_TDF_SHIFT==0);         /* Wait for Tx FIFO available      */       
LPSPI0->TDR = send;              /* Transmit data                     */       
LPSPI0->SR |= LPSPI_SR_TDF_MASK; /* Clear TDF flag                     */     }       

uint16_t LPSPI0_receive_16bits (uint8_t spi_read_req)      {       
 uint16_t receive = 0;        // while((LPSPI0->SR & LPSPI_SR_RDF_MASK)>>LPSPI_SR_RDF_SHIFT==0);
                                        /* Wait at least one RxFIFO entry      */      
 while((LPSPI0->SR & LPSPI_SR_TDF_MASK)>>LPSPI_SR_TDF_SHIFT==0); // Need to SEND address to request info to SLAVE, and then CS and CLK activate 
                                             /* Wait for Tx FIFO available      */        
LPSPI0->TDR = (spi_read_req<<8);              /* Transmit data 16 bits                    */       
receive= LPSPI0->RDR;            /* Read received data                     */       
LPSPI0->SR |= LPSPI_SR_RDF_MASK|LPSPI_SR_TDF_MASK; /* Clear RDF flag                          */     //  LPSPI0->SR |= LPSPI_SR_TDF_MASK ; /* Clear TDF flag                     */       
return receive;                  /* Return received data                */     
}  
//uint16 LPSPI0_receive_16bits (void);     

//Write a command to SBC      
//Receives SBC_ADDRESS (7bit, bits 16 through 9 ) and a SBC_data (bits 7 through 0)      
//Then uses 16bit SPI transmit to send SBC_ADDRESS (7bit, bits 16 through 9 ), bit 8 is 0=WRITE, and a SBC_data (bits 7 through 0)

void SBC_write(uint8_t SBC_address, uint8_t SBC_data){
       LPSPI0_transmit_16bits((SBC_address<<9)|SBC_data); // shift 9 places since it is a 7 bit address. Also bit 8 needs to be 0 for write 
}  
uint16_t SBC_read(uint8_t SBC_address){
       LPSPI0_receive_16bits((SBC_address<<1)|0x01); // shift 1 places since it is a 7 bit address. Also  LSB bit  needs to be 1 for read 
}
1 Solution
2,465 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello Juan,

In the LPSPI0_receive_16bits() function, you don’t wait until the receive data are ready, instead, you are sending another byte.
The CPU executes the code faster than the SPI module can manage the transfer. Therefore, you should wait until RDF = 1.

Write the two bytes in the TX FIFO (TX function) and then wait for the data in the RX function.

Regards,

Daniel

View solution in original post

4 Replies
2,466 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello Juan,

In the LPSPI0_receive_16bits() function, you don’t wait until the receive data are ready, instead, you are sending another byte.
The CPU executes the code faster than the SPI module can manage the transfer. Therefore, you should wait until RDF = 1.

Write the two bytes in the TX FIFO (TX function) and then wait for the data in the RX function.

Regards,

Daniel

2,465 Views
christianhdz
Contributor II

Thank your for your response. 

I added a line to wait for RDF. 

uint16_t LPSPI0_receive_16bits (uint8_t spi_read_req)

       {

         volatile static uint32_t receive = 0;

         while((LPSPI0->SR & LPSPI_SR_TDF_MASK)>>LPSPI_SR_TDF_SHIFT==0); // Need to SEND address to request info to SLAVE, and then CS and CLK activate

                                                /* Wait for Tx FIFO available     */

          LPSPI0->TDR = (uint32_t )(spi_read_req<<8);              /* Transmit data 16 bits                          */

         LPSPI0->SR |= LPSPI_SR_TDF_MASK; /* Clear TDF flag                              */

      while((LPSPI0->SR & LPSPI_SR_RDF_MASK)>>LPSPI_SR_RDF_SHIFT==0);

                                                /* Wait at least one RxFIFO entry       */

         receive= LPSPI0->RDR;            /* Read received data                          */

         LPSPI0->SR |= LPSPI_SR_RDF_MASK ; /* Clear RDF flag                      */

         return receive;                  /* Return received data                 */

       }

This seems to be working if I run the debugger whithout doing step by step. Otherwise, debugging step by step, gets stuck in the “while((LPSPI0->SR & LPSPI_SR_RDF_MASK)>>LPSPI_SR_RDF_SHIFT==0)

 

Is this normal/expected behavior?

0 Kudos
2,465 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Please close the EmbSys Registers window, because if you read the FIFO with your debugger, it clear the FIFO and the RDF flag.

Thanks,

BR,

Daniel

2,465 Views
nxf50096
NXP Employee
NXP Employee

Thank your information, Dainel. EmbSys Registers window also took me 2 waste weeks. T_T