0
mirror of https://github.com/OneOfEleven/uv-k5-firmware-custom.git synced 2025-04-27 22:01:26 +03:00
2023-11-06 09:34:35 +01:00

256 lines
6.0 KiB
C

/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include <stdio.h> // NULL
#include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/spi.h"
#include "driver/gpio.h"
#include "driver/spi.h"
#include "driver/st7565.h"
#include "driver/system.h"
#include "misc.h"
uint8_t g_status_line[128];
uint8_t g_frame_buffer[7][128];
#ifdef ENABLE_CONTRAST
uint8_t contrast = 31; // 0 ~ 63
#endif
static void ST7565_WriteByte(uint8_t Value);
static inline void ST7565_LowLevelWrite(uint8_t Value)
{
/* Wait for space in the fifo */
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
SPI0->WDR = Value;
}
void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const unsigned int Size, const uint8_t *pBitmap)
{
unsigned int i;
SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_SelectColumnAndLine(Column + 4U, Line);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
if (pBitmap != NULL)
{
for (i = 0; i < Size; i++)
{
ST7565_LowLevelWrite(pBitmap[i]);
}
}
else
{
for (i = 0; i < Size; i++)
{
ST7565_LowLevelWrite(0);
}
}
SPI_WaitForUndocumentedTxFifoStatusBit();
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_BlitFullScreen(void)
{
unsigned int Line;
// reset some of the displays settings to try and overcome the
// radios hardware problem - RF corrupting the display
ST7565_Init(false);
SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_WriteByte(0x40);
for (Line = 0; Line < ARRAY_SIZE(g_frame_buffer); Line++)
{
unsigned int Column;
ST7565_SelectColumnAndLine(4, Line + 1);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
for (Column = 0; Column < ARRAY_SIZE(g_frame_buffer[0]); Column++)
{
ST7565_LowLevelWrite(g_frame_buffer[Line][Column]);
}
SPI_WaitForUndocumentedTxFifoStatusBit();
}
#if 0
// whats the delay for, it holds things up :(
SYSTEM_DelayMs(20);
#else
// SYSTEM_DelayMs(1);
#endif
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_BlitStatusLine(void)
{ // the top small text line on the display
unsigned int i;
SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_WriteByte(0x40); // start line ?
ST7565_SelectColumnAndLine(4, 0);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
for (i = 0; i < ARRAY_SIZE(g_status_line); i++)
{
ST7565_LowLevelWrite(g_status_line[i]);
}
SPI_WaitForUndocumentedTxFifoStatusBit();
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_FillScreen(const uint8_t Value)
{
unsigned int i;
// reset some of the displays settings to try and overcome the
// radios hardware problem - RF corrupting the display
ST7565_Init(false);
SPI_ToggleMasterMode(&SPI0->CR, false);
for (i = 0; i < 8; i++)
{
unsigned int j;
ST7565_SelectColumnAndLine(0, i);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
for (j = 0; j < 132; j++)
{
ST7565_LowLevelWrite(Value);
}
SPI_WaitForUndocumentedTxFifoStatusBit();
}
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_Init(const bool full)
{
if (full)
{
SPI0_Init();
ST7565_HardwareReset();
}
SPI_ToggleMasterMode(&SPI0->CR, false);
if (full)
{
ST7565_WriteByte(0xE2); // internal reset
SYSTEM_DelayMs(120);
}
ST7565_WriteByte(0xA2); // bias 9
// ST7565_WriteByte(0xA3); // bias 7
ST7565_WriteByte(0xC0); // COM normal
// ST7565_WriteByte(0xC8); // COM reverse
// ST7565_WriteByte(0xA0); // normal ADC .. mirrors the screen
ST7565_WriteByte(0xA1); // reverse ADC
ST7565_WriteByte(0xA6); // normal screen
// ST7565_WriteByte(0xA7); // inverse screen
ST7565_WriteByte(0xA4); // all points normal
ST7565_WriteByte(0x24); // ???
ST7565_WriteByte(0x81); //
#ifdef ENABLE_CONTRAST
ST7565_WriteByte(contrast); // brightness 0 ~ 63
#else
ST7565_WriteByte(31); // brightness 0 ~ 63
#endif
if (full)
{
ST7565_WriteByte(0x28 | 4u); // enable voltage converter VC=1 VR=0 VF=0
SYSTEM_DelayMs(50);
ST7565_WriteByte(0x28 | 6u); // enable voltage regulator VC=1 VR=1 VF=0
SYSTEM_DelayMs(50);
ST7565_WriteByte(0x28 | 7u); // enable voltage follower VC=1 VR=1 VF=1
SYSTEM_DelayMs(10);
ST7565_WriteByte(0x20 | 6u); // set lcd operating voltage (regulator resistor, ref voltage resistor)
}
ST7565_WriteByte(0x40); // start line ?
ST7565_WriteByte(0xAF); // display on ?
SPI_WaitForUndocumentedTxFifoStatusBit();
SPI_ToggleMasterMode(&SPI0->CR, true);
if (full)
ST7565_FillScreen(0x00);
}
void ST7565_HardwareReset(void)
{
GPIO_SetBit( &GPIOB->DATA, GPIOB_PIN_ST7565_RES);
SYSTEM_DelayMs(1);
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES);
SYSTEM_DelayMs(20);
GPIO_SetBit( &GPIOB->DATA, GPIOB_PIN_ST7565_RES);
SYSTEM_DelayMs(120);
}
void ST7565_SelectColumnAndLine(const uint8_t Column, const uint8_t Line)
{
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
ST7565_LowLevelWrite(Line + 0xB0);
ST7565_LowLevelWrite(((Column >> 4) & 0x0F) | 0x10);
ST7565_LowLevelWrite((Column >> 0) & 0x0F);
SPI_WaitForUndocumentedTxFifoStatusBit();
}
static void ST7565_WriteByte(uint8_t Value)
{
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
ST7565_LowLevelWrite(Value);
}
#ifdef ENABLE_CONTRAST
void ST7565_SetContrast(const uint8_t value)
{
contrast = (value > 45) ? 45 : (value < 26) ? 26 : value;
}
uint8_t ST7565_GetContrast(void)
{
return contrast;
}
#endif