Fixed issue with external DAC handlign from repair process
repair process implemented. Simple regulation without feedback (must be addeed, yet) HW validation menu functional but buggy (IOs not OK) Added ClearLine functionality to displayDevice git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@244 05563f52-14a8-4384-a975-3d1654cca0fa
This commit is contained in:
@@ -66,47 +66,57 @@ ErrorStatus Display_construct(struct Display* self, struct DisplayDevice* displa
|
||||
{
|
||||
ErrorStatus returnValue = SUCCESS;
|
||||
|
||||
if (!self->initialized)
|
||||
{
|
||||
|
||||
self->displayDevice = displayDevice;
|
||||
self->TaskPriority = TaskPriority;
|
||||
self->stackSize = stackSize;
|
||||
self->maxCharactersPerTransmit = maxCharactersPerTransmit;
|
||||
self->refreshFeedCounter = 0;
|
||||
self->refreshFeedFrequency_ms = refreshFeedFrequency_ms;
|
||||
self->refreshPeriod_ms = refreshPeriod;
|
||||
self->displayDevice = displayDevice;
|
||||
self->TaskPriority = TaskPriority;
|
||||
self->stackSize = stackSize;
|
||||
self->maxCharactersPerTransmit = maxCharactersPerTransmit;
|
||||
self->refreshFeedCounter = 0;
|
||||
self->refreshFeedFrequency_ms = refreshFeedFrequency_ms;
|
||||
self->refreshPeriod_ms = refreshPeriod;
|
||||
|
||||
|
||||
if(returnValue == SUCCESS)
|
||||
{
|
||||
// Create a semaphore to sync access to the display shadow
|
||||
vSemaphoreCreateBinary(self->displayShadowAccessSemaphore);
|
||||
xSemaphoreGive(self->displayShadowAccessSemaphore);
|
||||
|
||||
// Clear the display shadow
|
||||
size_t rowCounter;
|
||||
size_t colCounter;
|
||||
for (rowCounter = 0; rowCounter < self->displayDevice->parameters.numberOfRows; rowCounter++)
|
||||
if(returnValue == SUCCESS)
|
||||
{
|
||||
for (colCounter = 0; colCounter < self->displayDevice->parameters.numberOfColumns; colCounter++)
|
||||
// Create a semaphore to sync access to the display shadow
|
||||
vSemaphoreCreateBinary(self->displayShadowAccessSemaphore);
|
||||
// Create a semaphore to sync writing requests to the display
|
||||
vSemaphoreCreateBinary(self->displayWriteRequest);
|
||||
|
||||
|
||||
// Clear the display shadow
|
||||
size_t rowCounter;
|
||||
size_t colCounter;
|
||||
for (rowCounter = 0; rowCounter < self->displayDevice->parameters.numberOfRows; rowCounter++)
|
||||
{
|
||||
Display_characterUpdate(&self->displayShadow[rowCounter][colCounter], 0x20);
|
||||
for (colCounter = 0; colCounter < self->displayDevice->parameters.numberOfColumns; colCounter++)
|
||||
{
|
||||
Display_characterUpdate(&self->displayShadow[rowCounter][colCounter], 0x20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self->runTask = true;
|
||||
|
||||
if(returnValue == SUCCESS)
|
||||
{
|
||||
if (xTaskCreate(DisplayTask, (const char*)"DisplayTask", self->stackSize, self, self->TaskPriority, &self->taskHandle) != pdTRUE)
|
||||
{
|
||||
returnValue = ERROR;
|
||||
LOGGER_ERROR(mainLog, "Starting display task failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER_INFO(mainLog, "Display task started");
|
||||
self->initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self->runTask = true;
|
||||
|
||||
if(returnValue == SUCCESS)
|
||||
else
|
||||
{
|
||||
if (xTaskCreate(DisplayTask, (const char*)"DisplayTask", self->stackSize, self, self->TaskPriority, &self->taskHandle) != pdTRUE)
|
||||
{
|
||||
returnValue = ERROR;
|
||||
LOGGER_ERROR(mainLog, "Starting display task failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER_INFO(mainLog, "Display task started");
|
||||
}
|
||||
returnValue = ERROR;
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
@@ -147,48 +157,57 @@ ErrorStatus Display_setContrast(struct Display* self, size_t contrast)
|
||||
ErrorStatus Display_write(struct Display* self, const char* buffer, unsigned int length, size_t row, size_t column)
|
||||
{
|
||||
ErrorStatus returnValue = SUCCESS;
|
||||
// Prior to any action on the display memory, perform necessary checkings
|
||||
if (returnValue == SUCCESS)
|
||||
|
||||
if (self->initialized)
|
||||
{
|
||||
// Check that the row coordinate does not exceed the display boundary
|
||||
if (row - 1 >= self->displayDevice->parameters.numberOfRows)
|
||||
// Prior to any action on the display memory, perform necessary checkings
|
||||
if (returnValue == SUCCESS)
|
||||
{
|
||||
returnValue = ERROR;
|
||||
// Check that the row coordinate does not exceed the display boundary
|
||||
if (row - 1 >= self->displayDevice->parameters.numberOfRows)
|
||||
{
|
||||
returnValue = ERROR;
|
||||
}
|
||||
}
|
||||
if (returnValue == SUCCESS)
|
||||
{
|
||||
// Check that the column coordinate does not exceed the display boundary
|
||||
if (column - 1 >= self->displayDevice->parameters.numberOfColumns)
|
||||
{
|
||||
returnValue = ERROR;
|
||||
}
|
||||
}
|
||||
if (returnValue == SUCCESS)
|
||||
{
|
||||
// Check that the length request does not exceed the display boundary
|
||||
// This is checked in combination with the column coordinate
|
||||
// numberOfColumns - column >= length
|
||||
// must be valid in order to put the requested message on display
|
||||
if (self->displayDevice->parameters.numberOfColumns - (column - 1) < length)
|
||||
{
|
||||
returnValue = ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (returnValue == SUCCESS)
|
||||
{
|
||||
// Get the access semaphore to the display memory - wait for access
|
||||
xSemaphoreTake(self->displayShadowAccessSemaphore, portMAX_DELAY);
|
||||
|
||||
int loopCounter;
|
||||
for (loopCounter = 0; loopCounter < length; loopCounter++)
|
||||
{
|
||||
Display_characterUpdate(&self->displayShadow[row - 1][(column - 1) + loopCounter], buffer[loopCounter]);
|
||||
}
|
||||
|
||||
xSemaphoreGive(self->displayShadowAccessSemaphore);
|
||||
xSemaphoreGive(self->displayWriteRequest);
|
||||
|
||||
}
|
||||
}
|
||||
if (returnValue == SUCCESS)
|
||||
else
|
||||
{
|
||||
// Check that the column coordinate does not exceed the display boundary
|
||||
if (column - 1 >= self->displayDevice->parameters.numberOfColumns)
|
||||
{
|
||||
returnValue = ERROR;
|
||||
}
|
||||
}
|
||||
if (returnValue == SUCCESS)
|
||||
{
|
||||
// Check that the length request does not exceed the display boundary
|
||||
// This is checked in combination with the column coordinate
|
||||
// numberOfColumns - column >= length
|
||||
// must be valid in order to put the requested message on display
|
||||
if (self->displayDevice->parameters.numberOfColumns - (column - 1) < length)
|
||||
{
|
||||
returnValue = ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (returnValue == SUCCESS)
|
||||
{
|
||||
// Get the access semaphore to the display memory - wait for access
|
||||
xSemaphoreTake(self->displayShadowAccessSemaphore, portMAX_DELAY);
|
||||
|
||||
int loopCounter;
|
||||
for (loopCounter = 0; loopCounter < length; loopCounter++)
|
||||
{
|
||||
Display_characterUpdate(&self->displayShadow[row - 1][(column - 1) + loopCounter], buffer[loopCounter]);
|
||||
}
|
||||
|
||||
xSemaphoreGive(self->displayShadowAccessSemaphore);
|
||||
|
||||
returnValue = ERROR;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
@@ -196,14 +215,21 @@ ErrorStatus Display_write(struct Display* self, const char* buffer, unsigned int
|
||||
|
||||
void Display_feedRefreshCounter(struct Display* self)
|
||||
{
|
||||
self->refreshFeedCounter++;
|
||||
if (self->initialized)
|
||||
{
|
||||
self->refreshFeedCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline static void Display_characterUpdate (struct DisplayCharacter* displayCharacter, char character)
|
||||
{
|
||||
displayCharacter->character = character;
|
||||
displayCharacter->isUpdated = true;
|
||||
// Sending the same character should not lead to an updated character
|
||||
if (displayCharacter->character != character)
|
||||
{
|
||||
displayCharacter->character = character;
|
||||
displayCharacter->isUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,8 +263,10 @@ static void Display_characterUpdateAll(struct Display* self)
|
||||
}
|
||||
// Give back display memory access semaphore to allow new updates
|
||||
xSemaphoreGive(self->displayShadowAccessSemaphore);
|
||||
xSemaphoreGive(self->displayWriteRequest);
|
||||
}
|
||||
|
||||
|
||||
static void DisplayTask(void* parameters)
|
||||
{
|
||||
struct Display* self = (struct Display*)parameters;
|
||||
@@ -253,91 +281,98 @@ static void DisplayTask(void* parameters)
|
||||
size_t columnStart;
|
||||
while (self->runTask)
|
||||
{
|
||||
// Get the access semaphore to the shadow - wait until the other functions are finished with updating the shadow
|
||||
xSemaphoreTake(self->displayShadowAccessSemaphore, portMAX_DELAY);
|
||||
leaveLoops = false;
|
||||
bufferIndex = 0;
|
||||
// Wait until a write or refresh function has requested this task to write to the display
|
||||
// xSemaphoreTake(self->displayWriteRequest, portMAX_DELAY);
|
||||
|
||||
// Fragment display writing - writing will be done per line
|
||||
for (; colCounter < self->displayDevice->parameters.numberOfColumns; colCounter++)
|
||||
// for (rowCounter = 0; rowCounter < self->displayDevice->parameters.numberOfRows; rowCounter++)
|
||||
{
|
||||
if (Display_isCharacterUpdated(&self->displayShadow[rowCounter][colCounter]))
|
||||
// Get the access semaphore to the shadow - wait until the other functions are finished with updating the shadow
|
||||
xSemaphoreTake(self->displayShadowAccessSemaphore, portMAX_DELAY);
|
||||
leaveLoops = false;
|
||||
bufferIndex = 0;
|
||||
|
||||
// Fragment display writing - writing will be done per line
|
||||
for (; colCounter < self->displayDevice->parameters.numberOfColumns; colCounter++)
|
||||
{
|
||||
// Found a character that has been updated
|
||||
// Put the display cursor at the appropriate coordinates
|
||||
rowStart = rowCounter + 1;
|
||||
columnStart = colCounter + 1;
|
||||
for (bufferIndex = 0; (colCounter < self->displayDevice->parameters.numberOfColumns); colCounter++, bufferIndex++)
|
||||
if (Display_isCharacterUpdated(&self->displayShadow[rowCounter][colCounter]))
|
||||
{
|
||||
// Respect the max number of bytes to transmit
|
||||
if (bufferIndex < self->maxCharactersPerTransmit)
|
||||
// Found a character that has been updated
|
||||
// Put the display cursor at the appropriate coordinates
|
||||
rowStart = rowCounter + 1;
|
||||
columnStart = colCounter + 1;
|
||||
for (bufferIndex = 0; (colCounter < self->displayDevice->parameters.numberOfColumns); colCounter++, bufferIndex++)
|
||||
{
|
||||
// Still within the boundaries
|
||||
if (Display_isCharacterUpdated(&self->displayShadow[rowCounter][colCounter]))
|
||||
// Respect the max number of bytes to transmit
|
||||
if (bufferIndex < self->maxCharactersPerTransmit)
|
||||
{
|
||||
// Current character has been updated and must be sent to display
|
||||
// But data from display shadow to transmit buffer
|
||||
buffer[bufferIndex] = Display_getUpdatedCharacter(&self->displayShadow[rowCounter][colCounter]);
|
||||
// Still within the boundaries
|
||||
if (Display_isCharacterUpdated(&self->displayShadow[rowCounter][colCounter]))
|
||||
{
|
||||
// Current character has been updated and must be sent to display
|
||||
// But data from display shadow to transmit buffer
|
||||
buffer[bufferIndex] = Display_getUpdatedCharacter(&self->displayShadow[rowCounter][colCounter]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Current character is already on the display
|
||||
// Stop scanning for more updated characters here and leave the loops in order
|
||||
// to start transmission to the display
|
||||
leaveLoops = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Current character is already on the display
|
||||
{
|
||||
// Max number of characters reached
|
||||
// Stop scanning for more updated characters here and leave the loops in order
|
||||
// to start transmission to the display
|
||||
leaveLoops = true;
|
||||
break;
|
||||
}
|
||||
leaveLoops = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Max number of characters reached
|
||||
// Stop scanning for more updated characters here and leave the loops in order
|
||||
// to start transmission to the display
|
||||
leaveLoops = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if loop should be left
|
||||
if (leaveLoops)
|
||||
{
|
||||
// An inner loop decided to leave, so leave
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if loop should be left
|
||||
if (leaveLoops)
|
||||
// Give back display memory access semaphore to allow new updates
|
||||
xSemaphoreGive(self->displayShadowAccessSemaphore);
|
||||
if (bufferIndex > 0)
|
||||
{
|
||||
// An inner loop decided to leave, so leave
|
||||
break;
|
||||
// If there was an update found, send it to the display
|
||||
DisplayDevice_write(self->displayDevice, buffer, bufferIndex, rowStart, columnStart);
|
||||
}
|
||||
}
|
||||
|
||||
// Give back display memory access semaphore to allow new updates
|
||||
xSemaphoreGive(self->displayShadowAccessSemaphore);
|
||||
if (bufferIndex > 0)
|
||||
{
|
||||
// If there was an update found, send it to the display
|
||||
DisplayDevice_write(self->displayDevice, buffer, bufferIndex, rowStart, columnStart);
|
||||
}
|
||||
|
||||
// Handle the counters for row and column
|
||||
if (colCounter > (self->displayDevice->parameters.numberOfColumns - 1))
|
||||
{
|
||||
// End of row reached - reset column and increment row
|
||||
colCounter = 0;
|
||||
|
||||
if (rowCounter < (self->displayDevice->parameters.numberOfRows - 1))
|
||||
// Handle the counters for row and column
|
||||
if (colCounter > (self->displayDevice->parameters.numberOfColumns - 1))
|
||||
{
|
||||
// Increment row
|
||||
rowCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Last row reached - restart at row 0
|
||||
rowCounter = 0;
|
||||
}
|
||||
}
|
||||
// End of row reached - reset column and increment row
|
||||
colCounter = 0;
|
||||
|
||||
// Check for display refresh timings
|
||||
if (self->refreshFeedCounter * self->refreshFeedFrequency_ms > self->refreshPeriod_ms)
|
||||
{
|
||||
self->refreshFeedCounter = 0;
|
||||
Display_characterUpdateAll(self);
|
||||
if (rowCounter < (self->displayDevice->parameters.numberOfRows - 1))
|
||||
{
|
||||
// Increment row
|
||||
rowCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Last row reached - restart at row 0
|
||||
rowCounter = 0;
|
||||
}
|
||||
}
|
||||
// Check for display refresh timings
|
||||
if (self->refreshFeedCounter * self->refreshFeedFrequency_ms > self->refreshPeriod_ms)
|
||||
{
|
||||
self->refreshFeedCounter = 0;
|
||||
Display_characterUpdateAll(self);
|
||||
}
|
||||
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
vTaskDelay(10);
|
||||
|
||||
Reference in New Issue
Block a user