Hi,
Someone has an SPI code example preferably with interrupt for FRDM-K64F?
It may be a example without interrupt also, already help me a lot because I can't make the SPI work only by reading the reference manual.
Solved! Go to Solution.
I developed a example of Sending/Receiving data:
#define SPI_PUSHR_PCS0_ON 0x10000
#define SPI_PUSHR_PCS1_ON 0x20000
#define SPI_PUSHR_PCS2_ON 0x40000
#define SPI_PUSHR_PCS3_ON 0x80000
#define SPI_PUSHR_PCS4_ON 0x100000
#define SPI_PUSHR_PCS5_ON 0x200000
#define SPI_CTAR_FMSZ_8BIT 0x38000000
#define SPI_CTAR_FMSZ_16BIT 0x78000000
int main(void)
{
unsigned char cmd = 0x01;
unsigned char receiveBuffer[3];
//configure ports
SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK; // Enable PORT clock gating ctrl
SIM_SCGC6 |= SIM_SCGC6_SPI0_MASK;
//PORT D
PORTD_PCR(0) = PORT_PCR_MUX(2); //PCS0
PORTD_PCR(1) = PORT_PCR_MUX(2); //SCK
PORTD_PCR(2) = PORT_PCR_MUX(2); //SOUT
PORTD_PCR(3) = PORT_PCR_MUX(2); //SIN
// Clear all registers
SPI0_SR = (SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK); //clear the status bits (write-1-to-clear)
SPI0_TCR = 0;
SPI0_RSER = 0;
SPI0_PUSHR = 0; //Clear out PUSHR register. Since DSPI is halted, nothing should be transmitted
SPI0_CTAR0 = 0;
// configure registers
SPI0_MCR |= SPI_MCR_MSTR_MASK | SPI_MCR_PCSIS_MASK;
SPI0_MCR &= (~SPI_MCR_DIS_RXF_MASK & ~SPI_MCR_DIS_TXF_MASK); // enable FIFOs
SPI0_MCR &= (~SPI_MCR_MDIS_MASK & ~SPI_MCR_HALT_MASK); //enable SPI and start transfer
SPI0_CTAR0 |= SPI_CTAR_FMSZ_8BIT | SPI_CTAR_CPOL_MASK | SPI_CTAR_CPHA_MASK | SPI_CTAR_BR(6); // 8 bits, 500khz at 120Mhz
// Send Steps:
while(1){
SPI0_MCR |= SPI_MCR_HALT_MASK;
SPI0_MCR |= (SPI_MCR_CLR_RXF_MASK | SPI_MCR_CLR_TXF_MASK); //flush the fifos
SPI0_SR |= (SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK); //clear the status bits (write-1-to-clear)
SPI0_TCR |= SPI_TCR_SPI_TCNT_MASK;
SPI0_MCR &= ~SPI_MCR_HALT_MASK;
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | cmd);
while(!(SPI0_SR & SPI_SR_TCF_MASK));
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xAA);
while(!(SPI0_SR & SPI_SR_TCF_MASK));
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xBB);
while(!(SPI0_SR & SPI_SR_TCF_MASK));
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xCC);
while(!(SPI0_SR & SPI_SR_TCF_MASK));
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xDD);
while(!(SPI0_SR & SPI_SR_TCF_MASK));
SPI0_PUSHR = (SPI_PUSHR_EOQ_MASK | SPI_PUSHR_PCS0_ON | 0xEE); //send last byte
SPI0_SR |= SPI_SR_TFFF_MASK; //clear the status bits (write-1-to-clear)
cmd++;
}
//*****************************************************************************************************************************************
//Receive Steps: (tested with memory MX25L3206E)
while(1){
SPI0_MCR |= SPI_MCR_HALT_MASK;
SPI0_MCR |= (SPI_MCR_CLR_RXF_MASK | SPI_MCR_CLR_TXF_MASK); //flush the fifos
SPI0_SR |= (SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK); //clear the status bits (write-1-to-clear)
SPI0_TCR |= SPI_TCR_SPI_TCNT_MASK;
SPI0_MCR &= ~SPI_MCR_HALT_MASK;
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS_MASK | 0x9F); //command byte
while (!(SPI0_SR & SPI_SR_RFDF_MASK) );
SPI0_POPR; //dummy read
SPI0_SR = SPI_SR_RFDF_MASK; // clear the reception flag (not self-clearing)
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xFF); //dummy byte to read
while (!(SPI0_SR & SPI_SR_RFDF_MASK) );
receiveBuffer[0] = SPI0_POPR; //read
SPI0_SR = SPI_SR_RFDF_MASK; // clear the reception flag (not self-clearing)
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xFF); //dummy byte to read
while (!(SPI0_SR & SPI_SR_RFDF_MASK) );
receiveBuffer[1] = SPI0_POPR; //read
SPI0_SR = SPI_SR_RFDF_MASK; // clear the reception flag (not self-clearing)
SPI0_PUSHR = (SPI_PUSHR_EOQ_MASK | SPI_PUSHR_PCS0_ON | 0xFF); //send last dummy byte to read
while (!(SPI0_SR & SPI_SR_RFDF_MASK) );
receiveBuffer[2] = SPI0_POPR; //read
SPI0_SR = SPI_SR_RFDF_MASK; // clear the reception flag (not self-clearing)
}
return 0;
}
I developed a example of Sending/Receiving data:
#define SPI_PUSHR_PCS0_ON 0x10000
#define SPI_PUSHR_PCS1_ON 0x20000
#define SPI_PUSHR_PCS2_ON 0x40000
#define SPI_PUSHR_PCS3_ON 0x80000
#define SPI_PUSHR_PCS4_ON 0x100000
#define SPI_PUSHR_PCS5_ON 0x200000
#define SPI_CTAR_FMSZ_8BIT 0x38000000
#define SPI_CTAR_FMSZ_16BIT 0x78000000
int main(void)
{
unsigned char cmd = 0x01;
unsigned char receiveBuffer[3];
//configure ports
SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK; // Enable PORT clock gating ctrl
SIM_SCGC6 |= SIM_SCGC6_SPI0_MASK;
//PORT D
PORTD_PCR(0) = PORT_PCR_MUX(2); //PCS0
PORTD_PCR(1) = PORT_PCR_MUX(2); //SCK
PORTD_PCR(2) = PORT_PCR_MUX(2); //SOUT
PORTD_PCR(3) = PORT_PCR_MUX(2); //SIN
// Clear all registers
SPI0_SR = (SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK); //clear the status bits (write-1-to-clear)
SPI0_TCR = 0;
SPI0_RSER = 0;
SPI0_PUSHR = 0; //Clear out PUSHR register. Since DSPI is halted, nothing should be transmitted
SPI0_CTAR0 = 0;
// configure registers
SPI0_MCR |= SPI_MCR_MSTR_MASK | SPI_MCR_PCSIS_MASK;
SPI0_MCR &= (~SPI_MCR_DIS_RXF_MASK & ~SPI_MCR_DIS_TXF_MASK); // enable FIFOs
SPI0_MCR &= (~SPI_MCR_MDIS_MASK & ~SPI_MCR_HALT_MASK); //enable SPI and start transfer
SPI0_CTAR0 |= SPI_CTAR_FMSZ_8BIT | SPI_CTAR_CPOL_MASK | SPI_CTAR_CPHA_MASK | SPI_CTAR_BR(6); // 8 bits, 500khz at 120Mhz
// Send Steps:
while(1){
SPI0_MCR |= SPI_MCR_HALT_MASK;
SPI0_MCR |= (SPI_MCR_CLR_RXF_MASK | SPI_MCR_CLR_TXF_MASK); //flush the fifos
SPI0_SR |= (SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK); //clear the status bits (write-1-to-clear)
SPI0_TCR |= SPI_TCR_SPI_TCNT_MASK;
SPI0_MCR &= ~SPI_MCR_HALT_MASK;
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | cmd);
while(!(SPI0_SR & SPI_SR_TCF_MASK));
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xAA);
while(!(SPI0_SR & SPI_SR_TCF_MASK));
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xBB);
while(!(SPI0_SR & SPI_SR_TCF_MASK));
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xCC);
while(!(SPI0_SR & SPI_SR_TCF_MASK));
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xDD);
while(!(SPI0_SR & SPI_SR_TCF_MASK));
SPI0_PUSHR = (SPI_PUSHR_EOQ_MASK | SPI_PUSHR_PCS0_ON | 0xEE); //send last byte
SPI0_SR |= SPI_SR_TFFF_MASK; //clear the status bits (write-1-to-clear)
cmd++;
}
//*****************************************************************************************************************************************
//Receive Steps: (tested with memory MX25L3206E)
while(1){
SPI0_MCR |= SPI_MCR_HALT_MASK;
SPI0_MCR |= (SPI_MCR_CLR_RXF_MASK | SPI_MCR_CLR_TXF_MASK); //flush the fifos
SPI0_SR |= (SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK); //clear the status bits (write-1-to-clear)
SPI0_TCR |= SPI_TCR_SPI_TCNT_MASK;
SPI0_MCR &= ~SPI_MCR_HALT_MASK;
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS_MASK | 0x9F); //command byte
while (!(SPI0_SR & SPI_SR_RFDF_MASK) );
SPI0_POPR; //dummy read
SPI0_SR = SPI_SR_RFDF_MASK; // clear the reception flag (not self-clearing)
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xFF); //dummy byte to read
while (!(SPI0_SR & SPI_SR_RFDF_MASK) );
receiveBuffer[0] = SPI0_POPR; //read
SPI0_SR = SPI_SR_RFDF_MASK; // clear the reception flag (not self-clearing)
SPI0_PUSHR = (SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS0_ON | 0xFF); //dummy byte to read
while (!(SPI0_SR & SPI_SR_RFDF_MASK) );
receiveBuffer[1] = SPI0_POPR; //read
SPI0_SR = SPI_SR_RFDF_MASK; // clear the reception flag (not self-clearing)
SPI0_PUSHR = (SPI_PUSHR_EOQ_MASK | SPI_PUSHR_PCS0_ON | 0xFF); //send last dummy byte to read
while (!(SPI0_SR & SPI_SR_RFDF_MASK) );
receiveBuffer[2] = SPI0_POPR; //read
SPI0_SR = SPI_SR_RFDF_MASK; // clear the reception flag (not self-clearing)
}
return 0;
}
Hello Rafael,
Are you interested in using the Kinetis SDK? It provides comprehensive software support for Kinetis MCUs. It includes a hardware abstraction layer (HAL) and drivers for each MCU peripheral, USB and connectivity stacks, middleware, real-time operating systems and example applications designed to simplify and accelerate application development on Kinetis MCUs. The Kinetis SDK is complimentary and includes full source code under a permissive open-source license for all hardware abstraction and peripheral driver software. The Kinetis SDK is offered for free, and support for it is provided here.
Of course the SPI driver is supported by KSDK. Examples about its usage are located in the installation path in the folder C:\Freescale\KSDK_1.2.0\examples, you can see the spi_sdcard example in the folder C:\Freescale\KSDK_1.2.0\examples\twrk22f120m\driver_examples\spi_sdcard, this is built for the K22 MCU but due to the portability that offers KSDK, this is exactly the same code for the K64 MCU. Also, you can take a look into the SPI driver examples built to the KL devices.
Also, you can take a look into the document KSDK SPI Master-Slave with FRDM-K64F.
Please let me know if this information is useful or if I can do anything else for you.
Best regards,
Earl Orlando.
/* If this post answers your question please click the Correct Answer button. */
Hello Earl,
I'm not using KSDK libraries purposely.
On really, I need to be able to manipulate the registers, because I'm trying to Develop my own SPI library, with some peculiarities specific to my project.
This is part of configuration for SPI0 in my code:
SPI0_INTERFACE:
SIM_SCGC5 |= MuxConfig[SPI_DeviceList[ID].RoutedPort].mask;// Enable PORT clock gating ctrl
SIM_SCGC6 |= SIM_SCGC6_SPI0_MASK; //Turn on clock to SPI module
PORT_PCR_REG(MuxConfig[SPI_DeviceList[ID].RoutedPort].port, MuxConfig[SPI_DeviceList[ID].RoutedPort].sck_pin) = PORT_PCR_MUX(MuxConfig[SPI_DeviceList[ID].RoutedPort].mux);
PORT_PCR_REG(MuxConfig[SPI_DeviceList[ID].RoutedPort].port, MuxConfig[SPI_DeviceList[ID].RoutedPort].sin_pin) = PORT_PCR_MUX(MuxConfig[SPI_DeviceList[ID].RoutedPort].mux);
PORT_PCR_REG(MuxConfig[SPI_DeviceList[ID].RoutedPort].port, MuxConfig[SPI_DeviceList[ID].RoutedPort].sout_pin) = PORT_PCR_MUX(MuxConfig[SPI_DeviceList[ID].RoutedPort].mux);
PORT_PCR_REG(MuxSCConfig[SPI_DeviceList[ID].ChipSelect].port,MuxSCConfig[SPI_DeviceList[ID].ChipSelect].pcs_pin) = PORT_PCR_MUX(MuxSCConfig[SPI_DeviceList[ID].ChipSelect].mux);
SPI0_MCR |= SPI_MCR_MSTR_MASK | SPI_DeviceList[ID].CSOption;
SPI0_MCR &= ~SPI_MCR_DIS_TXF_MASK; // enable FIFOs
SPI0_CTAR0 |= SPI_CTAR_FMSZ(8) | SPI_DeviceList[ID].CSOption | SPI_DeviceList[ID].Polarity | SPI_DeviceList[ID].Phase | SPI_DeviceList[ID].BaudRate;
NVIC_EnableIRQ(SPI0_IRQn);
I found some examples useful like this SPI Master always sends 16 bits words in non-continuous mode
But nothing significative.
I need an functional example, configurating the port, pin, baud rate, sending and receiving data through SPI to verify my code and find my error.