Hello,
I am using the FRDM-K64F development platform, and I have to communicate it with the board ADS1298 ECG FE using the SPI communication. Running the algorithm below, the FRDM-K64F only completes two transfers, but if I run it step by step it completes all the tranfers and in the last transfer the FRDM-K64F should receive 0x06, and it receives the right data; but, the variable 'rx' remains zero.
#include "MK64F12.h"
void config_ports(void){
//Habilitar os clocks dos ports
SIM_SCGC5 |= (1<<12) | (1<<11);
SIM_SCGC6 |= (1<<12);
//config. SPI0_PCS0
PORTD_PCR0 |= (1<<9) | (1<<6) | (1<<1);
PORTD_PCR0 &= ~(1<<5) & ~(1<<4) & ~(1<<2) & ~(1) ;
//config. SPI0_SCK
PORTD_PCR1 |= (1<<9) | (1<<6) | (1<<1);
PORTD_PCR1 &= ~(1<<5) & ~(1<<4) & ~(1<<2) & ~(1);
//config. SPI0_SOUT
PORTD_PCR2 |= (1<<9) | (1<<6) | (1<<1);
PORTD_PCR2 &= ~(1<<5) & ~(1<<4) & ~(1<<2) & ~(1);
//config. SPI0_SIN
PORTD_PCR3 |= (1<<9) | (1<<1);
PORTD_PCR3 &= ~(1<<5) & ~(1<<4) & ~(1);
}
void config_SPI0(void){
//Module Config.
SPI0_MCR |= (1<<31) | (0<<30) | (1<<16) | (1<<11) | (1<<10);
SPI0_MCR &= ~(1) & ~(1<<14);
SPI0_SR |= (1<<28);
//Clock and Transfer Attributes
SPI0_CTAR0 |= (1<<25) | (1<<22) | (1<<17) | (1<<16) | (1<<10) | (1<<9) | (1<<6) | (1<<5) | (1<<2) | (1) ;
SPI0_CTAR0 &= ~(1<<30);
}
void transmit_SPI0(uint8_t tx){
SPI0_MCR |= (1<<11);
SPI0_PUSHR |= (1<<16) |(tx);//CTAR0
}
void transmit2_SPI0(uint8_t tx){
SPI0_MCR |= (1<<11);
SPI0_PUSHR |= (1<<31) | (1<<16) |(tx);
}
void waitSPI(void){
while(SPI0_SR>>31==0){}
}
uint32_t read_REG(uint8_t reg){
uint32_t temp;
reg |= (1<<5);
SPI0_MCR |= (1<<10);
transmit2_SPI0(reg);
waitSPI();
transmit2_SPI0(0x00);
waitSPI();
SPI0_MCR |= (1<<11);
SPI0_PUSHR |= (1<<27) | (1<<16) |(0x00);
waitSPI();
temp = (uint32_t)SPI0_POPR;
return temp;
}
void delay_reset(void){
uint32_t i=610;
while(i>0){
i--;
}
}
int main(void)
{
uint8_t wakeup = 0x02;
uint8_t reset = 0x06;
uint8_t sdatac = 0x11;
uint8_t stop = 0x0A;
uint32_t rx=0;
config_ports();
config_SPI0();
transmit_SPI0(reset);
delay_reset();
transmit_SPI0(wakeup);
transmit_SPI0(sdatac);
transmit_SPI0(stop);
rx = read_REG(0x01);
while(1){
}
/* Never leave main */
return 0;
}
Hi Matheus
SPI0 of the K64 has a 4 word deep fifo and so it should be possible to send 3 bytes even with code that doesn't correctly wait for transmissions to terminate.
It may be that when you start it already has something in the FIFO but generally I think that you are not clearing any status register flags (eg. when one gets set it is generally necessary to write a '1' to it to clear it otherwise it sticks - there are also bits in SPIx_MCR that can be used to flush rx and tx FIFOs to ensure starting with them empty).
Beware also of using a debugger to view registers during operation since it can cause loss of reception when it refreshes the register view and clears the FIFO.
It is further advisable to use defines for the bits in registers otherwise the code is very difficult to read/understand what the intention is (it would require a lot of effort to analyse the code that you have shown to be clear on what it is and isn't doing correctly - and equally difficult to maintain).
Regards
Mark
Kinetis: http://www.uTasker.com/kinetis.html
K64:
- http://www.uTasker.com/kinetis/FRDM-K64F.html
- http://www.uTasker.com/kinetis/TWR-K64F120M.html
- http://www.uTasker.com/kinetis/TEENSY_3.5.html
- http://www.uTasker.com/kinetis/Hexiwear-K64F.html
Hi Macheus,
you can take a reference to the demo in sdk package. They are locate in C:\Users\nxf32199\mcuxpresso\SDKPackages\SDK_2.2_TWR-K64F120M\boards\twrk64f120m\cmsis_driver_examples\dspi and SDK_2.2_TWR-K64F120M\boards\twrk64f120m\driver_examples\dspi. If you use the demo and driver, I tnink your work can be much easier.
Regards
Jing
Hi Jing,
I am not using mcuxpresso, i am using Kinetis Design Studio.
Regards
Matheus