This repository has been archived on 2024-01-25. You can view files and clone it, but cannot push or open issues or pull requests.
Sem-dma/nokia.c

267 lines
8.7 KiB
C
Raw Normal View History

2023-12-11 13:43:05 +00:00
#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) {
2023-12-14 20:29:30 +00:00
// Activate Control on SPI device (DC = 0)
2023-12-11 13:43:05 +00:00
HAL_GPIO_WritePin(D_C_NOKIA_GPIO_Port, D_C_NOKIA_Pin, GPIO_PIN_RESET);
2023-12-11 15:22:42 +00:00
2023-12-14 20:29:30 +00:00
// Select the Nokia LCD (CS = 0)
HAL_GPIO_WritePin(CS_NOKIA_GPIO_Port, CS_NOKIA_Pin, GPIO_PIN_RESET);
// Send the control byte
2023-12-11 14:07:16 +00:00
HAL_SPI_Transmit(&hspi2, &controlByte, 1, 10);
2023-12-14 20:29:30 +00:00
// Deselect the Nokia LCD (CS = 1)
2023-12-11 13:43:05 +00:00
HAL_GPIO_WritePin(CS_NOKIA_GPIO_Port, CS_NOKIA_Pin, GPIO_PIN_SET);
2023-12-14 20:29:30 +00:00
// Activate Data on SPI device (DC = 1)
2023-12-11 13:43:05 +00:00
HAL_GPIO_WritePin(D_C_NOKIA_GPIO_Port, D_C_NOKIA_Pin, GPIO_PIN_SET);
2023-12-14 20:29:30 +00:00
2023-12-11 13:43:05 +00:00
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void NokiaData(uint8_t dataByte)
{
2023-12-14 20:29:30 +00:00
// Select the Nokia LCD (CS = 0)
2023-12-11 13:43:05 +00:00
HAL_GPIO_WritePin(CS_NOKIA_GPIO_Port, CS_NOKIA_Pin, GPIO_PIN_RESET);
2023-12-11 15:22:42 +00:00
2023-12-14 20:29:30 +00:00
// Send the data byte
2023-12-11 15:22:42 +00:00
HAL_SPI_Transmit(&hspi2, &dataByte, 1, 10);
2023-12-14 20:29:30 +00:00
// Deselect the Nokia LCD (CS = 1)
2023-12-11 13:43:05 +00:00
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);
}
}
}
}