AnsweredAssumed Answered

Explain the SPI peripheral's MSTIDLE flag for LPC84x

Question asked by michael boyko on Jun 7, 2018
Latest reply on Jun 13, 2018 by michael boyko

I am writing a SPI driver for the LPC84x line of micros. I may have a misunderstanding of the how the peripheral works in one aspect and need some clarification. First the SPI function in question:

 

static void LCD_Madctl(unsigned value)
{
    // wait for any previous commands to finish - this WORKS!
    while ((LPC_SPI1->STAT & STAT_MSTIDLE) == 0);

    // set command/data gpio to command
    LCD_SetCommand();

    // send the MADCTL command byte
    LPC_SPI1->TXDATCTL = TXCTL_TXSSEL0 | TXCTL_TXSSEL1_N | TXCTL_TXSSEL2_N
            | TXCTL_TXSSEL3_N | TXCTL_RXIGNORE| TXCTL_LEN8 | SITRONIX_CMD_MADCTL;

    // wait for command byte to finish transferring - this HANGS!
    while ((LPC_SPI1->STAT & STAT_MSTIDLE) == 0);

    // set command/data gpio to data
    LCD_SetData();

    // send the data byte
    LPC_SPI1->TXDATCTL = TXCTL_TXSSEL0 | TXCTL_TXSSEL1_N | TXCTL_TXSSEL2_N
            | TXCTL_TXSSEL3_N | TXCTL_EOT | TXCTL_RXIGNORE | TXCTL_LEN8
            | (value & 0xff);
}

 

This code is trying to do the following sequence:

  1. wait for any previous commands to finish
  2. set gpio for command
  3. transmit a command byte
  4. wait for the command byte to finish
  5. set gpio for data
  6. send the data byte

However, after sending the command byte the code waiting for the MSTIDLE flag (step 4) hangs.

 

The documentation for this bit reads as follows:

MSTIDLE - Master idle status flag. This bit is 1 whenever the SPI master function is fully
idle. This means that the transmit holding register is empty and the transmitter
is not in the process of sending data.

So, is my code working as one would expect? I think not - someone please correct if I'm missing something.

 

From test code MSTIDLE  seems to only get set after chip select is released. Is this correct? It would seem one of two things is incorrect: Either the documentation should mention the chip select must be released prior to this bit being set or maybe there a bug in the silicon of the LPC84x?!?

 

As a work around I was able to not ignore the rx of the command byte and trigger off the RXRDY flag to know when its safe to change the command/data line.

 

SIDE NOTE: It doesn't seem likely that chip select should be part of MSTIDLE. its not mentioned in the documentation 2. why mention transmit holding register and transmitter being idle since these obviously has to happen prior to releasing the chip select. 3. There is already a SSD flag that would seem to provide that functionality (except it has to be cleared in software).

Outcomes