SPI - Clock line not matching CPOL setting

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPI - Clock line not matching CPOL setting

942 Views
simonwood
Contributor II

Having trouble with SPI setup on an 824. I'm obviously missing something, but can't see what. The issue is that the SCK line is idling high, and I need it idling low. 

My init code is:

{code}

Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
Chip_SWM_MovablePinAssign(SWM_SPI0_MOSI_IO, NRF24L_MOSI_PIN);
Chip_SWM_MovablePinAssign(SWM_SPI0_MISO_IO, NRF24L_MISO_PIN);
Chip_SWM_MovablePinAssign(SWM_SPI0_SCK_IO, NRF24L_SCK_PIN);
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);

// setup SPI support
Chip_SPI_Init(MIRF_SPI);
MIRF_SPI->CFG = (SPI_MODE_MASTER) | SPI_CFG_CPOL_LO | SPI_CFG_CPHA_FIRST;
MIRF_SPI->TXDATCTL = SPI_TXDATCTL_FLEN(7);
MIRF_SPI->TXCTRL = SPI_TXDATCTL_FLEN(7);
MIRF_SPI->DIV = 10; // clk = 24Mhz,
Chip_SPI_Enable(MIRF_SPI);

{code}

and a basic transfer function that looks like this:

{code}

uint8_t spiTransfer(uint8_t nData)
{
while (~MIRF_SPI->STAT & SPI_STAT_TXRDY);

MIRF_SPI->TXDAT = nData;

// Wait for RXRDY
while (~MIRF_SPI->STAT & SPI_STAT_RXRDY);

nData = MIRF_SPI->RXDAT;

return nData;
}

void Nrf24lTransferSync(uint8_t *dataout,uint8_t *datain,uint8_t len)
{
uint8_t i;
for(i = 0;i < len;i++)
{
datain[i] = spiTransfer(dataout[i]);
}
}

{code}

The init code sets CPOL_LO (although this should be the default anyway). Looking on a logic analyser I get this:

SPI capture.png

As you can see, clock is idle high, dropping low just before transmission starts. If I set CPOL_HI then it looks right on the analyser but now the samples are off. If I then set CPHA_SECOND to attempt to use the right edge (although that would then break the rx side) then the clock starts idling hi again (without changing the CPOL value). 

I'm missing something - any pointers gratefully received!

Thanks

Simon

Labels (1)
0 Kudos
2 Replies

851 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Simon,

Regarding your issue, I do not see where you declare the macro SPI_CFG_CPOL_LO. I suggest you check the SPI Configuration register  in debugger after initialization of SPI, especially, check the CPOL and CPHA bits. Anyway, I think that if the CPOL bit in SPI Configuration register  is cleared, the SCK should be low in SPI idle state.

Pls have a check.

BR

XiangJun Rong

pastedImage_1.png

0 Kudos

851 Views
simonwood
Contributor II

Hi Xiangjun,

thanks for the quick response. I'm using lpcopen and the macro comes from there. 

I have now solved the issue. CPOL and CPHA were set correctly, the problem was the SPI bus was entering TX stalled mode and holding clock high. This is caused by not setting the EOT flag on the last byte sent (or not forcing STAT_EOT high in STAT reg after last byte). 

Interestingly :smileyalert: in the LPCOpen samples this is not explicitly done. If you use the basic spi sample (v3.02) and define loopback or rw_test then the function Chip_SPI_RWFrames_Blocking is used which internally does this. However if you use without these defined then function Chip_SPI_WriteFrames_Blocking is used which does NOT set the EOT flag unless you set terminate to true in the SPI_DATA_SETUP struct (which is not done). So I suspect you have the same issue there as well.

 

I also suspect only some SPI slaves are sensitive to this issue (the NRF24L01+ certainly is).

Regards

Simon

0 Kudos