Skip to content

Commit 761ee07

Browse files
committed
B1.6: add support for SPI display
1 parent b1b0bc0 commit 761ee07

File tree

3 files changed

+106
-32
lines changed

3 files changed

+106
-32
lines changed

src/board_8258_03mmc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ extern "C" {
4040
#define DEBUG_INFO_TX_PIN GPIO_SWS //print
4141
#endif
4242

43+
/* Possible pins for different LCD options */
44+
#define LCD_UART_TX_PIN UART_TX_PD7
45+
#define LCD_UART_RX_PIN UART_RX_PD6
46+
#define LCD_SPI_SCK_PIN UART_TX_PD7
47+
#define LCD_SPI_SDO_PIN UART_RX_PD6
4348

4449
enum{
4550
VK_SW1 = 0x01,

src/lcd.c

Lines changed: 91 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -62,32 +62,52 @@ _attribute_data_retention_ u8 lcd_version;
6262
_attribute_data_retention_ u8 i2c_address_lcd = 0x78; // B1.4 uses Address 0x78 and B1.9 uses 0x7c
6363

6464

65+
static u8 check_is_uart() {
66+
u8 ret = 0;
67+
u32 cur_time = clock_time();
68+
do
69+
{
70+
if(reg_uart_buf_cnt & FLD_UART_RX_BUF_CNT) {
71+
ret = reg_uart_data_buf0;
72+
break;
73+
}
74+
} while(!clock_time_exceed(cur_time, 512));
75+
return ret == 0xAA;
76+
}
77+
6578
void init_lcd(bool clear){
6679

80+
u8 lcd_is_uart = 0;
81+
6782
if(test_i2c_device(0x3C)){// B1.4
68-
lcd_version = 0;
83+
lcd_version = LCD_I2C_3C;
6984
i2c_address_lcd = 0x78;
7085
}else if(test_i2c_device(0x3E)){// B1.9
71-
lcd_version = 2;
86+
lcd_version = LCD_I2C_3E;
7287
i2c_address_lcd = 0x7C;
7388
}else{// B1.6 uses UART and is not testable this way
74-
// UART 38400 BAUD
75-
lcd_version = 1;
89+
// B1.6 has two revisions: just TX and SPI connected
90+
// UART 38400 BAUD
91+
lcd_version = LCD_UART; // or LCD_SPI, check later
7692
}
7793

78-
if(lcd_version == 0){// B1.4 Hardware
94+
if(lcd_version == LCD_I2C_3C){// B1.4 Hardware
7995
gpio_set_func(GPIO_PB6, AS_GPIO);//LCD on low temp needs this, its an unknown pin going to the LCD controller chip
8096
gpio_set_output_en(GPIO_PB6, 0);
8197
gpio_set_input_en(GPIO_PB6, 1);
8298
gpio_setup_up_down_resistor(GPIO_PB6, PM_PIN_PULLUP_10K);
8399
sleep_us(50000);
84100
send_i2c(i2c_address_lcd, lcd_3C_init_cmd, sizeof(lcd_3C_init_cmd));
85101

86-
}else if(lcd_version == 1){// B1.6 Hardware
102+
}else if(lcd_version == LCD_UART){// B1.6 Hardware
87103

88104
init_lcd_deepsleep();
105+
lcd_is_uart = check_is_uart();
106+
if (!lcd_is_uart){
107+
lcd_version = LCD_SPI;
108+
}
89109

90-
}else if(lcd_version == 2){// B1.9 Hardware
110+
}else if(lcd_version == LCD_I2C_3E){// B1.9 Hardware
91111

92112
send_i2c(i2c_address_lcd,lcd_3E_init_cmd, sizeof(lcd_3E_init_cmd));
93113
send_i2c(i2c_address_lcd,lcd_3E_init_cmd, sizeof(lcd_3E_init_cmd));
@@ -98,21 +118,25 @@ void init_lcd(bool clear){
98118
}
99119

100120
void init_lcd_deepsleep(){
101-
if(lcd_version == 0){// B1.4 Hardware
121+
if(lcd_version == LCD_I2C_3C){// B1.4 Hardware
102122
gpio_set_func(GPIO_PB6, AS_GPIO);//LCD on low temp needs this, its an unknown pin going to the LCD controller chip
103123
gpio_set_output_en(GPIO_PB6, 0);
104124
gpio_set_input_en(GPIO_PB6, 1);
105125
gpio_setup_up_down_resistor(GPIO_PB6, PM_PIN_PULLUP_10K);
106-
}
107-
else if(lcd_version == 1) {
108-
drv_uart_pin_set(UART_TX_PD7, UART_RX_PB0);
126+
}
127+
else if(lcd_version == LCD_UART) {
128+
drv_uart_pin_set(LCD_UART_TX_PIN, LCD_UART_RX_PIN);
109129
uart_reset();
110130
uart_init_baudrate(LCD_UART_BAUD, UART_CLOCK_SOURCE, PARITY_NONE, STOP_BIT_ONE);
111131
uart_dma_enable(0, 0);
112132
dma_chn_irq_enable(0, 0);
113133
uart_irq_enable(0,0);
114134
uart_ndma_irq_triglevel(0,0);
115135
}
136+
else if (lcd_version == LCD_SPI) {
137+
gpio_set_func(LCD_SPI_SCK_PIN, AS_GPIO);
138+
gpio_set_func(LCD_SPI_SDO_PIN, AS_GPIO);
139+
}
116140

117141
}
118142

@@ -127,6 +151,37 @@ void uart_send_lcd(u8 byte1, u8 byte2, u8 byte3, u8 byte4, u8 byte5, u8 byte6){
127151
};
128152
}
129153

154+
155+
static void lcd_send_spi_byte(u8 b) {
156+
u32 x = b;
157+
for(int i = 0; i < 8; i++) {
158+
drv_gpio_write(LCD_SPI_SCK_PIN, 0);
159+
drv_gpio_write(LCD_SPI_SDO_PIN, x & 1); // MOSI
160+
sleep_us(CLK_DELAY_US);
161+
162+
drv_gpio_write(LCD_SPI_SCK_PIN, 1);
163+
sleep_us(CLK_DELAY_US);
164+
x >>= 1;
165+
}
166+
sleep_us(CLK_DELAY_US);
167+
}
168+
169+
170+
_attribute_ram_code_
171+
static void spi_send_lcd(u8 byte1, u8 byte2, u8 byte3, u8 byte4, u8 byte5, u8 byte6) {
172+
gpio_set_output_en(LCD_SPI_SCK_PIN, 1); // CLK output enable
173+
gpio_set_output_en(LCD_SPI_SDO_PIN, 1); // SDI output enable
174+
175+
unsigned char r = irq_disable();
176+
u8 trans_buff[9] = {0xAA,byte6,byte5,byte4,byte3,byte2,byte1,(byte1 ^byte2 ^byte3 ^byte4 ^byte5 ^byte6),0x55};
177+
178+
for (int i = 0; i < sizeof(trans_buff); i++) {
179+
lcd_send_spi_byte(trans_buff[i]);
180+
}
181+
irq_restore(r);
182+
}
183+
184+
130185
u8 reverse(u8 revByte) {
131186
revByte = (revByte & 0xF0) >> 4 | (revByte & 0x0F) << 4;
132187
revByte = (revByte & 0xCC) >> 2 | (revByte & 0x33) << 2;
@@ -135,27 +190,31 @@ u8 reverse(u8 revByte) {
135190
}
136191

137192
void send_to_lcd_long(u8 byte1, u8 byte2, u8 byte3, u8 byte4, u8 byte5, u8 byte6){
138-
if(lcd_version == 0){// B1.4 Hardware
139-
u8 lcd_set_segments[] = {0x80,0x40,0xC0,byte1,0xC0,byte2,0xC0,byte3,0xC0,byte4,0xC0,byte5,0xC0,byte6,0xC0,0x00,0xC0,0x00};
140-
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
141-
}else if(lcd_version == 1){// B1.6 Hardware
142-
uart_send_lcd(byte1,byte2,byte3,byte4,byte5,byte6);
143-
}else if(lcd_version == 2){// B1.9 Hardware
144-
u8 lcd_set_segments[] = {0x04,reverse(byte1),reverse(byte2),0x00,0x00,reverse(byte3),reverse(byte4),0x00,0x00,reverse(byte5),reverse(byte6), 0xc8};
145-
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
146-
}
193+
if(lcd_version == LCD_UART){// B1.6 Hardware
194+
uart_send_lcd(byte1,byte2,byte3,byte4,byte5,byte6);
195+
} else if (lcd_version == LCD_SPI){// B1.6 Hardware
196+
spi_send_lcd(byte1,byte2,byte3,byte4,byte5,byte6);
197+
} else if(lcd_version == LCD_I2C_3C){// B1.4 Hardware
198+
u8 lcd_set_segments[] = {0x80,0x40,0xC0,byte1,0xC0,byte2,0xC0,byte3,0xC0,byte4,0xC0,byte5,0xC0,byte6,0xC0,0x00,0xC0,0x00};
199+
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
200+
} else if(lcd_version == LCD_I2C_3E){// B1.9 Hardware
201+
u8 lcd_set_segments[] = {0x04,reverse(byte1),reverse(byte2),0x00,0x00,reverse(byte3),reverse(byte4),0x00,0x00,reverse(byte5),reverse(byte6), 0xc8};
202+
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
203+
}
147204
}
148205

149206
void send_to_lcd(u8 byte1, u8 byte2, u8 byte3, u8 byte4, u8 byte5, u8 byte6){
150-
if(lcd_version == 0){// B1.4 Hardware
151-
u8 lcd_set_segments[] = {0x80,0x40,0xC0,byte1,0xC0,byte2,0xC0,byte3,0xC0,byte4,0xC0,byte5,0xC0,byte6};
152-
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
153-
}else if(lcd_version == 1){// B1.6 Hardware
154-
uart_send_lcd(byte1,byte2,byte3,byte4,byte5,byte6);
155-
}else if(lcd_version == 2){// B1.9 Hardware
156-
u8 lcd_set_segments[] = {0x04,reverse(byte1),reverse(byte2),0x00,0x00,reverse(byte3),reverse(byte4),0x00,0x00,reverse(byte5),reverse(byte6), 0xc8};
157-
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
158-
}
207+
if(lcd_version == LCD_UART){// B1.6 Hardware
208+
uart_send_lcd(byte1,byte2,byte3,byte4,byte5,byte6);
209+
}else if(lcd_version == LCD_SPI){// B1.6 Hardware
210+
spi_send_lcd(byte1,byte2,byte3,byte4,byte5,byte6);
211+
} else if(lcd_version == LCD_I2C_3C){// B1.4 Hardware
212+
u8 lcd_set_segments[] = {0x80,0x40,0xC0,byte1,0xC0,byte2,0xC0,byte3,0xC0,byte4,0xC0,byte5,0xC0,byte6};
213+
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
214+
}else if(lcd_version == LCD_I2C_3E){// B1.9 Hardware
215+
u8 lcd_set_segments[] = {0x04,reverse(byte1),reverse(byte2),0x00,0x00,reverse(byte3),reverse(byte4),0x00,0x00,reverse(byte5),reverse(byte6), 0xc8};
216+
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
217+
}
159218
}
160219

161220
void update_lcd(){
@@ -164,7 +223,7 @@ void update_lcd(){
164223

165224
void show_number(u8 position,u8 number){
166225
if(position>5 || position == 2 || number >9)return;
167-
display_buff[position] = display_numbers[number] & 0xF7;
226+
display_buff[position] = display_numbers[number] & 0xF7;
168227
}
169228

170229
void show_temp_symbol(u8 symbol){/*1 = C, 2 = F*/
@@ -232,13 +291,13 @@ void show_big_number(int16_t number, bool point){
232291
if(number > 99)display_buff[5] |= display_numbers[number / 100 % 10] & 0xF7;
233292
if(number > 9)display_buff[4] |= display_numbers[number / 10 % 10] & 0xF7;
234293
if(number < 9)display_buff[4] |= display_numbers[0] & 0xF7;
235-
display_buff[3] = display_numbers[number %10] & 0xF7;
294+
display_buff[3] = display_numbers[number %10] & 0xF7;
236295
}
237296

238297
void show_small_number(u16 number, bool percent){
239298
if(number >99)return;
240299
display_buff[0] = percent?0x08:0x00;
241300
display_buff[1] = display_buff[1] & 0x08;
242301
if(number > 9)display_buff[1] |= display_numbers[number / 10 % 10] & 0xF7;
243-
display_buff[0] |= display_numbers[number %10] & 0xF7;
302+
display_buff[0] |= display_numbers[number %10] & 0xF7;
244303
}

src/lcd.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
#include <stdbool.h>
44
#include <stdint.h>
55

6+
enum {
7+
LCD_I2C_3C = 0x01, // B1.4
8+
LCD_I2C_3E = 0x02, // B1.9
9+
LCD_UART = 0x03, // B1.6 old
10+
LCD_SPI = 0x04, // B1.6 new
11+
};
12+
13+
#define CLK_DELAY_US 32 // =24 -> 20 kHz, =48 -> 10 kHz
14+
15+
616
void init_lcd(bool clear);
717
void init_lcd_deepsleep();
818
void send_to_lcd(u8 byte1, u8 byte2, u8 byte3, u8 byte4, u8 byte5, u8 byte6);

0 commit comments

Comments
 (0)