Moved LCD control code to separate module
This commit is contained in:
parent
0d98607a0a
commit
c56e00a084
256
src/lcd.c
Normal file
256
src/lcd.c
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
#include <libopencm3/stm32/gpio.h>
|
||||||
|
|
||||||
|
#include "lcd.h"
|
||||||
|
|
||||||
|
#define LCD_USE_4BIT_MODE 1
|
||||||
|
|
||||||
|
#define LCD_PORT GPIOA
|
||||||
|
#define LCD_E GPIO10
|
||||||
|
#define LCD_RW GPIO11
|
||||||
|
#define LCD_RS GPIO12
|
||||||
|
#define LCD_D4 GPIO4
|
||||||
|
#define LCD_D5 GPIO5
|
||||||
|
#define LCD_D6 GPIO6
|
||||||
|
#define LCD_D7 GPIO7
|
||||||
|
|
||||||
|
struct LCDCommand {
|
||||||
|
uint8_t data;
|
||||||
|
enum LCDRegType reg_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LCD_QUEUE_LEN 64
|
||||||
|
struct LCDCommand lcd_cmd_buffer[LCD_QUEUE_LEN];
|
||||||
|
uint16_t lcd_buf_read_pos, lcd_buf_write_pos;
|
||||||
|
|
||||||
|
uint8_t lcd_init_sequence_idx = 0;
|
||||||
|
|
||||||
|
static inline void busy_wait(uint32_t cycles)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < cycles; i++) {
|
||||||
|
__asm__("nop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LCD_USE_4BIT_MODE
|
||||||
|
/*
|
||||||
|
* Send 4 bits to the LCD. Only use directly during initialization.
|
||||||
|
*
|
||||||
|
* The display samples data on the falling edge of E.
|
||||||
|
*
|
||||||
|
* \param data lower nibble contains the data to send
|
||||||
|
*/
|
||||||
|
static void lcd_send_4bit(uint8_t data, enum LCDRegType reg_type)
|
||||||
|
{
|
||||||
|
uint8_t gpios2set = 0, gpios2clear = 0;
|
||||||
|
|
||||||
|
// set E high (rising edge has no effect)
|
||||||
|
gpio_set(LCD_PORT, LCD_E);
|
||||||
|
|
||||||
|
if(reg_type == LCD_REG_CONTROL) {
|
||||||
|
gpio_clear(LCD_PORT, LCD_RS);
|
||||||
|
} else { // LCD_REG_DATA
|
||||||
|
gpio_set(LCD_PORT, LCD_RS);
|
||||||
|
}
|
||||||
|
|
||||||
|
busy_wait(100);
|
||||||
|
|
||||||
|
// calculate target gpio states
|
||||||
|
if(data & (1 << 0)) { gpios2set |= LCD_D4; } else { gpios2clear |= LCD_D4; }
|
||||||
|
if(data & (1 << 1)) { gpios2set |= LCD_D5; } else { gpios2clear |= LCD_D5; }
|
||||||
|
if(data & (1 << 2)) { gpios2set |= LCD_D6; } else { gpios2clear |= LCD_D6; }
|
||||||
|
if(data & (1 << 3)) { gpios2set |= LCD_D7; } else { gpios2clear |= LCD_D7; }
|
||||||
|
|
||||||
|
// apply data pins
|
||||||
|
gpio_set(LCD_PORT, gpios2set);
|
||||||
|
gpio_clear(LCD_PORT, gpios2clear);
|
||||||
|
|
||||||
|
busy_wait(100);
|
||||||
|
|
||||||
|
// set E low (display samples on falling edge)
|
||||||
|
gpio_clear(LCD_PORT, LCD_E);
|
||||||
|
|
||||||
|
busy_wait(100);
|
||||||
|
}
|
||||||
|
#else /* !LCD_USE_4BIT_MODE */
|
||||||
|
static void lcd_send_8bit(uint8_t data, enum LCDRegType reg_type)
|
||||||
|
{
|
||||||
|
uint32_t gpios2set = 0, gpios2clear = 0;
|
||||||
|
|
||||||
|
// set E high (rising edge has no effect)
|
||||||
|
gpio_set(LCD_PORT, LCD_E);
|
||||||
|
|
||||||
|
if(reg_type == LCD_REG_CONTROL) {
|
||||||
|
gpio_clear(LCD_PORT, LCD_RS);
|
||||||
|
} else { // LCD_REG_DATA
|
||||||
|
gpio_set(LCD_PORT, LCD_RS);
|
||||||
|
}
|
||||||
|
|
||||||
|
busy_wait(100);
|
||||||
|
|
||||||
|
// calculate target gpio states
|
||||||
|
if(data & (1 << 0)) { gpios2set |= LCD_D0; } else { gpios2clear |= LCD_D0; }
|
||||||
|
if(data & (1 << 1)) { gpios2set |= LCD_D1; } else { gpios2clear |= LCD_D1; }
|
||||||
|
if(data & (1 << 2)) { gpios2set |= LCD_D2; } else { gpios2clear |= LCD_D2; }
|
||||||
|
if(data & (1 << 3)) { gpios2set |= LCD_D3; } else { gpios2clear |= LCD_D3; }
|
||||||
|
if(data & (1 << 4)) { gpios2set |= LCD_D4; } else { gpios2clear |= LCD_D4; }
|
||||||
|
if(data & (1 << 5)) { gpios2set |= LCD_D5; } else { gpios2clear |= LCD_D5; }
|
||||||
|
if(data & (1 << 6)) { gpios2set |= LCD_D6; } else { gpios2clear |= LCD_D6; }
|
||||||
|
if(data & (1 << 7)) { gpios2set |= LCD_D7; } else { gpios2clear |= LCD_D7; }
|
||||||
|
|
||||||
|
// apply data pins
|
||||||
|
gpio_set(LCD_PORT, gpios2set);
|
||||||
|
gpio_clear(LCD_PORT, gpios2clear);
|
||||||
|
|
||||||
|
busy_wait(100);
|
||||||
|
|
||||||
|
// set E low (display samples on falling edge)
|
||||||
|
gpio_clear(LCD_PORT, LCD_E);
|
||||||
|
|
||||||
|
busy_wait(100);
|
||||||
|
}
|
||||||
|
#endif /* LCD_USE_4BIT_MODE */
|
||||||
|
|
||||||
|
void lcd_send_init(uint8_t data, enum LCDRegType reg_type)
|
||||||
|
{
|
||||||
|
#if LCD_USE_4BIT_MODE
|
||||||
|
lcd_send_4bit((data >> 4) & 0x0F, reg_type);
|
||||||
|
#else
|
||||||
|
lcd_send_8bit(data, reg_type);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_init(void)
|
||||||
|
{
|
||||||
|
lcd_buf_write_pos = 0;
|
||||||
|
lcd_buf_read_pos = 0;
|
||||||
|
|
||||||
|
lcd_init_sequence_idx = 0;
|
||||||
|
|
||||||
|
// Set up GPIOs. RCC setup must be done externally!
|
||||||
|
gpio_mode_setup(LCD_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,
|
||||||
|
LCD_E | LCD_RW | LCD_RS | LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_send(uint8_t data, enum LCDRegType reg_type)
|
||||||
|
{
|
||||||
|
#if LCD_USE_4BIT_MODE
|
||||||
|
lcd_send_4bit((data >> 4) & 0x0F, reg_type);
|
||||||
|
lcd_send_4bit((data >> 0) & 0x0F, reg_type);
|
||||||
|
#else
|
||||||
|
lcd_send_8bit(data, reg_type);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Send next command from the queue.
|
||||||
|
*/
|
||||||
|
int lcd_process(void)
|
||||||
|
{
|
||||||
|
if(lcd_buf_read_pos != lcd_buf_write_pos) {
|
||||||
|
lcd_send(lcd_cmd_buffer[lcd_buf_read_pos].data,
|
||||||
|
lcd_cmd_buffer[lcd_buf_read_pos].reg_type);
|
||||||
|
|
||||||
|
lcd_buf_read_pos++;
|
||||||
|
if(lcd_buf_read_pos >= LCD_QUEUE_LEN) {
|
||||||
|
lcd_buf_read_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // success
|
||||||
|
} else {
|
||||||
|
return -1; // queue empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcd_enqueue(uint8_t data, enum LCDRegType reg_type)
|
||||||
|
{
|
||||||
|
uint16_t tmp_pos = lcd_buf_write_pos + 1;
|
||||||
|
if(tmp_pos >= LCD_QUEUE_LEN) {
|
||||||
|
tmp_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tmp_pos != lcd_buf_read_pos) {
|
||||||
|
lcd_cmd_buffer[tmp_pos].data = data;
|
||||||
|
lcd_cmd_buffer[tmp_pos].reg_type = reg_type;
|
||||||
|
|
||||||
|
lcd_buf_write_pos = tmp_pos;
|
||||||
|
|
||||||
|
return 0; // success
|
||||||
|
} else {
|
||||||
|
return -1; // queue full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_send_string(char *data)
|
||||||
|
{
|
||||||
|
while(*data) {
|
||||||
|
lcd_enqueue((uint8_t)(*data), LCD_REG_DATA);
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_set_cursor_pos(uint8_t line, uint8_t col)
|
||||||
|
{
|
||||||
|
lcd_enqueue(0x80 | (line << 6) | col, LCD_REG_CONTROL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called in a 1-ms cycle */
|
||||||
|
int lcd_setup(void)
|
||||||
|
{
|
||||||
|
/* Display INIT:
|
||||||
|
* Power On
|
||||||
|
* sleep(15) minimum
|
||||||
|
* send(0x30, RW = RS = 0) -> command = 0x3X
|
||||||
|
* sleep(4.1) minimum
|
||||||
|
* send(0x30, RW = RS = 0) -> command = 0x33 -> 8-bit mode
|
||||||
|
* sleep(0.1) minimum
|
||||||
|
* send(0x20, RW = RS = 0) -> command = 0x2X -> 4-bit mode active
|
||||||
|
* now write upper 4 bits and lower 4 bits afterwards
|
||||||
|
*/
|
||||||
|
if(lcd_init_sequence_idx < 38) {
|
||||||
|
// init sequence
|
||||||
|
switch(lcd_init_sequence_idx) {
|
||||||
|
case 19:
|
||||||
|
lcd_send_init(0x30, LCD_REG_CONTROL);
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
lcd_send_init(0x30, LCD_REG_CONTROL);
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
lcd_send_init(0x30, LCD_REG_CONTROL);
|
||||||
|
break;
|
||||||
|
#if LCD_USE_4BIT_MODE
|
||||||
|
case 26:
|
||||||
|
lcd_send_init(0x20, LCD_REG_CONTROL); // switch to 4-bit mode
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 27:
|
||||||
|
#if LCD_USE_4BIT_MODE
|
||||||
|
lcd_send(0x28, LCD_REG_CONTROL); // function set: 4-bit mode, 2 lines, 5x7 font
|
||||||
|
#else
|
||||||
|
lcd_send(0x38, LCD_REG_CONTROL); // function set: 8-bit mode, 2 lines, 5x7 font
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case 28:
|
||||||
|
lcd_send(0x08, LCD_REG_CONTROL); // display off
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
lcd_send(0x01, LCD_REG_CONTROL); // display clear
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
lcd_send(0x06, LCD_REG_CONTROL); // entry mode set: increment, no shift
|
||||||
|
break;
|
||||||
|
case 34:
|
||||||
|
lcd_send(0x0C, LCD_REG_CONTROL); // display on, cursor off
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
lcd_send(0x02, LCD_REG_CONTROL); // cursor home, needs 1.6 ms to execute
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd_init_sequence_idx++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
29
src/lcd.h
Normal file
29
src/lcd.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef LCD_H
|
||||||
|
#define LCD_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
enum LCDRegType {
|
||||||
|
LCD_REG_CONTROL,
|
||||||
|
LCD_REG_DATA
|
||||||
|
};
|
||||||
|
|
||||||
|
void lcd_init(void);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* This function should be called from the main loop every millisecond.
|
||||||
|
*
|
||||||
|
* \returns 1 if the initialization of the display is complete.
|
||||||
|
*/
|
||||||
|
int lcd_setup(void);
|
||||||
|
|
||||||
|
void lcd_send_init(uint8_t data, enum LCDRegType reg_type);
|
||||||
|
void lcd_send(uint8_t data, enum LCDRegType reg_type);
|
||||||
|
void lcd_send_string(char *data);
|
||||||
|
|
||||||
|
int lcd_process(void);
|
||||||
|
int lcd_enqueue(uint8_t data, enum LCDRegType reg_type);
|
||||||
|
|
||||||
|
void lcd_set_cursor_pos(uint8_t line, uint8_t col);
|
||||||
|
|
||||||
|
#endif // LCD_H
|
258
src/main.c
258
src/main.c
|
@ -9,6 +9,7 @@
|
||||||
#include <fxp.h>
|
#include <fxp.h>
|
||||||
#include <fxp_basic.h>
|
#include <fxp_basic.h>
|
||||||
|
|
||||||
|
#include "lcd.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
volatile int wait_frame = 1;
|
volatile int wait_frame = 1;
|
||||||
|
@ -16,201 +17,9 @@ volatile int wait_frame = 1;
|
||||||
#define ADC_NUM_CHANNELS 3
|
#define ADC_NUM_CHANNELS 3
|
||||||
volatile uint16_t adc_values[ADC_NUM_CHANNELS];
|
volatile uint16_t adc_values[ADC_NUM_CHANNELS];
|
||||||
|
|
||||||
#define LCD_USE_4BIT_MODE 1
|
|
||||||
|
|
||||||
#define LCD_PORT GPIOA
|
|
||||||
#define LCD_E GPIO10
|
|
||||||
#define LCD_RW GPIO11
|
|
||||||
#define LCD_RS GPIO12
|
|
||||||
#define LCD_D4 GPIO4
|
|
||||||
#define LCD_D5 GPIO5
|
|
||||||
#define LCD_D6 GPIO6
|
|
||||||
#define LCD_D7 GPIO7
|
|
||||||
|
|
||||||
enum LCDRegType {
|
|
||||||
LCD_REG_CONTROL,
|
|
||||||
LCD_REG_DATA
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LCDCommand {
|
|
||||||
uint8_t data;
|
|
||||||
enum LCDRegType reg_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LCD_QUEUE_LEN 64
|
|
||||||
struct LCDCommand lcd_cmd_buffer[LCD_QUEUE_LEN];
|
|
||||||
uint16_t lcd_buf_read_pos, lcd_buf_write_pos;
|
|
||||||
|
|
||||||
static inline void busy_wait(uint32_t cycles)
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < cycles; i++) {
|
|
||||||
__asm__("nop");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LCD_USE_4BIT_MODE
|
|
||||||
/*
|
|
||||||
* Send 4 bits to the LCD. Only use directly during initialization.
|
|
||||||
*
|
|
||||||
* The display samples data on the falling edge of E.
|
|
||||||
*
|
|
||||||
* \param data lower nibble contains the data to send
|
|
||||||
*/
|
|
||||||
static void lcd_send_4bit(uint8_t data, enum LCDRegType reg_type)
|
|
||||||
{
|
|
||||||
uint8_t gpios2set = 0, gpios2clear = 0;
|
|
||||||
|
|
||||||
// set E high (rising edge has no effect)
|
|
||||||
gpio_set(LCD_PORT, LCD_E);
|
|
||||||
|
|
||||||
if(reg_type == LCD_REG_CONTROL) {
|
|
||||||
gpio_clear(LCD_PORT, LCD_RS);
|
|
||||||
} else { // LCD_REG_DATA
|
|
||||||
gpio_set(LCD_PORT, LCD_RS);
|
|
||||||
}
|
|
||||||
|
|
||||||
busy_wait(100);
|
|
||||||
|
|
||||||
// calculate target gpio states
|
|
||||||
if(data & (1 << 0)) { gpios2set |= LCD_D4; } else { gpios2clear |= LCD_D4; }
|
|
||||||
if(data & (1 << 1)) { gpios2set |= LCD_D5; } else { gpios2clear |= LCD_D5; }
|
|
||||||
if(data & (1 << 2)) { gpios2set |= LCD_D6; } else { gpios2clear |= LCD_D6; }
|
|
||||||
if(data & (1 << 3)) { gpios2set |= LCD_D7; } else { gpios2clear |= LCD_D7; }
|
|
||||||
|
|
||||||
// apply data pins
|
|
||||||
gpio_set(LCD_PORT, gpios2set);
|
|
||||||
gpio_clear(LCD_PORT, gpios2clear);
|
|
||||||
|
|
||||||
busy_wait(100);
|
|
||||||
|
|
||||||
// set E low (display samples on falling edge)
|
|
||||||
gpio_clear(LCD_PORT, LCD_E);
|
|
||||||
|
|
||||||
busy_wait(100);
|
|
||||||
}
|
|
||||||
#else /* !LCD_USE_4BIT_MODE */
|
|
||||||
static void lcd_send_8bit(uint8_t data, enum LCDRegType reg_type)
|
|
||||||
{
|
|
||||||
uint32_t gpios2set = 0, gpios2clear = 0;
|
|
||||||
|
|
||||||
// set E high (rising edge has no effect)
|
|
||||||
gpio_set(LCD_PORT, LCD_E);
|
|
||||||
|
|
||||||
if(reg_type == LCD_REG_CONTROL) {
|
|
||||||
gpio_clear(LCD_PORT, LCD_RS);
|
|
||||||
} else { // LCD_REG_DATA
|
|
||||||
gpio_set(LCD_PORT, LCD_RS);
|
|
||||||
}
|
|
||||||
|
|
||||||
busy_wait(100);
|
|
||||||
|
|
||||||
// calculate target gpio states
|
|
||||||
if(data & (1 << 0)) { gpios2set |= LCD_D0; } else { gpios2clear |= LCD_D0; }
|
|
||||||
if(data & (1 << 1)) { gpios2set |= LCD_D1; } else { gpios2clear |= LCD_D1; }
|
|
||||||
if(data & (1 << 2)) { gpios2set |= LCD_D2; } else { gpios2clear |= LCD_D2; }
|
|
||||||
if(data & (1 << 3)) { gpios2set |= LCD_D3; } else { gpios2clear |= LCD_D3; }
|
|
||||||
if(data & (1 << 4)) { gpios2set |= LCD_D4; } else { gpios2clear |= LCD_D4; }
|
|
||||||
if(data & (1 << 5)) { gpios2set |= LCD_D5; } else { gpios2clear |= LCD_D5; }
|
|
||||||
if(data & (1 << 6)) { gpios2set |= LCD_D6; } else { gpios2clear |= LCD_D6; }
|
|
||||||
if(data & (1 << 7)) { gpios2set |= LCD_D7; } else { gpios2clear |= LCD_D7; }
|
|
||||||
|
|
||||||
// apply data pins
|
|
||||||
gpio_set(LCD_PORT, gpios2set);
|
|
||||||
gpio_clear(LCD_PORT, gpios2clear);
|
|
||||||
|
|
||||||
busy_wait(100);
|
|
||||||
|
|
||||||
// set E low (display samples on falling edge)
|
|
||||||
gpio_clear(LCD_PORT, LCD_E);
|
|
||||||
|
|
||||||
busy_wait(100);
|
|
||||||
}
|
|
||||||
#endif /* LCD_USE_4BIT_MODE */
|
|
||||||
|
|
||||||
static void lcd_send_init(uint8_t data, enum LCDRegType reg_type)
|
|
||||||
{
|
|
||||||
#if LCD_USE_4BIT_MODE
|
|
||||||
lcd_send_4bit((data >> 4) & 0x0F, reg_type);
|
|
||||||
#else
|
|
||||||
lcd_send_8bit(data, reg_type);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lcd_init(void)
|
|
||||||
{
|
|
||||||
lcd_buf_write_pos = 0;
|
|
||||||
lcd_buf_read_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lcd_send(uint8_t data, enum LCDRegType reg_type)
|
|
||||||
{
|
|
||||||
#if LCD_USE_4BIT_MODE
|
|
||||||
lcd_send_4bit((data >> 4) & 0x0F, reg_type);
|
|
||||||
lcd_send_4bit((data >> 0) & 0x0F, reg_type);
|
|
||||||
#else
|
|
||||||
lcd_send_8bit(data, reg_type);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Send next command from the queue.
|
|
||||||
*/
|
|
||||||
static int lcd_process(void)
|
|
||||||
{
|
|
||||||
if(lcd_buf_read_pos != lcd_buf_write_pos) {
|
|
||||||
lcd_send(lcd_cmd_buffer[lcd_buf_read_pos].data,
|
|
||||||
lcd_cmd_buffer[lcd_buf_read_pos].reg_type);
|
|
||||||
|
|
||||||
lcd_buf_read_pos++;
|
|
||||||
if(lcd_buf_read_pos >= LCD_QUEUE_LEN) {
|
|
||||||
lcd_buf_read_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; // success
|
|
||||||
} else {
|
|
||||||
return -1; // queue empty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int lcd_enqueue(uint8_t data, enum LCDRegType reg_type)
|
|
||||||
{
|
|
||||||
uint16_t tmp_pos = lcd_buf_write_pos + 1;
|
|
||||||
if(tmp_pos >= LCD_QUEUE_LEN) {
|
|
||||||
tmp_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tmp_pos != lcd_buf_read_pos) {
|
|
||||||
lcd_cmd_buffer[tmp_pos].data = data;
|
|
||||||
lcd_cmd_buffer[tmp_pos].reg_type = reg_type;
|
|
||||||
|
|
||||||
lcd_buf_write_pos = tmp_pos;
|
|
||||||
|
|
||||||
return 0; // success
|
|
||||||
} else {
|
|
||||||
return -1; // queue full
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lcd_send_string(char *data)
|
|
||||||
{
|
|
||||||
while(*data) {
|
|
||||||
lcd_enqueue((uint8_t)(*data), LCD_REG_DATA);
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lcd_set_cursor_pos(uint8_t line, uint8_t col)
|
|
||||||
{
|
|
||||||
lcd_enqueue(0x80 | (line << 6) | col, LCD_REG_CONTROL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void init_gpio(void)
|
static void init_gpio(void)
|
||||||
{
|
{
|
||||||
// Display GPIOs
|
|
||||||
gpio_mode_setup(LCD_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,
|
|
||||||
LCD_E | LCD_RW | LCD_RS | LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7);
|
|
||||||
|
|
||||||
// Set up UART TX on PB6 for debugging
|
// Set up UART TX on PB6 for debugging
|
||||||
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO6);
|
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO6);
|
||||||
gpio_set_af(GPIOB, GPIO_AF0, GPIO6);
|
gpio_set_af(GPIOB, GPIO_AF0, GPIO6);
|
||||||
|
@ -225,10 +34,10 @@ static void init_clock(void)
|
||||||
rcc_clock_setup_in_hsi_out_48mhz();
|
rcc_clock_setup_in_hsi_out_48mhz();
|
||||||
|
|
||||||
// enable GPIO clocks:
|
// enable GPIO clocks:
|
||||||
// Port B is needed for debugging
|
// Port A is needed for the Display and more
|
||||||
rcc_periph_clock_enable(RCC_GPIOA);
|
rcc_periph_clock_enable(RCC_GPIOA);
|
||||||
|
|
||||||
// Port A is needed for the Display and more
|
// Port B is needed for debugging
|
||||||
rcc_periph_clock_enable(RCC_GPIOB);
|
rcc_periph_clock_enable(RCC_GPIOB);
|
||||||
|
|
||||||
// enable TIM3 for scheduling
|
// enable TIM3 for scheduling
|
||||||
|
@ -545,62 +354,7 @@ int main(void)
|
||||||
sentSomething = 0;
|
sentSomething = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display INIT:
|
if(lcd_setup()) {
|
||||||
* Power On
|
|
||||||
* sleep(15) minimum
|
|
||||||
* send(0x30, RW = RS = 0) -> command = 0x3X
|
|
||||||
* sleep(4.1) minimum
|
|
||||||
* send(0x30, RW = RS = 0) -> command = 0x33 -> 8-bit mode
|
|
||||||
* sleep(0.1) minimum
|
|
||||||
* send(0x20, RW = RS = 0) -> command = 0x2X -> 4-bit mode active
|
|
||||||
* now write upper 4 bits and lower 4 bits afterwards
|
|
||||||
*/
|
|
||||||
if(timebase_ms < 50) {
|
|
||||||
// init sequence
|
|
||||||
switch(timebase_ms) {
|
|
||||||
case 19:
|
|
||||||
lcd_send_init(0x30, LCD_REG_CONTROL);
|
|
||||||
break;
|
|
||||||
case 24:
|
|
||||||
lcd_send_init(0x30, LCD_REG_CONTROL);
|
|
||||||
break;
|
|
||||||
case 25:
|
|
||||||
lcd_send_init(0x30, LCD_REG_CONTROL);
|
|
||||||
break;
|
|
||||||
#if LCD_USE_4BIT_MODE
|
|
||||||
case 26:
|
|
||||||
lcd_send_init(0x20, LCD_REG_CONTROL); // switch to 4-bit mode
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 27:
|
|
||||||
#if LCD_USE_4BIT_MODE
|
|
||||||
lcd_send(0x28, LCD_REG_CONTROL); // function set: 4-bit mode, 2 lines, 5x7 font
|
|
||||||
#else
|
|
||||||
lcd_send(0x38, LCD_REG_CONTROL); // function set: 8-bit mode, 2 lines, 5x7 font
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 28:
|
|
||||||
lcd_send(0x08, LCD_REG_CONTROL); // display off
|
|
||||||
break;
|
|
||||||
case 30:
|
|
||||||
lcd_send(0x01, LCD_REG_CONTROL); // display clear
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
lcd_send(0x06, LCD_REG_CONTROL); // entry mode set: increment, no shift
|
|
||||||
break;
|
|
||||||
case 34:
|
|
||||||
lcd_send(0x0C, LCD_REG_CONTROL); // display on, cursor off
|
|
||||||
break;
|
|
||||||
case 31:
|
|
||||||
lcd_send(0x02, LCD_REG_CONTROL); // cursor home, needs 1.6 ms to execute
|
|
||||||
break;
|
|
||||||
case 49:
|
|
||||||
lcd_send_string("L:");
|
|
||||||
lcd_set_cursor_pos(1, 0);
|
|
||||||
lcd_send_string("Hello World!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lcd_process();
|
lcd_process();
|
||||||
|
|
||||||
if((timebase_ms % 500) == 0) {
|
if((timebase_ms % 500) == 0) {
|
||||||
|
@ -635,11 +389,11 @@ int main(void)
|
||||||
if((timebase_ms % 1000) == 10) {
|
if((timebase_ms % 1000) == 10) {
|
||||||
cpuload /= 1000;
|
cpuload /= 1000;
|
||||||
|
|
||||||
lcd_set_cursor_pos(0, 2);
|
lcd_set_cursor_pos(0, 0);
|
||||||
|
|
||||||
fxp_format_int((int32_t)cpuload, number);
|
fxp_format_int((int32_t)cpuload, number);
|
||||||
fxp_right_align(number, msg, 3, '0');
|
fxp_right_align(number, msg, 3, '0');
|
||||||
lcd_send_string("0.");
|
lcd_send_string("L:0.");
|
||||||
lcd_send_string(msg);
|
lcd_send_string(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue