0
mirror of https://github.com/OneOfEleven/uv-k5-firmware-custom.git synced 2025-04-28 22:31:25 +03:00

247 lines
6.1 KiB
C
Raw Normal View History

2023-09-09 08:03:56 +01:00
/* 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
2023-09-11 00:02:57 +01:00
2023-09-09 08:03:56 +01:00
#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"
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
uint8_t g_status_line[128];
uint8_t g_frame_buffer[7][128];
uint8_t contrast = 31; // 0 ~ 63
2023-09-09 08:03:56 +01:00
void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const unsigned int Size, const uint8_t *pBitmap)
2023-09-09 08:03:56 +01:00
{
unsigned int i;
2023-09-09 08:03:56 +01:00
SPI_ToggleMasterMode(&SPI0->CR, false);
2023-09-09 08:03:56 +01:00
ST7565_SelectColumnAndLine(Column + 4U, Line);
2023-09-09 08:03:56 +01:00
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
if (pBitmap != NULL)
2023-09-09 11:17:45 +01:00
{
for (i = 0; i < Size; i++)
{
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
2023-09-09 08:03:56 +01:00
SPI0->WDR = pBitmap[i];
}
2023-09-09 11:17:45 +01:00
}
else
{
for (i = 0; i < Size; i++)
{
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
2023-09-09 08:03:56 +01:00
SPI0->WDR = 0;
}
}
SPI_WaitForUndocumentedTxFifoStatusBit();
2023-09-09 11:17:45 +01:00
2023-09-09 08:03:56 +01:00
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_BlitFullScreen(void)
{
2023-09-16 17:16:36 +01:00
unsigned int Line;
2023-09-09 08:03:56 +01:00
// reset some of the displays settings to try and overcome the
// radios hardware problem - RF corrupting the display
ST7565_Init(false);
2023-09-09 08:03:56 +01:00
SPI_ToggleMasterMode(&SPI0->CR, false);
2023-09-09 11:17:45 +01:00
2023-09-09 08:03:56 +01:00
ST7565_WriteByte(0x40);
2023-10-08 20:23:37 +01:00
for (Line = 0; Line < ARRAY_SIZE(g_frame_buffer); Line++)
2023-09-09 11:17:45 +01:00
{
2023-09-16 17:16:36 +01:00
unsigned int Column;
2023-09-09 11:17:45 +01:00
ST7565_SelectColumnAndLine(4, Line + 1);
2023-09-09 08:03:56 +01:00
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
2023-10-08 20:23:37 +01:00
for (Column = 0; Column < ARRAY_SIZE(g_frame_buffer[0]); Column++)
2023-09-09 11:17:45 +01:00
{
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
2023-10-08 20:23:37 +01:00
SPI0->WDR = g_frame_buffer[Line][Column];
2023-09-09 08:03:56 +01:00
}
SPI_WaitForUndocumentedTxFifoStatusBit();
}
2023-09-09 11:17:45 +01:00
#if 0
// whats the delay for, it holds things up :(
2023-09-09 11:17:45 +01:00
SYSTEM_DelayMs(20);
#else
// SYSTEM_DelayMs(1);
2023-09-09 11:17:45 +01:00
#endif
2023-09-11 00:02:57 +01:00
2023-09-09 08:03:56 +01:00
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_BlitStatusLine(void)
{ // the top small text line on the display
2023-09-09 11:17:45 +01:00
unsigned int i;
2023-09-09 08:03:56 +01:00
SPI_ToggleMasterMode(&SPI0->CR, false);
2023-09-09 11:17:45 +01:00
2023-09-15 10:57:26 +01:00
ST7565_WriteByte(0x40); // start line ?
2023-09-09 11:17:45 +01:00
2023-09-09 08:03:56 +01:00
ST7565_SelectColumnAndLine(4, 0);
2023-09-09 11:17:45 +01:00
2023-09-09 08:03:56 +01:00
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
2023-10-08 20:23:37 +01:00
for (i = 0; i < ARRAY_SIZE(g_status_line); i++)
2023-09-09 11:17:45 +01:00
{
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
2023-10-08 20:23:37 +01:00
SPI0->WDR = g_status_line[i];
2023-09-09 08:03:56 +01:00
}
2023-09-09 11:17:45 +01:00
2023-09-09 08:03:56 +01:00
SPI_WaitForUndocumentedTxFifoStatusBit();
2023-09-09 11:17:45 +01:00
2023-09-09 08:03:56 +01:00
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_FillScreen(const uint8_t Value)
2023-09-09 08:03:56 +01:00
{
2023-09-09 11:17:45 +01:00
unsigned int i;
2023-09-09 08:03:56 +01:00
// reset some of the displays settings to try and overcome the
// radios hardware problem - RF corrupting the display
ST7565_Init(false);
2023-09-09 08:03:56 +01:00
SPI_ToggleMasterMode(&SPI0->CR, false);
2023-10-05 17:38:25 +01:00
2023-09-09 11:17:45 +01:00
for (i = 0; i < 8; i++)
{
unsigned int j;
2023-09-09 08:03:56 +01:00
ST7565_SelectColumnAndLine(0, i);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
2023-09-09 11:17:45 +01:00
for (j = 0; j < 132; j++)
{
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
2023-09-09 08:03:56 +01:00
SPI0->WDR = Value;
}
SPI_WaitForUndocumentedTxFifoStatusBit();
}
2023-10-05 17:38:25 +01:00
2023-09-09 08:03:56 +01:00
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_Init(const bool full)
2023-09-09 08:03:56 +01:00
{
if (full)
{
SPI0_Init();
ST7565_HardwareReset();
2023-10-16 20:58:19 +01:00
}
2023-10-16 20:58:19 +01:00
SPI_ToggleMasterMode(&SPI0->CR, false);
2023-10-16 20:58:19 +01:00
if (full)
{
ST7565_WriteByte(0xE2); // internal reset
SYSTEM_DelayMs(120);
}
2023-10-16 20:58:19 +01:00
ST7565_WriteByte(0xA2); // bias 9
// ST7565_WriteByte(0xA3); // bias 7
2023-10-16 20:58:19 +01:00
ST7565_WriteByte(0xC0); // COM normal
// ST7565_WriteByte(0xC8); // COM reverse
2023-10-16 20:58:19 +01:00
// ST7565_WriteByte(0xA0); // normal ADC .. mirrors the screen
ST7565_WriteByte(0xA1); // reverse ADC
2023-09-16 07:08:18 +01:00
2023-10-16 20:58:19 +01:00
ST7565_WriteByte(0xA6); // normal screen
// ST7565_WriteByte(0xA7); // inverse screen
2023-09-09 11:17:45 +01:00
2023-10-16 20:58:19 +01:00
ST7565_WriteByte(0xA4); // all points normal
2023-10-05 17:38:25 +01:00
2023-10-16 20:58:19 +01:00
ST7565_WriteByte(0x24); // ???
2023-10-16 20:58:19 +01:00
ST7565_WriteByte(0x81); //
ST7565_WriteByte(contrast); // brightness 0 ~ 63
2023-10-16 20:58:19 +01:00
if (full)
{
ST7565_WriteByte(0x28 | 4u); // enable voltage converter VC=1 VR=0 VF=0
SYSTEM_DelayMs(50);
2023-10-16 20:58:19 +01:00
ST7565_WriteByte(0x28 | 6u); // enable voltage regulator VC=1 VR=1 VF=0
SYSTEM_DelayMs(50);
2023-10-16 20:58:19 +01:00
ST7565_WriteByte(0x28 | 7u); // enable voltage follower VC=1 VR=1 VF=1
SYSTEM_DelayMs(10);
2023-10-16 20:58:19 +01:00
ST7565_WriteByte(0x20 | 6u); // set lcd operating voltage (regulator resistor, ref voltage resistor)
}
2023-10-16 20:58:19 +01:00
ST7565_WriteByte(0x40); // start line ?
ST7565_WriteByte(0xAF); // display on ?
2023-09-09 08:03:56 +01:00
SPI_WaitForUndocumentedTxFifoStatusBit();
2023-09-09 11:17:45 +01:00
2023-09-09 08:03:56 +01:00
SPI_ToggleMasterMode(&SPI0->CR, true);
2023-09-09 11:17:45 +01:00
if (full)
ST7565_FillScreen(0x00);
2023-09-09 08:03:56 +01:00
}
void ST7565_HardwareReset(void)
2023-09-09 08:03:56 +01:00
{
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)
2023-09-09 08:03:56 +01:00
{
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
2023-09-09 11:17:45 +01:00
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
SPI0->WDR = Line + 176;
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
2023-09-09 08:03:56 +01:00
SPI0->WDR = ((Column >> 4) & 0x0F) | 0x10;
2023-09-09 11:17:45 +01:00
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
2023-09-09 08:03:56 +01:00
SPI0->WDR = ((Column >> 0) & 0x0F);
SPI_WaitForUndocumentedTxFifoStatusBit();
}
void ST7565_WriteByte(const uint8_t Value)
2023-09-09 08:03:56 +01:00
{
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
2023-09-09 11:17:45 +01:00
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
2023-09-09 08:03:56 +01:00
SPI0->WDR = Value;
}
void ST7565_SetContrast(const uint8_t value)
{
contrast = (value <= 63) ? value : 63;
}
uint8_t ST7565_GetContrast(void)
{
return contrast;
}