AnsweredAssumed Answered

SPI Master always sends 16 bits words in non-continuous mode

Question asked by Trevor Hey on Apr 2, 2015
Latest reply on Apr 3, 2015 by Kerry Zhou

Hi,

 

Anyone come across such a problem?  I am not using the KSDK libraries, but used them to model my own driver to trim down the code size.

 

I set up SPI master mode on SPI1. The code below is to show the settings. I am interfacing to a SPANSION SPI memory device, really simple and basic SPI device.

 

The problem comes in with the setting of the CONT_SCKE bit in MCR.

 

If I clear this bit (not continuous mode) , the SPI master clocks out 16 bits for each transfer written to PUSHR, if I set it, it clocks out 8 bits?  That should not happen.

All other settings are kept the same for this test, I change only this one bit and see this behaviour.  I use CTAR  0 in all cases.

 

Why does the SPI module clock out 8 or a6 bits when I change this one setting? Of course I dont want continuous mode.

 

Thanks for any help

 

 

Device = MK24F25612

 

My SPi init:  Info: SPI1_CTAR_USR = 0

 

SPI1->MCR |= SPI_MCR_MSTR_MASK;  // Master Mode

//SPI1->MCR |= SPI_MCR_CONT_SCKE_MASK; // clock runs continuosly

SPI1->MCR &= ~SPI_MCR_CONT_SCKE_MASK; // clock doesnt run continuosly

SPI1->MCR |=  1 << SPI_MCR_PCSIS_SHIFT ; // Active low CS

SPI1->MCR &= ~SPI_MCR_DIS_RXF_MASK;

SPI1->MCR &= ~SPI_MCR_DIS_TXF_MASK; // enable FIFOs

// CS pre-delay  ---- must be > 3 ns, SPANSION clock is 9ns min so do at least 1 clock delay is sufficient but Ill do 8

SPI1->CTAR[SPI1_CTAR_USR] &= ~SPI_CTAR_PCSSCK_MASK;

SPI1->CTAR[SPI1_CTAR_USR] |= SPI_CTAR_PCSSCK(1);

SPI1->CTAR[SPI1_CTAR_USR] &= ~SPI_CTAR_CSSCK_MASK;

SPI1->CTAR[SPI1_CTAR_USR] |= SPI_CTAR_CSSCK(8); 

// min CS high time  50ns for SPANSION so at 9ns clock we need @ least 6 clocks, choose 16

SPI1->CTAR[SPI1_CTAR_USR] &= ~SPI_CTAR_PASC_MASK;

SPI1->CTAR[SPI1_CTAR_USR] |= SPI_CTAR_PASC(1); 

SPI1->CTAR[SPI1_CTAR_USR] &= ~SPI_CTAR_ASC_MASK;

SPI1->CTAR[SPI1_CTAR_USR] |= SPI_CTAR_ASC(16);

//baud rate SCK baud rate = (fP/PBR) x [(1+DBR)/BR]

retBaudrate = CalcSPIBaudRate( port,  baudrate, clock);

 

SPI1->CTAR[SPI1_CTAR_USR] &= ~SPI_CTAR_FMSZ_MASK; // bits per frame = bits-1

SPI1->CTAR[SPI1_CTAR_USR] |= SPI_CTAR_FMSZ(7); //

SPI1->CTAR[SPI1_CTAR_USR] &= ~SPI_CTAR_CPOL_MASK; // Using Mode 0 - CLK inactive state is low CPOL = 0

  SPI1->CTAR[SPI1_CTAR_USR] &= ~SPI_CTAR_CPHA_MASK; // Using Mode 0 - CData is captured on the leading edge of SCK and changed on the following edge CPHA = 0

 

// SPI1->CTAR[SPI1_CTAR_USR] &= ~SPI_CTAR_CPOL_MASK; // Using Mode 0 - CLK inactive state is low CPOL = 0

//SPI1->CTAR[SPI1_CTAR_USR] |= SPI_CTAR_CPHA_MASK; // Using Mode 0 - CData is captured on the leading edge of SCK and changed on the following edge CPHA = 0

 

SPI1->CTAR[SPI1_CTAR_USR] &= ~SPI_CTAR_LSBFE_MASK; // bit direction -SPANSION neebs msb first

NVIC_EnableIRQ(SPI1_IRQn);

// Last thing - start it up

SPI1->MCR &= ~SPI_MCR_MDIS_MASK;  // Zero enables SPI

 

How I loaf the TX fifo:

 

void fs_SPI_WriteDataMastermode(SPI_Type * port,  dspi_command_config_t * command,   uint16_t data) {

    uint32_t temp = 0;

 

 

    /* First, build up the 32-bit word then write it to the PUSHR */

if(command->isChipSelectContinuous) temp |= SPI_PUSHR_CONT_MASK;

temp |= SPI_PUSHR_CTAS(command->whichCtar);

temp |= SPI_PUSHR_PCS(command->whichPcs);

if (command->isEndOfQueue) temp |=  SPI_PUSHR_EOQ_MASK;

if (command->clearTransferCount) temp  |= SPI_PUSHR_CTCNT_MASK;

temp |= SPI_PUSHR_TXDATA(data);

 

SPI_PUSHR_REG(port) = temp;

 

}

Outcomes