I am developing an application in MCUXpresso for the LPC54102 processor. I am using the SDK and the configuration tools to setup SPI.
The processor has to communicate with display (four wire SPI) connected to SPI1. Additionally, there is a slave select (0), and a D/C# pin on the display. The D/C# is used to denote data or commands. Low for commands and high for data. This pin is checked by the display on the 8th bit of data in each byte transmitted.
The problem I've having is that when I call SPI_MasterTransferBlocking(), I see all the data, but the function returns before the last few bits are transmitted to the display. As I set the D/C# pin (to get ready for data) high after the function returns, the display sees it go high and the last command is interpreted as data instead of a command.
Is there any way to know that all data has been transmitted? I have tried checking the the END TRANSFER and MSTIDLE bits in the SPI->STAT register. From the description, it would seem that the MSTIDLE bit is what I want, but it appears to not be set when the SPI_MasterTransferBlocking() function returns.
I have also tried adjusting the SPI delays, but no luck there either.
I can fake it by adding a loop (counting to 100 seems to do it), but that's kind of a hack as far as I'm concerned - it makes me think I'm missing something.
How is this typically done with this processor?
Here's the SPI configuration:
const spi_master_config_t SPI1_config = {
.polarity = kSPI_ClockPolarityActiveHigh,
.phase = kSPI_ClockPhaseFirstEdge,
.direction = kSPI_MsbFirst,
.baudRate_Bps = 2000000UL,
.dataWidth = kSPI_Data8Bits,
.sselNum = kSPI_Ssel0,
.sselPol = kSPI_SpolActiveAllLow,
.enableLoopback = false,
.enableMaster = true,
.fifoConfig = {
.enableTxFifo = false,
.txFifoSize = 1U,
.txFifoThreshold = 0U,
.enableRxFifo = false,
.rxFifoSize = 0U,
.rxFifoThreshold = 0U
},
.delayConfig = {
.preDelay = 0U,
.postDelay = 0U,
.frameDelay = 0U,
.transferDelay = 0U
}
};
spi_master_handle_t SPI1_handle;
static void SPI1_init(void) {
/* Initialization function */
SPI_MasterInit(SPI1_PERIPHERAL, &SPI1_config, SPI1_CLOCK_SOURCE);
/* Interrupt vector SPI1_IRQn priority settings in the NVIC. */
NVIC_SetPriority(SPI1_IRQN, SPI1_IRQ_PRIORITY);
SPI_MasterTransferCreateHandle(SPI1_PERIPHERAL, &SPI1_handle, display_hardware_master_transfer_callback, NULL);
}
I use the callback for non-blocking calls so it is not called here.
Another issue is that the slave select pin does not appear to be toggling at all. It is constantly low.
Here's the generated configuration for that pin:
IOCON->PIO[1][5] = ((IOCON->PIO[1][5] &
/* Mask bits to zero which are setting */
(~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK)))
/* Selects pin function.
* : PORT15 (pin 19) is configured as SPI1_SSEL0. */
| IOCON_PIO_FUNC(PIO15_FUNC_ALT2)
/* Selects function mode (on-chip pull-up/pull-down resistor control).
* : Inactive.
* Inactive (no pull-down/pull-up resistor enabled). */
| IOCON_PIO_MODE(PIO15_MODE_INACTIVE)
/* Select Analog/Digital mode.
* : Digital mode. */
| IOCON_PIO_DIGIMODE(PIO15_DIGIMODE_DIGITAL));
I don't see any issue with the pin configuration.
I have checked continuity from the processor to the display (custom hardware) and it is connected.
Unfortunately I can't post code.
Thanks.
Solved! Go to Solution.
This turned out to be a bad processor. After a while, the clock signal from the SPI1 module had a 1 volt DC offset. I got a new board and everything works.
This turned out to be a bad processor. After a while, the clock signal from the SPI1 module had a 1 volt DC offset. I got a new board and everything works.