The SSD1803 is a controller which is used to control an LCD-Display. I'm using SPI to communicate with the controller, which works fine for normal instructions: I can print text onto the display, clearing the display, storing my custom characters in the RAM, setting the cursor, etc.
But now I want to read the Busy Flag (BF
), which isn't working properly-> The byte which contains the BF
always returns 0
.
Command Table
Instruction | RE | RS | R/W | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 | Execution Time |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Clear Display | X | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1.53ms |
Ready busy flag and address/part ID | X | 0 | 1 | BF | AC6/ID6 | AC5/ID5 | AC4/ID4 | AC3/ID3 | AC2/ID2 | AC1/ID1 | AC0/ID0 | 0us |
BF = 1
: busy state
BF = 0
: ready state
SSD1803 Datasheet p. 29
Timing Diagram
SSD1803 Datasheet p. 27
IOC Config File
The clock frequency is 312.5kHz
which is in the external clock range of the controller:
SSD1803 Datasheet p. 57
Code
int LCDInstrHandler(void)
{
// Clear Display
• HAL_GPIO_WritePin(SPI_LCD_NSS_GPIO_Port, SPI_LCD_NSS_Pin, GPIO_PIN_RESET);
uint8_t tDataClear[3] = {0b11111000, 0b10000000, 0b00000000};
HAL_StatusTypeDef tClearState = HAL_SPI_Transmit(&SPI_LCD, tDataClear, 3, 1000);
HAL_GPIO_WritePin(SPI_LCD_NSS_GPIO_Port, SPI_LCD_NSS_Pin, GPIO_PIN_SET);
// Read Busy Flag
uint8_t tDataBF[2] = {0b11111100, 0x00};
uint8_t tRecBuf[2];
HAL_GPIO_WritePin(SPI_LCD_NSS_GPIO_Port, SPI_LCD_NSS_Pin, GPIO_PIN_RESET);
HAL_StatusTypeDef tBFState = HAL_SPI_TransmitReceive(&SPI_LCD, tDataBF, tRecBuf, 2, 1000);
HAL_GPIO_WritePin(SPI_LCD_NSS_GPIO_Port, SPI_LCD_NSS_Pin, GPIO_PIN_SET);
• return 0;
}
•
= Breakpoint
By default, there's a text on the display, which gets printed after the initialization. After that the function LCDInstrHandler
gets called.
As you can see in the IOC Config file, I set the First Bit to MSB First
. Means the left bit is sent first and when I receive a byte, the left bit is the first bit the slave sent.
To test if the busy flag works, I send the clear display instruction, which takes 1.53ms. This works: My display is cleared. After that, I send the start byte with RS = 0
and R/W = 1
, which tells the SSD1803 controller to return me a byte containing the BF
in DB7
(see Command Table).
The time between the first breakpoint and the second breakpoint is 150us (measured with oscilloscope). Means that the BF
instruction gets executed in time, so that the BF
should be 1
since the SSD1803 controller is still executing the clear display instruction.
What I get:
tRecBuf
:{0, 0}
tClearState
,tBFState
:HAL_OK
What I expect
tRecBuf
:{0, 0bxxxxxxx1}
1
:BF
(DB7
) as LSBxxxxxxx
:AC0-AC6