Files
hsb/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/Display.c
mmi 17207a3a4b Fixed some major issues with RAM shortage. Also moved the cached storage to a MALLOC design instead of fixed memory usage. Using freertos porteds malloc and free required to move to HEAP4 to make sure memory does not get fragmented.
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
2017-11-07 15:50:25 +00:00

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);
}