Resized nearly all task stacks Also: - Menu fixes for insertion. Almost done, just need to fix the negative voltage insertion for mcp and cathode - Added Device parameters, must be filled in git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@271 05563f52-14a8-4384-a975-3d1654cca0fa
300 lines
9.0 KiB
C
300 lines
9.0 KiB
C
// -----------------------------------------------------------------------------
|
|
/// @file Display.c
|
|
/// @brief Description
|
|
// -----------------------------------------------------------------------------
|
|
// Micro-Key bv
|
|
// Industrieweg 28, 9804 TG Noordhorn
|
|
// Postbus 92, 9800 AB Zuidhorn
|
|
// The Netherlands
|
|
// Tel: +31 594 503020
|
|
// Fax: +31 594 505825
|
|
// Email: support@microkey.nl
|
|
// Web: www.microkey.nl
|
|
// -----------------------------------------------------------------------------
|
|
/// $Revision$
|
|
/// $Author$
|
|
/// $Date$
|
|
// (c) 2017 Micro-Key bv
|
|
// -----------------------------------------------------------------------------
|
|
|
|
/// @file Display.c
|
|
/// @ingroup {group_name}
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Include files
|
|
// -----------------------------------------------------------------------------
|
|
|
|
#include <string.h>
|
|
|
|
#include "Display.h"
|
|
#include "Logger.h"
|
|
|
|
#include "nhd0420.h"
|
|
|
|
#include "platform.h"
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Constant and macro definitions
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Type definitions
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// File-scope variables
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Function declarations
|
|
// -----------------------------------------------------------------------------
|
|
|
|
static void DisplayTask(void* parameters);
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Function definitions
|
|
// -----------------------------------------------------------------------------
|
|
|
|
ErrorStatus Display_construct(struct Display* self, struct DisplayDevice* displayDevice, int TaskPriority, uint16_t stackSize, int maxCharactersPerTransmit, int refreshFeedFrequency_ms, int refreshPeriod)
|
|
{
|
|
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;
|
|
|
|
|
|
if(returnValue == SUCCESS)
|
|
{
|
|
// Create a semaphore to sync writing requests to the display
|
|
vSemaphoreCreateBinary(self->displayWriteRequest);
|
|
}
|
|
if (returnValue == SUCCESS)
|
|
{
|
|
returnValue = DisplayContent_construct(&self->displayContent, self->displayDevice->parameters.numberOfRows, self->displayDevice->parameters.numberOfColumns);
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
returnValue = ERROR;
|
|
}
|
|
|
|
return returnValue;
|
|
}
|
|
|
|
|
|
void Display_destruct(struct Display* self)
|
|
{
|
|
self->runTask = false;
|
|
}
|
|
|
|
|
|
ErrorStatus Display_clearScreen(struct Display* self)
|
|
{
|
|
ErrorStatus returnValue = SUCCESS;
|
|
DisplayContent_clear(&self->displayContent);
|
|
xSemaphoreGive(self->displayWriteRequest);
|
|
return returnValue;
|
|
}
|
|
|
|
|
|
ErrorStatus Display_clearLine(struct Display* self, size_t line)
|
|
{
|
|
char buffer[self->displayDevice->parameters.numberOfColumns + 1];
|
|
|
|
int loopcounter;
|
|
for (loopcounter = 0; loopcounter < self->displayDevice->parameters.numberOfColumns; loopcounter++)
|
|
{
|
|
buffer[loopcounter] = 0x20;
|
|
}
|
|
buffer[self->displayDevice->parameters.numberOfColumns] = '\0';
|
|
|
|
return Display_write(self, buffer, line, 1);
|
|
}
|
|
|
|
|
|
ErrorStatus Display_setState(struct Display* self, DisplayDevice_functionalState state)
|
|
{
|
|
return DisplayDevice_setState(self->displayDevice, state);
|
|
}
|
|
|
|
|
|
ErrorStatus Display_setBrightness(struct Display* self, size_t brightness)
|
|
{
|
|
return DisplayDevice_setBrightness(self->displayDevice, brightness);
|
|
}
|
|
|
|
|
|
ErrorStatus Display_setContrast(struct Display* self, size_t contrast)
|
|
{
|
|
return DisplayDevice_setContrast(self->displayDevice, contrast);
|
|
}
|
|
|
|
|
|
ErrorStatus Display_setBlinkingCursorState(struct Display* self, DisplayDevice_functionalState state)
|
|
{
|
|
return DisplayDevice_setBlinkingCursorState(self->displayDevice, state);
|
|
}
|
|
|
|
ErrorStatus Display_setCursorToPosition(struct Display* self, unsigned int row, unsigned int column)
|
|
{
|
|
return DisplayDevice_setCursorToPosition(self->displayDevice, row, column);
|
|
}
|
|
|
|
|
|
ErrorStatus Display_backspace(struct Display* self)
|
|
{
|
|
return DisplayDevice_backspace(self->displayDevice);
|
|
}
|
|
|
|
|
|
ErrorStatus Display_write(struct Display* self, const char* buffer, size_t row, size_t column)
|
|
{
|
|
ErrorStatus returnValue = SUCCESS;
|
|
|
|
if (self->initialized)
|
|
{
|
|
int length = 0;
|
|
// Prior to any action on the display memory, perform necessary checkings
|
|
if (returnValue == SUCCESS)
|
|
{
|
|
// 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)
|
|
{
|
|
length = strlen(buffer);
|
|
// 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)
|
|
{
|
|
int loopCounter;
|
|
for (loopCounter = 0; loopCounter < length; loopCounter++)
|
|
{
|
|
DisplayContent_updateCharacter(&self->displayContent, (row - 1), (column - 1) + loopCounter, buffer[loopCounter]);
|
|
}
|
|
|
|
xSemaphoreGive(self->displayWriteRequest);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
returnValue = ERROR;
|
|
}
|
|
return returnValue;
|
|
}
|
|
|
|
|
|
void Display_feedRefreshCounter(struct Display* self)
|
|
{
|
|
if (self->initialized)
|
|
{
|
|
self->refreshFeedCounter++;
|
|
if (self->refreshFeedCounter * self->refreshFeedFrequency_ms > self->refreshPeriod_ms)
|
|
{
|
|
xSemaphoreGive(self->displayWriteRequest);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Display_feedRefreshCounterFromISR(struct Display* self)
|
|
{
|
|
portBASE_TYPE higherPriorityTaskWoken = pdFALSE;
|
|
if (self->initialized)
|
|
{
|
|
self->refreshFeedCounter++;
|
|
if (self->refreshFeedCounter * self->refreshFeedFrequency_ms > self->refreshPeriod_ms)
|
|
{
|
|
xSemaphoreGiveFromISR(self->displayWriteRequest, &higherPriorityTaskWoken);
|
|
}
|
|
}
|
|
portEND_SWITCHING_ISR(higherPriorityTaskWoken);
|
|
}
|
|
|
|
|
|
static void DisplayTask(void* parameters)
|
|
{
|
|
struct Display* self = (struct Display*)parameters;
|
|
|
|
char buffer;
|
|
int rowCounter = 0;
|
|
int colCounter = 0;
|
|
|
|
while (self->runTask)
|
|
{
|
|
xSemaphoreTake(self->displayWriteRequest, portMAX_DELAY);
|
|
// Check for display refresh timings
|
|
if (self->refreshFeedCounter * self->refreshFeedFrequency_ms > self->refreshPeriod_ms)
|
|
{
|
|
self->refreshFeedCounter = 0;
|
|
DisplayContent_refresh(&self->displayContent);
|
|
}
|
|
|
|
for (rowCounter = 0; rowCounter < self->displayDevice->parameters.numberOfRows; rowCounter++)
|
|
{
|
|
for (colCounter = 0; colCounter < self->displayDevice->parameters.numberOfColumns; colCounter++)
|
|
{
|
|
if (DisplayContent_isCharacterUpdated(&self->displayContent, rowCounter, colCounter))
|
|
{
|
|
buffer = DisplayContent_getCharacter(&self->displayContent, rowCounter, colCounter);
|
|
DisplayDevice_write(self->displayDevice, &buffer, 1, rowCounter + 1, colCounter + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
vTaskDelay(10);
|
|
}
|
|
|
|
// Task has been marked to end - after leaving the endless loop, end/delete this task
|
|
vTaskDelete(NULL);
|
|
|
|
}
|
|
|