talon/User/lcd.c

146 lines
3.5 KiB
C
Raw Permalink Normal View History

2024-02-10 16:16:29 -05:00
#include "lcd.h"
#include "ch32v20x.h"
void lcd_begin(lcd_t *lcd);
void lcd_expander_write(lcd_t *lcd, uint8_t data);
void lcd_write4bits(lcd_t *lcd, uint8_t value);
void lcd_command(lcd_t *lcd, uint8_t cmd);
void lcd_init(lcd_t *lcd, u8 address) {
lcd->address = address;
lcd->backlight = 0;
// Enable I2C1 and GPIOB
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
// Set up GPIO on port B
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
// SCL - PB8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// SDA - PB9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_DeInit(I2C1);
I2C_InitTypeDef I2C_InitStructure;
I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
lcd_begin(lcd);
}
void lcd_begin(lcd_t *lcd) {
lcd->backlight = LCD_BACKLIGHT;
Delay_Ms(50);
lcd_expander_write(lcd, 0);
Delay_Ms(1000);
lcd_write4bits(lcd, 0x03 << 4);
Delay_Us(4500);
lcd_write4bits(lcd, 0x03 << 4);
Delay_Us(4500);
lcd_write4bits(lcd, 0x03 << 4);
Delay_Us(150);
lcd_write4bits(lcd, 0x02 << 4);
lcd->function = LCD_4BITMODE | LCD_2LINE;
lcd_command(lcd, LCD_FUNCTIONSET | lcd->function);
lcd->dispctrl = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
lcd_command(lcd, LCD_DISPLAYCONTROL | lcd->dispctrl);
lcd->entrymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDEC;
lcd_command(lcd, LCD_ENTRYMODESET | lcd->entrymode);
lcd_clear(lcd);
lcd_home(lcd);
}
void lcd_backlight(lcd_t *lcd) {
lcd->backlight = LCD_BACKLIGHT;
lcd_expander_write(lcd, 0);
}
void lcd_no_backlight(lcd_t *lcd) {
lcd->backlight = LCD_NOBACKLIGHT;
lcd_expander_write(lcd, 0);
}
void lcd_clear(lcd_t *lcd) {
lcd_command(lcd, LCD_CLEARDISPLAY);
Delay_Us(2000);
}
void lcd_home(lcd_t *lcd) {
lcd_command(lcd, LCD_RETURNHOME);
Delay_Us(2000);
}
void lcd_cursor(lcd_t *lcd, uint8_t col, uint8_t row) {
uint8_t row_offsets[] = {0x00, 0x40, 0x14, 0x54};
lcd_command(lcd, LCD_SETDDRAMADDR | (col + row_offsets[row]));
}
void lcd_expander_write(lcd_t *lcd, uint8_t data) {
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET);
I2C_GenerateSTART(I2C1, ENABLE);
// Delay_Ms(1);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
// I2C_Send7bitAddress(I2C1, 0x4E, I2C_Direction_Receiver);
I2C_SendData(I2C1, lcd->address << 1);
// Delay_Ms(1);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
// I2C_SendData(I2C1, 0x27);
// while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, data | lcd->backlight);
// Delay_Ms(1);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
// Delay_Ms(1);
}
void lcd_write4bits(lcd_t *lcd, uint8_t value) {
lcd_expander_write(lcd, value);
lcd_expander_write(lcd, value | LCD_EN);
Delay_Us(1);
lcd_expander_write(lcd, value & ~LCD_EN);
Delay_Us(50);
}
void lcd_command(lcd_t *lcd, uint8_t cmd) {
lcd_write4bits(lcd, cmd & 0xF0);
lcd_write4bits(lcd, cmd << 4);
}
void lcd_write(lcd_t *lcd, char c) {
lcd_write4bits(lcd, (c & 0xF0) | LCD_RS);
lcd_write4bits(lcd, (c << 4) | LCD_RS);
}
void lcd_puts(lcd_t *lcd, char *str) {
while(*str)
lcd_write(lcd, *str++);
}