SPI Chip select toggles between bytes

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

SPI Chip select toggles between bytes

Jump to solution
3,483 Views
rogerpease
Contributor III

I am using an MKL24Z32VLH4 device. We are using SPI0 to talk to a bluetooth module. CW 10.6, Processor expert

Despite setting Chip-select toggling to no,

KinetisSPI.png

I am still getting that chip select toggling per each byte (sorry for the sideways picture)

IMG_0516.JPG.jpg

I also noticed there is no hardware buffer for sends/receives (well, it's one byte long) ..... I am using the sample code

  char RecvBlock[] = {0x0,0,0,0,0};

  char SendBlock[] = {0x08,0,0,0,0};

..

..

  while(1) {

        spiBluetoothBlockReceived = 0;

        LDD_TError Error1 = BLUETOOTH_ReceiveBlock(BLUETOOTH_DeviceData,RecvBlock,5);

        LDD_TError Error2 = BLUETOOTH_SendBlock(BLUETOOTH_DeviceData,SendBlock,5);

        while (spiBluetoothBlockReceived == 0);

   }

Do I need to use the DMA? Or is there another setting I am missing?

Thanks,


Roger

Labels (1)
0 Kudos
1 Solution
1,961 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Roger,

I think this is a PE bug, from hardware perspective, the SPI module of KL2x family supports toggling /SS pin automatically during data transfer process when the SPI is set up in master mode. If the SSOE and MSTR bits in SPIx_C1 register are set, the MODFEN bit in SPIx_C1 is set, the /SS pin of the SPI will toggle during the data transfer process(when data is transfering, /SS pin is low, when transfer is idle, /SS pin is high automatically) .

In the following code PE generated, all SSOE/MSTR/MODFEN bits are set no matter you select "Chip select toggling" box is "yes"  or "not", so this is a bug. for correct configuration, if select "yes" for "Chip select toggling" box, the SSOE bit should be set, if select "not", the SSOE bit should be cleared.

BR

XiangJun Rong

LDD_TDeviceData* BLUETOOTH_Init(LDD_TUserData *UserDataPtr)
{
  /* Allocate LDD device structure */
  BLUETOOTH_TDeviceDataPtr DeviceDataPrv;

  /* {Default RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */
  DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC;
  DeviceDataPrv->UserData = UserDataPtr; /* Store the RTOS device structure */
  /* Interrupt vector(s) allocation */
  /* {Default RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */
  INT_SPI0__DEFAULT_RTOS_ISRPARAM = DeviceDataPrv;
  DeviceDataPrv->ErrFlag = 0x00U;      /* Clear error flags */
  /* Clear the receive counters and pointer */
  DeviceDataPrv->InpRecvDataNum = 0x00U; /* Clear the counter of received characters */
  DeviceDataPrv->InpDataNumReq = 0x00U; /* Clear the counter of characters to receive by ReceiveBlock() */
  DeviceDataPrv->InpDataPtr = NULL;    /* Clear the buffer pointer for received characters */
  /* Clear the transmit counters and pointer */
  DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters */
  DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */
  DeviceDataPrv->OutDataPtr = NULL;    /* Clear the buffer pointer for data to be transmitted */
  /* SIM_SCGC4: SPI0=1 */
  SIM_SCGC4 |= SIM_SCGC4_SPI0_MASK;
  /* Interrupt vector(s) priority setting */
  /* NVIC_IPR2: PRI_10=0x80 */
  NVIC_IPR2 = (uint32_t)((NVIC_IPR2 & (uint32_t)~(uint32_t)(
               NVIC_IP_PRI_10(0x7F)
              )) | (uint32_t)(
               NVIC_IP_PRI_10(0x80)
              ));
  /* NVIC_ISER: SETENA|=0x0400 */
  NVIC_ISER |= NVIC_ISER_SETENA(0x0400);
  /* PORTA_PCR16: ISF=0,MUX=5 */
  PORTA_PCR16 = (uint32_t)((PORTA_PCR16 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x02)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x05)
                ));
  /* PORTA_PCR17: ISF=0,MUX=5 */
  PORTA_PCR17 = (uint32_t)((PORTA_PCR17 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x02)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x05)
                ));
  /* PORTA_PCR15: ISF=0,MUX=2 */
  PORTA_PCR15 = (uint32_t)((PORTA_PCR15 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x05)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x02)
                ));
  /* PORTA_PCR14: ISF=0,MUX=2 */
  PORTA_PCR14 = (uint32_t)((PORTA_PCR14 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x05)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x02)
                ));
  /* SPI0_C1: SPIE=0,SPE=0,SPTIE=0,MSTR=1,CPOL=0,CPHA=0,SSOE=1,LSBFE=0 */
  SPI0_C1 = (SPI_C1_MSTR_MASK | SPI_C1_SSOE_MASK); /* Set configuration register */
  /* SPI0_C2: SPMIE=0,??=0,TXDMAE=0,MODFEN=1,BIDIROE=0,RXDMAE=0,SPISWAI=0,SPC0=0 */
  SPI0_C2 = SPI_C2_MODFEN_MASK;        /* Set configuration register */
  /* SPI0_BR: ??=0,SPPR=2,SPR=4 */
  SPI0_BR = (SPI_BR_SPPR(0x02) | SPI_BR_SPR(0x04)); /* Set baud rate register */
  /* SPI0_C1: SPE=1 */
  SPI0_C1 |= SPI_C1_SPE_MASK;          /* Enable SPI module */
  /* Registration of the device structure */
  PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BLUETOOTH_ID,DeviceDataPrv);
  return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the data data structure */
}

View solution in original post

0 Kudos
4 Replies
1,961 Views
carloshass
Contributor II

Hello Roger,

You know if this issue is still not solved by PEX team?

0 Kudos
1,962 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Roger,

I think this is a PE bug, from hardware perspective, the SPI module of KL2x family supports toggling /SS pin automatically during data transfer process when the SPI is set up in master mode. If the SSOE and MSTR bits in SPIx_C1 register are set, the MODFEN bit in SPIx_C1 is set, the /SS pin of the SPI will toggle during the data transfer process(when data is transfering, /SS pin is low, when transfer is idle, /SS pin is high automatically) .

In the following code PE generated, all SSOE/MSTR/MODFEN bits are set no matter you select "Chip select toggling" box is "yes"  or "not", so this is a bug. for correct configuration, if select "yes" for "Chip select toggling" box, the SSOE bit should be set, if select "not", the SSOE bit should be cleared.

BR

XiangJun Rong

LDD_TDeviceData* BLUETOOTH_Init(LDD_TUserData *UserDataPtr)
{
  /* Allocate LDD device structure */
  BLUETOOTH_TDeviceDataPtr DeviceDataPrv;

  /* {Default RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */
  DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC;
  DeviceDataPrv->UserData = UserDataPtr; /* Store the RTOS device structure */
  /* Interrupt vector(s) allocation */
  /* {Default RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */
  INT_SPI0__DEFAULT_RTOS_ISRPARAM = DeviceDataPrv;
  DeviceDataPrv->ErrFlag = 0x00U;      /* Clear error flags */
  /* Clear the receive counters and pointer */
  DeviceDataPrv->InpRecvDataNum = 0x00U; /* Clear the counter of received characters */
  DeviceDataPrv->InpDataNumReq = 0x00U; /* Clear the counter of characters to receive by ReceiveBlock() */
  DeviceDataPrv->InpDataPtr = NULL;    /* Clear the buffer pointer for received characters */
  /* Clear the transmit counters and pointer */
  DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters */
  DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */
  DeviceDataPrv->OutDataPtr = NULL;    /* Clear the buffer pointer for data to be transmitted */
  /* SIM_SCGC4: SPI0=1 */
  SIM_SCGC4 |= SIM_SCGC4_SPI0_MASK;
  /* Interrupt vector(s) priority setting */
  /* NVIC_IPR2: PRI_10=0x80 */
  NVIC_IPR2 = (uint32_t)((NVIC_IPR2 & (uint32_t)~(uint32_t)(
               NVIC_IP_PRI_10(0x7F)
              )) | (uint32_t)(
               NVIC_IP_PRI_10(0x80)
              ));
  /* NVIC_ISER: SETENA|=0x0400 */
  NVIC_ISER |= NVIC_ISER_SETENA(0x0400);
  /* PORTA_PCR16: ISF=0,MUX=5 */
  PORTA_PCR16 = (uint32_t)((PORTA_PCR16 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x02)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x05)
                ));
  /* PORTA_PCR17: ISF=0,MUX=5 */
  PORTA_PCR17 = (uint32_t)((PORTA_PCR17 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x02)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x05)
                ));
  /* PORTA_PCR15: ISF=0,MUX=2 */
  PORTA_PCR15 = (uint32_t)((PORTA_PCR15 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x05)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x02)
                ));
  /* PORTA_PCR14: ISF=0,MUX=2 */
  PORTA_PCR14 = (uint32_t)((PORTA_PCR14 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x05)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x02)
                ));
  /* SPI0_C1: SPIE=0,SPE=0,SPTIE=0,MSTR=1,CPOL=0,CPHA=0,SSOE=1,LSBFE=0 */
  SPI0_C1 = (SPI_C1_MSTR_MASK | SPI_C1_SSOE_MASK); /* Set configuration register */
  /* SPI0_C2: SPMIE=0,??=0,TXDMAE=0,MODFEN=1,BIDIROE=0,RXDMAE=0,SPISWAI=0,SPC0=0 */
  SPI0_C2 = SPI_C2_MODFEN_MASK;        /* Set configuration register */
  /* SPI0_BR: ??=0,SPPR=2,SPR=4 */
  SPI0_BR = (SPI_BR_SPPR(0x02) | SPI_BR_SPR(0x04)); /* Set baud rate register */
  /* SPI0_C1: SPE=1 */
  SPI0_C1 |= SPI_C1_SPE_MASK;          /* Enable SPI module */
  /* Registration of the device structure */
  PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BLUETOOTH_ID,DeviceDataPrv);
  return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the data data structure */
}

0 Kudos
1,961 Views
rogerpease
Contributor III

Thanks for both replies. I ended up making the Chip select into a GPIO and toggling it manually as a workaround.

0 Kudos
1,961 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hi Roger,

1) In L series chip , you can refer to  the Reference manual, there is not the function of "chip select toggling" .

so in the processor expert ,the button is useless, the SS signal change to inactive is done by software , usually on interrupt function  set the SS signal .

2)Yes ,in the L series ,there is no buffer for transmit data , you can refer to your need to select whether use DMA.

Wish it helps you!
If you still have question, please contact me!

Alice

------------------------------------------------------------------------------------------

If this post answers your question, please click the Correct Answer button.

0 Kudos