Hi all,
I have a problem with the Kinetis SPI module
MCU: K10DX32
software: CodeWarrior Development Studio 10.6
programmer: PE micro multilink universal
The SPI module is configurated as slave. When data is coming in at SIN an interrupt is generated where the data are saved in a buffer. This is working.
From other MCUs and applications I'm used that the incoming data are automatically shifted out to SOUT when the next data is coming. But here the value at SOUT is always zero.
Then I tried to set the value of the shift register manually by writing the desired value into SPI0_PUSHR_SLAVE. This results in the following behaviour:
- data received, SPI0_PUSHR_SLAVE set with value1, 0 is shifted out => ok
- data received, SPI0_PUSHR_SLAVE set with value2, value1 is shifted out => ok
- data received, SPI0_PUSHR_SLAVE set with value3, value1 is shifted out => not ok
- now always value1 is shiftet out
It seems that writing to SPI0_PUSHR_SLAVE works exactly one time. Enabling or disabling the FIFO shows the same behaviour.
I analysed a lot of flags and registers to understand what happens, but without success.
my configuration:
interrupt code:
/*
** ===================================================================
** Interrupt handler : SPI
**
** Description :
** User interrupt service routine.
** Parameters : None
** Returns : Nothing
** ===================================================================
*/
PE_ISR(SPI)
{
/* Write your interrupt code here ... */
// save the input data
spidata = SPI0_POPR;
// set the FIFO register with some value that should appear at the output next time
SPI0_PUSHR_SLAVE = value;
// clear the Receive FIFO Drain Flag
SPI0_SR |= SPI_SR_RFDF_MASK;
}
regards,
Jörg
已解决! 转到解答。
Hi,
finally I found the reason for my problem.
I have a constellation with exactly one master and exactly one slave, so the SS line can be kept low all the time (tied to ground). So I thought, because it's working with other MCUs that I programmed.
But the Kinetis seems to dislike when the SS line is already low during initialization. Interestingly the Rx is working as normal, only the Tx part is annoying.
The solution is to use the regular SS connection from the master or as a workaround to connect SS of the slave to a GPIO that is high on reset or power up and goes low after initialization.
regards,
Jörg
Hi,
finally I found the reason for my problem.
I have a constellation with exactly one master and exactly one slave, so the SS line can be kept low all the time (tied to ground). So I thought, because it's working with other MCUs that I programmed.
But the Kinetis seems to dislike when the SS line is already low during initialization. Interestingly the Rx is working as normal, only the Tx part is annoying.
The solution is to use the regular SS connection from the master or as a workaround to connect SS of the slave to a GPIO that is high on reset or power up and goes low after initialization.
regards,
Jörg
Hi Adrian,
sorry for my late reply. I was busy with some urgent stuff.
"value" is set in the interrupt routine.
It can be a constant like in the following example:
PE_ISR(SPI)
{
/* Write your interrupt code here ... */
// save the input data
spidata = SPI0_POPR;
// set the FIFO register with some value that should appear at the output next time
if (cnt==0) {
SPI0_PUSHR_SLAVE = 0xAA;
cnt++;
} else {
SPI0_PUSHR_SLAVE = 0xBB;
cnt = 0;
}
// clear the Receive FIFO Drain Flag
SPI0_SR |= SPI_SR_RFDF_MASK;
}
The output should toggle between AA and BB, but it's always AA.
It can be set by a variable (global or not) like in the following example:
PE_ISR(SPI)
{
/* Write your interrupt code here ... */
// save the input data
spidata = SPI0_POPR;
// set the FIFO register with some value that should appear at the output next time
if (cnt==0) {
SPI0_PUSHR_SLAVE = cnt ;
cnt++;
} else {
SPI0_PUSHR_SLAVE = cnt ;
cnt = 0;
}
// clear the Receive FIFO Drain Flag
SPI0_SR |= SPI_SR_RFDF_MASK;
}
The output should toggle between 0 and 1, but it's always 0.
It seems that the output is always the value that was used when setting SPI0_PUSHR_SLAVE the first time.
regards
Jörg
Hi,
I apologize for the late response. I have some suggestions to do in order to test the behavior of the SPI module.
Debug the code an set a breakpoint inside the else statement to ensure that the instruction is being executed an check the values written to the SPI0_PUSHR_SLAVE register when the instruction is executed, if you are not using FIFO then you have a one entry FIFO, please check the value stored there to see if the value is being stored or not.
Also it is possible that the FIFO is ignoring the writes to it because is full, you can check the TFFF flag just before trying to write to the PUSH register to ensure a empty FIFO (a full FIFO ignores any attempt to write to it).
Hope this information can help you.
Best Regards,
Adrian Sanchez Cano
Technical Support Engineer
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Adrian,
I debugged the code as you proposed.
The interrupt routine is as follows:
PE_ISR(SPI)
{
/* Write your interrupt code here ... */
// save the input data
spidata = SPI0_POPR;
// set the FIFO register with some value that should appear at the output next time
if (cnt==0) {
SPI0_PUSHR_SLAVE = 0xAA;
cnt = 1;
} else {
SPI0_PUSHR_SLAVE = 0xBB;
cnt = 0;
}
// clear the Receive FIFO Drain Flag
SPI0_SR |= SPI_SR_RFDF_MASK;
}
FIFO is disabled.
The master sends four bytes, so the interrupt is triggered four times.
The receiving of the incoming data works fine, but the flags and registers for the transmitter functions are not as expected.
I also experimented with setting/resetting of several flags at several points, all without any influence on the behaviour.
Maybe the initialisation is wrong? This is done with the Processor Expert.
best regards
Jörg