344d0000fa
- Implemented DMA functionality with a new dma.c and dma.h file. - Added LiquidCrystal I2C driver with liquidcrystal_i2c.c and liquidcrystal_i2c.h files. - Updated CMakeLists.txt to include dma.c and liquidcrystal_i2c.c in the build process. - Modified build.ninja and compile_commands.json to reflect the new source files. - Enhanced the main application to utilize the new DMA and LiquidCrystal I2C features.
297 lines
5.2 KiB
C
Executable File
297 lines
5.2 KiB
C
Executable File
#include "liquidcrystal_i2c.h"
|
|
|
|
extern I2C_HandleTypeDef hi2c1;
|
|
|
|
uint8_t dpFunction;
|
|
uint8_t dpControl;
|
|
uint8_t dpMode;
|
|
uint8_t dpRows;
|
|
uint8_t dpBacklight;
|
|
|
|
static void SendCommand(uint8_t);
|
|
static void SendChar(uint8_t);
|
|
static void Send(uint8_t, uint8_t);
|
|
static void Write4Bits(uint8_t);
|
|
static void ExpanderWrite(uint8_t);
|
|
static void PulseEnable(uint8_t);
|
|
static void DelayInit(void);
|
|
static void DelayUS(uint32_t);
|
|
|
|
uint8_t special1[8] = {
|
|
0b00000,
|
|
0b11001,
|
|
0b11011,
|
|
0b00110,
|
|
0b01100,
|
|
0b11011,
|
|
0b10011,
|
|
0b00000
|
|
};
|
|
|
|
uint8_t special2[8] = {
|
|
0b11000,
|
|
0b11000,
|
|
0b00110,
|
|
0b01001,
|
|
0b01000,
|
|
0b01001,
|
|
0b00110,
|
|
0b00000
|
|
};
|
|
|
|
void HD44780_Init(uint8_t rows)
|
|
{
|
|
dpRows = rows;
|
|
|
|
dpBacklight = LCD_BACKLIGHT;
|
|
|
|
dpFunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
|
|
|
|
if (dpRows > 1)
|
|
{
|
|
dpFunction |= LCD_2LINE;
|
|
}
|
|
else
|
|
{
|
|
dpFunction |= LCD_5x10DOTS;
|
|
}
|
|
|
|
/* Wait for initialization */
|
|
DelayInit();
|
|
HAL_Delay(50);
|
|
|
|
ExpanderWrite(dpBacklight);
|
|
HAL_Delay(1000);
|
|
|
|
/* 4bit Mode */
|
|
Write4Bits(0x03 << 4);
|
|
DelayUS(4500);
|
|
|
|
Write4Bits(0x03 << 4);
|
|
DelayUS(4500);
|
|
|
|
Write4Bits(0x03 << 4);
|
|
DelayUS(4500);
|
|
|
|
Write4Bits(0x02 << 4);
|
|
DelayUS(100);
|
|
|
|
/* Display Control */
|
|
SendCommand(LCD_FUNCTIONSET | dpFunction);
|
|
|
|
dpControl = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
|
|
HD44780_Display();
|
|
HD44780_Clear();
|
|
|
|
/* Display Mode */
|
|
dpMode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
|
|
SendCommand(LCD_ENTRYMODESET | dpMode);
|
|
DelayUS(4500);
|
|
|
|
HD44780_CreateSpecialChar(0, special1);
|
|
HD44780_CreateSpecialChar(1, special2);
|
|
|
|
HD44780_Home();
|
|
}
|
|
|
|
void HD44780_Clear()
|
|
{
|
|
SendCommand(LCD_CLEARDISPLAY);
|
|
DelayUS(2000);
|
|
}
|
|
|
|
void HD44780_Home()
|
|
{
|
|
SendCommand(LCD_RETURNHOME);
|
|
DelayUS(2000);
|
|
}
|
|
|
|
void HD44780_SetCursor(uint8_t col, uint8_t row)
|
|
{
|
|
int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
|
|
if (row >= dpRows)
|
|
{
|
|
row = dpRows-1;
|
|
}
|
|
SendCommand(LCD_SETDDRAMADDR | (col + row_offsets[row]));
|
|
}
|
|
|
|
void HD44780_NoDisplay()
|
|
{
|
|
dpControl &= ~LCD_DISPLAYON;
|
|
SendCommand(LCD_DISPLAYCONTROL | dpControl);
|
|
}
|
|
|
|
void HD44780_Display()
|
|
{
|
|
dpControl |= LCD_DISPLAYON;
|
|
SendCommand(LCD_DISPLAYCONTROL | dpControl);
|
|
}
|
|
|
|
void HD44780_NoCursor()
|
|
{
|
|
dpControl &= ~LCD_CURSORON;
|
|
SendCommand(LCD_DISPLAYCONTROL | dpControl);
|
|
}
|
|
|
|
void HD44780_Cursor()
|
|
{
|
|
dpControl |= LCD_CURSORON;
|
|
SendCommand(LCD_DISPLAYCONTROL | dpControl);
|
|
}
|
|
|
|
void HD44780_NoBlink()
|
|
{
|
|
dpControl &= ~LCD_BLINKON;
|
|
SendCommand(LCD_DISPLAYCONTROL | dpControl);
|
|
}
|
|
|
|
void HD44780_Blink()
|
|
{
|
|
dpControl |= LCD_BLINKON;
|
|
SendCommand(LCD_DISPLAYCONTROL | dpControl);
|
|
}
|
|
|
|
void HD44780_ScrollDisplayLeft(void)
|
|
{
|
|
SendCommand(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
|
|
}
|
|
|
|
void HD44780_ScrollDisplayRight(void)
|
|
{
|
|
SendCommand(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
|
|
}
|
|
|
|
void HD44780_LeftToRight(void)
|
|
{
|
|
dpMode |= LCD_ENTRYLEFT;
|
|
SendCommand(LCD_ENTRYMODESET | dpMode);
|
|
}
|
|
|
|
void HD44780_RightToLeft(void)
|
|
{
|
|
dpMode &= ~LCD_ENTRYLEFT;
|
|
SendCommand(LCD_ENTRYMODESET | dpMode);
|
|
}
|
|
|
|
void HD44780_AutoScroll(void)
|
|
{
|
|
dpMode |= LCD_ENTRYSHIFTINCREMENT;
|
|
SendCommand(LCD_ENTRYMODESET | dpMode);
|
|
}
|
|
|
|
void HD44780_NoAutoScroll(void)
|
|
{
|
|
dpMode &= ~LCD_ENTRYSHIFTINCREMENT;
|
|
SendCommand(LCD_ENTRYMODESET | dpMode);
|
|
}
|
|
|
|
void HD44780_CreateSpecialChar(uint8_t location, uint8_t charmap[])
|
|
{
|
|
location &= 0x7;
|
|
SendCommand(LCD_SETCGRAMADDR | (location << 3));
|
|
for (int i=0; i<8; i++)
|
|
{
|
|
SendChar(charmap[i]);
|
|
}
|
|
}
|
|
|
|
void HD44780_PrintSpecialChar(uint8_t index)
|
|
{
|
|
SendChar(index);
|
|
}
|
|
|
|
void HD44780_LoadCustomCharacter(uint8_t char_num, uint8_t *rows)
|
|
{
|
|
HD44780_CreateSpecialChar(char_num, rows);
|
|
}
|
|
|
|
void HD44780_PrintStr(const char c[])
|
|
{
|
|
while(*c) SendChar(*c++);
|
|
}
|
|
|
|
void HD44780_SetBacklight(uint8_t new_val)
|
|
{
|
|
if(new_val) HD44780_Backlight();
|
|
else HD44780_NoBacklight();
|
|
}
|
|
|
|
void HD44780_NoBacklight(void)
|
|
{
|
|
dpBacklight=LCD_NOBACKLIGHT;
|
|
ExpanderWrite(0);
|
|
}
|
|
|
|
void HD44780_Backlight(void)
|
|
{
|
|
dpBacklight=LCD_BACKLIGHT;
|
|
ExpanderWrite(0);
|
|
}
|
|
|
|
static void SendCommand(uint8_t cmd)
|
|
{
|
|
Send(cmd, 0);
|
|
}
|
|
|
|
static void SendChar(uint8_t ch)
|
|
{
|
|
Send(ch, RS);
|
|
}
|
|
|
|
static void Send(uint8_t value, uint8_t mode)
|
|
{
|
|
uint8_t highnib = value & 0xF0;
|
|
uint8_t lownib = (value<<4) & 0xF0;
|
|
Write4Bits((highnib)|mode);
|
|
Write4Bits((lownib)|mode);
|
|
}
|
|
|
|
static void Write4Bits(uint8_t value)
|
|
{
|
|
ExpanderWrite(value);
|
|
PulseEnable(value);
|
|
}
|
|
|
|
static void ExpanderWrite(uint8_t _data)
|
|
{
|
|
uint8_t data = _data | dpBacklight;
|
|
HAL_I2C_Master_Transmit(&hi2c1, DEVICE_ADDR, (uint8_t*)&data, 1, 10);
|
|
}
|
|
|
|
static void PulseEnable(uint8_t _data)
|
|
{
|
|
ExpanderWrite(_data | ENABLE);
|
|
DelayUS(20);
|
|
|
|
ExpanderWrite(_data & ~ENABLE);
|
|
DelayUS(20);
|
|
}
|
|
|
|
static void DelayInit(void)
|
|
{
|
|
CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
|
|
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
|
|
|
DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; //~0x00000001;
|
|
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; //0x00000001;
|
|
|
|
DWT->CYCCNT = 0;
|
|
|
|
/* 3 NO OPERATION instructions */
|
|
__ASM volatile ("NOP");
|
|
__ASM volatile ("NOP");
|
|
__ASM volatile ("NOP");
|
|
}
|
|
|
|
static void DelayUS(uint32_t us) {
|
|
uint32_t cycles = (SystemCoreClock/1000000L)*us;
|
|
uint32_t start = DWT->CYCCNT;
|
|
volatile uint32_t cnt;
|
|
|
|
do
|
|
{
|
|
cnt = DWT->CYCCNT - start;
|
|
} while(cnt < cycles);
|
|
}
|