Reputation: 1010
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