267 lines
8.7 KiB
C
267 lines
8.7 KiB
C
#include "stm32f7xx_hal.h"
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
#include "nokia.h"
|
|
#include "spi.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
/// \file nokia.c
|
|
/// \brief Nokia functions
|
|
/// \version 1.0 first release
|
|
/// \author Pascal Sartoretti (sap at hevs dot ch)
|
|
/// \date 04-2014
|
|
/// \details The LCD is connected to the module interface bus
|
|
///
|
|
///-------------------------------------------------------------------------------
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// NOKIA CONSTANTS DEFINITIONS
|
|
//-----------------------------------------------------------------------------
|
|
#define DISPLAY_SEG_ON 0x09 // all display segment on
|
|
#define DISPLAY_INVERSE_VIDEO 0x0D // inverse video mode
|
|
#define DISPLAY_BLANK 0x08 // display blank
|
|
#define DISPLAY_NORMAL 0x0C // display in normal mode
|
|
#define SET_BASIC_MODE 0x20 // use basic instruction set
|
|
#define SET_EXTENDED_MODE 0x21 // use extended instruction set
|
|
#define VDD_LCD 0xC8 // VDD_LCD parameters
|
|
#define VDD_LCD_REG 0x80 // access of LCD_VDD register
|
|
#define CONTRAST_REG 0x10 // access of CONTRAST register
|
|
#define YPOS_REG 0x40 // access of Y_POS register
|
|
#define XPOS_REG 0x80 // access of X_POS register
|
|
#define X_NB_PIXELS 84 // Pixels in X
|
|
#define Y_NB_PIXELS 48 // Pixels in Y
|
|
#define Y_NB_LINES 6 // Number of lines
|
|
|
|
|
|
uint8_t gNokiaBuffer[X_NB_PIXELS * Y_NB_LINES];
|
|
uint8_t * gNokiaBufferPtr = gNokiaBuffer;
|
|
|
|
const size_t gNokiaBufferSize = sizeof(gNokiaBuffer);
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void NokiaControl(uint8_t controlByte) {
|
|
// Activate Control on SPI device (DC = 0)
|
|
HAL_GPIO_WritePin(D_C_NOKIA_GPIO_Port, D_C_NOKIA_Pin, GPIO_PIN_RESET);
|
|
|
|
// Select the Nokia LCD (CS = 0)
|
|
HAL_GPIO_WritePin(CS_NOKIA_GPIO_Port, CS_NOKIA_Pin, GPIO_PIN_RESET);
|
|
|
|
// Send the control byte
|
|
HAL_SPI_Transmit(&hspi2, &controlByte, 1, 10);
|
|
|
|
// Deselect the Nokia LCD (CS = 1)
|
|
HAL_GPIO_WritePin(CS_NOKIA_GPIO_Port, CS_NOKIA_Pin, GPIO_PIN_SET);
|
|
|
|
// Activate Data on SPI device (DC = 1)
|
|
HAL_GPIO_WritePin(D_C_NOKIA_GPIO_Port, D_C_NOKIA_Pin, GPIO_PIN_SET);
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void NokiaData(uint8_t dataByte)
|
|
{
|
|
// Select the Nokia LCD (CS = 0)
|
|
HAL_GPIO_WritePin(CS_NOKIA_GPIO_Port, CS_NOKIA_Pin, GPIO_PIN_RESET);
|
|
|
|
// Send the data byte
|
|
HAL_SPI_Transmit(&hspi2, &dataByte, 1, 10);
|
|
|
|
// Deselect the Nokia LCD (CS = 1)
|
|
HAL_GPIO_WritePin(CS_NOKIA_GPIO_Port, CS_NOKIA_Pin, GPIO_PIN_SET);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void Nokia_Init(void)
|
|
{
|
|
HAL_GPIO_WritePin(RST_NOKIA_GPIO_Port, RST_NOKIA_Pin, GPIO_PIN_SET);
|
|
//HAL_GPIO_WritePin(D_C_NOKIA_GPIO_Port, D_C_NOKIA_Pin, GPIO_PIN_SET);
|
|
HAL_GPIO_WritePin(CS_NOKIA_GPIO_Port, CS_NOKIA_Pin, GPIO_PIN_SET);
|
|
//-------------------------------------------------------------------------
|
|
// Setup the Nokia LCD for standard usage
|
|
//-------------------------------------------------------------------------
|
|
NokiaControl(SET_EXTENDED_MODE);
|
|
NokiaControl(VDD_LCD_REG + 62);
|
|
NokiaControl(CONTRAST_REG + 3);
|
|
NokiaControl(SET_BASIC_MODE);
|
|
NokiaControl(DISPLAY_SEG_ON);
|
|
NokiaControl(DISPLAY_BLANK);
|
|
NokiaControl(DISPLAY_NORMAL);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void NokiaGotoXY(uint8_t posX, uint8_t posY)
|
|
{
|
|
NokiaControl(YPOS_REG | (posY & 0x07)); // Y axe init: 0100 0yyy
|
|
NokiaControl(XPOS_REG | (posX & 0x7f)); // X axe init: 1xxx xxxx
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void NokiaClrDisplay(void)
|
|
{
|
|
memset(gNokiaBufferPtr, 0x0, X_NB_PIXELS * Y_NB_LINES);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void NokiaUpdate(void)
|
|
{
|
|
uint16_t i; // for local counter
|
|
|
|
NokiaGotoXY(0, 0); // topleft corner of screen
|
|
//-------------------------------------------------------------------------
|
|
for (i = 0; i < X_NB_PIXELS * Y_NB_LINES; i++) // for size of display
|
|
{
|
|
NokiaData(gNokiaBufferPtr[i]); // display memory content
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void NokiaSetPixel(uint8_t posX, uint8_t posY)
|
|
{
|
|
|
|
if ((posX > 83) || (posY > 47))
|
|
{
|
|
return;
|
|
}
|
|
// write a pixel on the display buffer
|
|
gNokiaBufferPtr[posX + 84 * (posY >> 3)] |= 1 << (posY & 0x07);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void NokiaClrPixel(uint8_t posX, uint8_t posY)
|
|
{
|
|
if ((posX > 83) || (posY > 47))
|
|
{
|
|
return;
|
|
}
|
|
// clear a pixel on the display buffer
|
|
gNokiaBufferPtr[posX + 84 * (posY >> 3)] &= ~(1 << (posY & 0x07));
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void NokiaColorPixel(uint8_t posX, uint8_t posY, uint8_t color)
|
|
{
|
|
if ((posX > 83) || (posY > 47))
|
|
{
|
|
return;
|
|
}
|
|
// clear a pixel on the display buffer
|
|
if(color == 0)
|
|
{
|
|
gNokiaBufferPtr[posX + 84 * (posY >> 3)] &= ~(1 << (posY & 0x07));
|
|
}
|
|
else // set this pixel
|
|
{
|
|
gNokiaBufferPtr[posX + 84 * (posY >> 3)] |= 1 << (posY & 0x07);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void NokiaDrawLine(uint8_t posX1, uint8_t posY1, uint8_t posX2, uint8_t posY2,
|
|
uint8_t color)
|
|
{
|
|
int16_t posX;
|
|
int16_t posY;
|
|
uint8_t temp;
|
|
|
|
if ((posX1 > 83) || (posY1 > 47) || (posX2 > 83) || (posY2 > 47))
|
|
{
|
|
return;
|
|
}
|
|
//---------------------------------------------------------------------
|
|
// line in quadrant 2 or 4
|
|
//---------------------------------------------------------------------
|
|
if (((posX1 > posX2) && (posY1 > posY2)) // QUADRANT 2
|
|
|| ((posX1 < posX2) && (posY1 < posY2))) // or QUADRANT 4
|
|
{
|
|
//-----------------------------------------------------------------
|
|
if (posX1 > posX2) // QUADRANT 2 ONLY
|
|
{
|
|
temp = posX1; // swap posX1 <> posX2
|
|
posX1 = posX2;
|
|
posX2 = temp;
|
|
temp = posY1; // swap posY1 <> posY2
|
|
posY1 = posY2;
|
|
posY2 = temp;
|
|
}
|
|
//-----------------------------------------------------------------
|
|
if ((posX2 - posX1) > (posY2 - posY1)) // angle is less 45 deg
|
|
{
|
|
for (posX = posX1; posX <= posX2; posX++) // display the line
|
|
{
|
|
posY = posY2
|
|
- ((((posY2 - posY1) * (posX2 - posX)) * 16)
|
|
/ (posX2 - posX1) + 8) / 16;
|
|
NokiaColorPixel(posX, posY,color);
|
|
}
|
|
}
|
|
//-----------------------------------------------------------------
|
|
else // line angle more 45 deg
|
|
{
|
|
for (posY = posY1; posY <= posY2; posY++) // display the line
|
|
{
|
|
posX = posX2
|
|
- ((((posX2 - posX1) * (posY2 - posY)) * 16)
|
|
/ (posY2 - posY1) + 8) / 16;
|
|
NokiaColorPixel(posX, posY,color);
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------
|
|
// line in quadrant 1 or 3
|
|
//---------------------------------------------------------------------
|
|
else
|
|
{
|
|
if (posX1 > posX2) // QUADRANT 1
|
|
{
|
|
temp = posX1; // swap posX1 <> posX2
|
|
posX1 = posX2;
|
|
posX2 = temp;
|
|
}
|
|
//-----------------------------------------------------------------
|
|
else if (posY1 > posY2) // QUADRANT 3
|
|
{
|
|
temp = posY1; // swap posY1 <> posY2
|
|
posY1 = posY2;
|
|
posY2 = temp;
|
|
}
|
|
//-----------------------------------------------------------------
|
|
if ((posX2 - posX1) > (posY2 - posY1)) // angle is less 45 deg
|
|
{
|
|
for (posX = posX1; posX <= posX2; posX++) // display the line
|
|
{
|
|
posY = posY1
|
|
+ ((((posY2 - posY1) * (posX2 - posX)) * 16)
|
|
/ (posX2 - posX1) + 8) / 16;
|
|
NokiaColorPixel(posX, posY,color);
|
|
}
|
|
}
|
|
else // angle is more 45 deg
|
|
{
|
|
if (posY1 == posY2)
|
|
{
|
|
NokiaColorPixel(posX1, posY1,color);
|
|
return;
|
|
}
|
|
for (posY = posY1; posY <= posY2; posY++) // display the line
|
|
{
|
|
posX = posX1
|
|
+ ((((posX2 - posX1) * (posY2 - posY)) * 16)
|
|
/ (posY2 - posY1) + 8) / 16;
|
|
NokiaColorPixel(posX, posY,color);
|
|
}
|
|
}
|
|
}
|
|
}
|