emg184
emg184

Reputation: 1010

Changing SPI DATA Size Mid Transaction on STM32G474

I've got an LCD screen that I am using that requires the first spi packet that is sent to be 10 bits long and all subsequent packets to be 8 bits long. So commands are 10 bits and data is bits. Sending data to the device must happen after a command in the same transaction.

I tried a few implementations of this that utilize the HAL but they all appear to cause some strange behavior on the MOSI and CLK lines.

Approach 1: Using the HAL

void set_spi_size_10(SPI_HandleTypeDef *hspi)
{
    HAL_SPI_DeInit(hspi);
    hspi->Init.DataSize = SPI_DATASIZE_10BIT;
    HAL_SPI_Init(hspi);
}

void set_spi_size_8(SPI_HandleTypeDef *hspi)
{
    HAL_SPI_DeInit(hspi);
    hspi->Init.DataSize = SPI_DATASIZE_8BIT;
    HAL_SPI_Init(hspi);
}

void send_data() 
{
    set_spi_size_10(&hspi2);
    HAL_SPI_Transmit(&hspi2, some_buffer, HAL_MAX_DELAY);
    set_spi_size_8(&hspi2);
}

Approach 2: Register Manipulation

void set_spi_size_10(SPI_HandleTypeDef *hspi)
{

    __HAL_SPI_DISABLE(hspi);
    hspi->Init.DataSize = SPI_DATASIZE_10BIT;
    uint32_t frxth = SPI_RXFIFO_THRESHOLD_HF;
    WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) |
                                    (hspi->Init.TIMode & SPI_CR2_FRF) |
                                    (hspi->Init.NSSPMode & SPI_CR2_NSSP) |
                                    (SPI_DATASIZE_10BIT & SPI_CR2_DS_Msk) |
                                    (frxth & SPI_CR2_FRXTH)));
    __HAL_SPI_ENABLE(hspi);
}

void set_spi_size_8(SPI_HandleTypeDef *hspi)
{
    __HAL_SPI_DISABLE(hspi);

    hspi->Init.DataSize = SPI_DATASIZE_8BIT;
    uint32_t frxth = SPI_RXFIFO_THRESHOLD_QF;
    WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) |
                                    (hspi->Init.TIMode & SPI_CR2_FRF) |
                                    (hspi->Init.NSSPMode & SPI_CR2_NSSP) |
                                    (SPI_DATASIZE_8BIT & SPI_CR2_DS_Msk) |
                                    (frxth & SPI_CR2_FRXTH)));
    __HAL_SPI_ENABLE(hspi);
}

When using the functions by themselves they work fine, but when using the functions immediately after one another the transaction doesn't work appropriately.

Using a logic analyzer I can see that the init/deinit times appear to be fairly long and when reiniting it causes an unintended change in the CLK and MOSI lines.

I'd prefer not to bit bang the data out if possible, but that is an alternative. (Looking at the device manufacturers examples this is the approach they took).

https://www.newhavendisplay.com/specs/NHD-0420DZW-AB5.pdf https://github.com/NewhavenDisplay/NHD-0420DZW_Example/blob/main/NHD-0420DZW_Serial/NHD-0420DZW_Serial.ino

Upvotes: 0

Views: 600

Answers (0)

Related Questions