Hello,
I use TWR-K60F120M as my firmware development platform. I have implemented SPI interface on SPI2. The receiver is in polling mode. It is working fine. I would like to change it to interrupt mode. When I set break point with CW debugger inside of interrupt service routine, it doesn't stop there. I do enable SPI2 receiver interrupt bit in register SPI2_RSER and select interrupt (not DMA) generate interrupt. I can't think of what I have missed. But the behavior does look like that either SPI2 receiver interrupt not generated or I have not installed spi2_isr properly. I use oscillate scope to monitor MISO and MOSI as well as SPI2_CLK and SPI2_CS. It looks like that it stop after the first word is transferred/received. I attached my source code here. Please take a look what I have missed or what I have done improperly. Thanks!
Lisa
uint_16 recv_buf[8];// this global variable is for SPI2 receiver which allows both spi2_isr and spi2_task access
void spi2_recv_isr(void)
{
uint_8 recv_index = 0;
pointer event_ptr;
recv_buf[recv_index] = (uint_16)(SPI2_RXFR0 & 0xffff);
SPI2_SR |= SPI_SR_RFDF_MASK | SPI_SR_RFOF_MASK ;
if(recv_index == 7)
{
recv_index = 0;
if(_event_open("global", &event_ptr) != MQX_OK)
{
_mqx_exit(0);
}
if(_event_set(event_ptr, RMSSC_EVENT_SPI2_RECV_DATA) != MQX_OK)
{
_mqx_exit(0);
}
}
else
{
recv_index++;
}
}
void spi_task(uint_32 initial_data)
{
MQX_FILE_PTR spi2_dev = NULL;
uint_32 cnt2 = 0, param;
uint_16 send_buf[] = {0x1234, 0x5678, 0x9abc, 0xdef0, 0xaa55, 0xa55a, 0xcc33, 0x6699};
uint_8 send_index = 0;
pointer event_ptr;
printf("\nPrint from spi_task. \n");
fflush(stdout);
// setup event
if(_event_create("global") != MQX_OK)
{
printf("Create event failed!\n");
fflush(stdout);
_mqx_exit(0);
}
if(_event_open("global", &event_ptr) != MQX_OK)
{
printf("Open event failed!\n");
fflush(stdout);
_mqx_exit(0);
}
// install spi2 isr
_int_install_isr(INT_SPI2, (void (_CODE_PTR_)(pointer))spi2_recv_isr, NULL);
// open SPI2 channel with full duplex mode
spi2_dev = fopen("ispi2:", (pointer)SPI_FLAG_FULL_DUPLEX);
if(spi2_dev == NULL)
{
printf("Open spi2 fails. \n");
fflush(stdout);
_mqx_exit(0);
}
SIM_SCGC3 |= SIM_SCGC3_DSPI2_MASK; //enable SPI2 component
PORTD_PCR11 |= PORT_PCR_MUX(1 << 1) | PORT_PCR_DSE_MASK; //enable SPI2_CS0 pin
PORTD_PCR12 |= PORT_PCR_MUX(1 << 1) | PORT_PCR_DSE_MASK; //enable SPI2_CLK pin
PORTD_PCR13 |= PORT_PCR_MUX(1 << 1) | PORT_PCR_DSE_MASK; //enable SPI2_MOSI pin
PORTD_PCR14 |= PORT_PCR_MUX(1 << 1); //enable SPI2_MISO pin
PORTD_PCR15 |= PORT_PCR_MUX(1 << 1) | PORT_PCR_DSE_MASK; //enable SPI2_CS1 pin
//SPI2_CTARx = 0x7D000000
// | SPI_CTAR_LSBFE_MASK
SPI2_CTAR0 |= SPI_CTAR_FMSZ(15 << 0) | SPI_CTAR_CPHA_MASK; //set frame size as 8-bit and least significant bit first
SPI2_CTAR1 |= SPI_CTAR_FMSZ(15 << 0) | SPI_CTAR_CPHA_MASK; //set frame size as 8-bit and least significant bit first
//SPI2_MCR = 0x833f0C00
// | SPI_MCR_ROOE_MASK
SPI2_MCR |= SPI_MCR_MSTR_MASK | SPI_MCR_CONT_SCKE_MASK | SPI_MCR_FRZ_MASK
| SPI_MCR_PCSSE_MASK |SPI_MCR_PCSIS_MASK| SPI_MCR_CLR_TXF_MASK
| SPI_MCR_CLR_RXF_MASK;
SPI2_MCR &= ~SPI_MCR_MDIS_MASK; //enable DSPI clocks
SPI2_MCR &= ~SPI_MCR_DIS_TXF_MASK; //enable TX FIFO
SPI2_MCR &= ~SPI_MCR_DIS_RXF_MASK; //enable TX FIFO
SPI2_RSER |= SPI_RSER_EOQF_RE_MASK | SPI_RSER_RFOF_RE_MASK;
SPI2_RSER &= ~SPI_RSER_RFDF_DIRS_MASK;
SPI2_SR |= SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK
| SPI_SR_RFDF_MASK;
// set SPI2 baud rate
param = 5000; //5000000;
if(SPI_OK != ioctl(spi2_dev, IO_IOCTL_SPI_SET_BAUD, ¶m))
{
printf("Set SPI2 baud rate error!\n");
fflush(stdout);
}
printf("SPI2_MCR = 0x%x SPI2_TCR = 0x%x\n", SPI2_MCR, SPI2_TCR);
printf("SPI2_CTAR0 = 0x%x SPI2_CTAR1 = 0x%x\n", SPI2_CTAR0, SPI2_CTAR1);
printf("SPI2_SR = 0x%x SPI2_RSER = 0x%x\n", SPI2_SR, SPI2_RSER);
printf("SPI2_PUSHR = 0x%x SPI2_POPR = 0x%x\n", SPI2_PUSHR, SPI2_POPR);
printf("SIM_SCGC3 = 0x%x PORTD_PCR11 = 0x%x\n", SIM_SCGC3, PORTD_PCR11);
printf("PORTD_PCR12 = 0x%x PORTD_PCR13 = 0x%x\n", PORTD_PCR12, PORTD_PCR13);
printf("PORTD_PCR14 = 0x%x PORTD_PCR15 = 0x%x\n", PORTD_PCR14, PORTD_PCR15);
while(1)
{
// send data
// SPI_PUSHR_CONT_MASK |
SPI2_PUSHR = SPI_PUSHR_CTCNT_MASK | SPI_PUSHR_PCS(1<<0) | send_buf[send_index];
while (!(SPI2_SR & SPI_SR_TCF_MASK))
{
} // wait for byte to be sent and a byte to be read in
SPI2_SR |= SPI_SR_TCF_MASK; // clear the reception flag (not self-clearing)
if(send_index == 7)
{
printf("send_buf[0] = 0x%x send_buf[7] = 0x%x\n", send_buf[0], send_buf[7]);
fflush(stdout);
send_index = 0;
}
else
send_index++;
// receive data
if(_event_wait_all(event_ptr, RMSSC_EVENT_SPI2_RECV_DATA, 0) == MQX_OK)
{
printf("recv_buf[0] = 0x%x recv_buf[7] = 0x%x\n", recv_buf[0], recv_buf[7]);
fflush(stdout);
memset(recv_buf, 0, 8);
}
else
{
printf("Event wait failed!\n");
fflush(stdout);
_mqx_exit(0);
}
if(_event_clear(event_ptr, RMSSC_EVENT_SPI2_RECV_DATA) != MQX_OK)
{
printf("Event clear failed!\n");
fflush(stdout);
_mqx_exit(0);
}
}
fflush(stdout);
_task_block();
}
This is a timely post on SPI interrupts and I got some help from your code, thanks.
The one thing I did to get RXFIFO data in my SPI isr is to use the POPR register instead of the RXFR0 register like you did.
Your line of code -> recv_buf[recv_index] = (uint_16)(SPI2_RXFR0 & 0xffff);
You could try -> recv_buf[recv_index] = (uint_16)(SPI2_POPR & 0xffff);
I hope this helps,
Cheers,
Tom
Hi Tom,
Thank you for your suggestion! I have just seen your reply today.
I had changed my spi2_isr function before I saw your reply. I realized that I should use SPI2_POPR, instead of SPI2_RXFR0. I still can't see spi2_isr is called.
Do you mind to share your code here?
Lisa
I forgot to mention in above post that I have defined BSPCFG_ENABLE_ISPI2 in user_config.h and twrk60f120m.h. I have rebuilt bsp and psp.
Lisa