implement I²C modes/calls
This commit is contained in:
parent
d3b5533f57
commit
1e446cbb0b
81
main.c
81
main.c
|
@ -52,10 +52,26 @@
|
||||||
// the I²C address of this slave
|
// the I²C address of this slave
|
||||||
#define I2C_ADDR 0x28
|
#define I2C_ADDR 0x28
|
||||||
|
|
||||||
|
// the functions we can call over I²C
|
||||||
enum i2c_mode_t {
|
enum i2c_mode_t {
|
||||||
MODE_INSTRUCTION, // read/write instruction/command
|
// custom modes
|
||||||
MODE_DATA, // read/write data
|
MODE_CLEAR_DISPLAY, // clear display
|
||||||
MODE_PORT, // read/write
|
MODE_LINE1, // write to line 1
|
||||||
|
MODE_LINE2, // write to line 2
|
||||||
|
MODE_DISPLAY_ON, // turn display on
|
||||||
|
MODE_DISPLAY_OFF, // turn display off
|
||||||
|
MODE_BRIGHTNESS, // set backlight brightness
|
||||||
|
|
||||||
|
// raw instructions, directly mapping to HD44780
|
||||||
|
MODE_DISPLAY,
|
||||||
|
MODE_RETURN_HOME,
|
||||||
|
MODE_ENTRY_MODE_SET,
|
||||||
|
MODE_CURSOR_DISPLAY_SHIFT,
|
||||||
|
MODE_FUNCTION_SET,
|
||||||
|
MODE_CGRAM_ADDR,
|
||||||
|
MODE_DDRAM_ADDR,
|
||||||
|
MODE_DATA,
|
||||||
|
|
||||||
MODE_COUNT, // number of modes
|
MODE_COUNT, // number of modes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -269,7 +285,7 @@ void main(void)
|
||||||
wait_10us(4 + 1); // wait 37 us (BF could be checked at this point)
|
wait_10us(4 + 1); // wait 37 us (BF could be checked at this point)
|
||||||
// we are now for sure in 8-bit more (and could switch do 4-bit). 8-bit mode is actually the default after power up
|
// we are now for sure in 8-bit more (and could switch do 4-bit). 8-bit mode is actually the default after power up
|
||||||
IWDG_KR = IWDG_KR_KEY_REFRESH; // reset watchdog
|
IWDG_KR = IWDG_KR_KEY_REFRESH; // reset watchdog
|
||||||
hd44780_write_instruction(0x20); // function set: 4-bit mode
|
hd44780_write_instruction(0x28); // function set (DL=1: 4-bit mode, N=1: 2 lines, F=0: 5x8 dots)
|
||||||
hd44780_write_instruction(0x08); // display off
|
hd44780_write_instruction(0x08); // display off
|
||||||
hd44780_write_instruction(0x01); // display clear
|
hd44780_write_instruction(0x01); // display clear
|
||||||
hd44780_write_instruction(0x06); // entry mode set
|
hd44780_write_instruction(0x06); // entry mode set
|
||||||
|
@ -289,26 +305,63 @@ void main(void)
|
||||||
if (i2c_input_new) { // this is the start of a transaction, the first byte indicates the mode to be used
|
if (i2c_input_new) { // this is the start of a transaction, the first byte indicates the mode to be used
|
||||||
i2c_mode = input_data; // set user provided mode (no need to check since the undefined modes don't do anything)
|
i2c_mode = input_data; // set user provided mode (no need to check since the undefined modes don't do anything)
|
||||||
i2c_input_new = false; // clear flag
|
i2c_input_new = false; // clear flag
|
||||||
|
// process mode switch
|
||||||
|
switch (i2c_mode) {
|
||||||
|
case MODE_CLEAR_DISPLAY: // clear display
|
||||||
|
hd44780_write_instruction(0x01); // clear display instruction
|
||||||
|
break;
|
||||||
|
case MODE_LINE1:
|
||||||
|
hd44780_write_instruction(0x80); // set DDRAM address to 0 (line 1)
|
||||||
|
break;
|
||||||
|
case MODE_LINE2:
|
||||||
|
hd44780_write_instruction(0xc0); // set DDRAM address to 0x40 (line 2)
|
||||||
|
break;
|
||||||
|
case MODE_DISPLAY_ON:
|
||||||
|
hd44780_write_instruction(0x0c); // display on
|
||||||
|
break;
|
||||||
|
case MODE_DISPLAY_OFF:
|
||||||
|
hd44780_write_instruction(0x08); // display off
|
||||||
|
break;
|
||||||
|
case MODE_RETURN_HOME:
|
||||||
|
hd44780_write_instruction(0x02); // return home
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break; // waiting for data
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// process data
|
// process data
|
||||||
// note set RS at every byte since read busy always switches it to instruction
|
// note set RS at every byte since read busy always switches it to instruction
|
||||||
switch (i2c_mode) {
|
switch (i2c_mode) {
|
||||||
case MODE_PORT:
|
case MODE_LINE1:
|
||||||
|
case MODE_LINE2:
|
||||||
|
case MODE_DATA:
|
||||||
|
hd44780_write_data(input_data);
|
||||||
|
break;
|
||||||
|
case MODE_ENTRY_MODE_SET:
|
||||||
|
hd44780_write_instruction(0x04 | (input_data & 0x3));
|
||||||
|
break;
|
||||||
|
case MODE_DISPLAY:
|
||||||
|
hd44780_write_instruction(0x08 | (input_data & 0x7));
|
||||||
|
break;
|
||||||
|
case MODE_CURSOR_DISPLAY_SHIFT:
|
||||||
|
hd44780_write_instruction(0x10 | (input_data & 0xc));
|
||||||
|
break;
|
||||||
|
case MODE_FUNCTION_SET:
|
||||||
|
hd44780_write_instruction(0x20 | (input_data & 0xc)); // keep DL=0 4-bit mode
|
||||||
|
break;
|
||||||
|
case MODE_CGRAM_ADDR:
|
||||||
|
hd44780_write_instruction(0x40 | (input_data & 0x3f));
|
||||||
|
break;
|
||||||
|
case MODE_DDRAM_ADDR:
|
||||||
|
hd44780_write_instruction(0x80 | (input_data & 0x3f));
|
||||||
|
break;
|
||||||
|
case MODE_BRIGHTNESS:
|
||||||
if (input_data) {
|
if (input_data) {
|
||||||
led_on();
|
led_on();
|
||||||
} else {
|
} else {
|
||||||
led_off();
|
led_off();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MODE_INSTRUCTION:
|
|
||||||
if (0x20 == (input_data & 0x20)) { // function set instruction
|
|
||||||
input_data &= ~(1 << 4); // ensure we stay in 4-bit mode
|
|
||||||
}
|
|
||||||
hd44780_write_instruction(input_data);
|
|
||||||
break;
|
|
||||||
case MODE_DATA:
|
|
||||||
hd44780_write_data(input_data);
|
|
||||||
break;
|
|
||||||
default: // read values do not make sense
|
default: // read values do not make sense
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue