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,
I am still getting that chip select toggling per each byte (sorry for the sideways picture)
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
Solved! Go to Solution.
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 */
}
Hello Roger,
You know if this issue is still not solved by PEX team?
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 */
}
Thanks for both replies. I ended up making the Chip select into a GPIO and toggling it manually as a workaround.
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.