Skip to content

Commit 471b9ba

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

File tree

3 files changed

+114
-32
lines changed

3 files changed

+114
-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: 99 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -62,32 +62,60 @@ _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+
68+
for (int i = 0; i < 3; i++) {
69+
uart_send_lcd(0x00,0x00,0x00,0x00,0x00,0x00);
70+
u32 cur_time = clock_time();
71+
do
72+
{
73+
if(reg_uart_buf_cnt & FLD_UART_RX_BUF_CNT) {
74+
ret = reg_uart_data_buf0;
75+
return (ret == 0xAA);
76+
}
77+
} while(!clock_time_exceed(cur_time, 512));
78+
}
79+
return 0;
80+
}
81+
6582
void init_lcd(bool clear){
6683

84+
u8 lcd_is_uart = 0;
85+
6786
if(test_i2c_device(0x3C)){// B1.4
68-
lcd_version = 0;
87+
lcd_version = LCD_I2C_3C;
6988
i2c_address_lcd = 0x78;
7089
}else if(test_i2c_device(0x3E)){// B1.9
71-
lcd_version = 2;
90+
lcd_version = LCD_I2C_3E;
7291
i2c_address_lcd = 0x7C;
7392
}else{// B1.6 uses UART and is not testable this way
74-
// UART 38400 BAUD
75-
lcd_version = 1;
93+
// B1.6 has two revisions: just TX and SPI connected
94+
// UART 38400 BAUD
95+
lcd_version = LCD_UART; // or LCD_SPI, check later
7696
}
7797

78-
if(lcd_version == 0){// B1.4 Hardware
98+
if(lcd_version == LCD_I2C_3C){// B1.4 Hardware
7999
gpio_set_func(GPIO_PB6, AS_GPIO);//LCD on low temp needs this, its an unknown pin going to the LCD controller chip
80100
gpio_set_output_en(GPIO_PB6, 0);
81101
gpio_set_input_en(GPIO_PB6, 1);
82102
gpio_setup_up_down_resistor(GPIO_PB6, PM_PIN_PULLUP_10K);
83103
sleep_us(50000);
84104
send_i2c(i2c_address_lcd, lcd_3C_init_cmd, sizeof(lcd_3C_init_cmd));
85105

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

88108
init_lcd_deepsleep();
109+
lcd_is_uart = check_is_uart();
110+
if (!lcd_is_uart){
111+
lcd_version = LCD_SPI;
112+
// enable SPI, it is not enabled before SPI detected
113+
gpio_set_func(LCD_SPI_SCK_PIN, AS_GPIO);
114+
gpio_set_func(LCD_SPI_SDO_PIN, AS_GPIO);
115+
sleep_us(512);
116+
}
89117

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

92120
send_i2c(i2c_address_lcd,lcd_3E_init_cmd, sizeof(lcd_3E_init_cmd));
93121
send_i2c(i2c_address_lcd,lcd_3E_init_cmd, sizeof(lcd_3E_init_cmd));
@@ -98,21 +126,25 @@ void init_lcd(bool clear){
98126
}
99127

100128
void init_lcd_deepsleep(){
101-
if(lcd_version == 0){// B1.4 Hardware
129+
if(lcd_version == LCD_I2C_3C){// B1.4 Hardware
102130
gpio_set_func(GPIO_PB6, AS_GPIO);//LCD on low temp needs this, its an unknown pin going to the LCD controller chip
103131
gpio_set_output_en(GPIO_PB6, 0);
104132
gpio_set_input_en(GPIO_PB6, 1);
105133
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);
134+
}
135+
else if(lcd_version == LCD_UART) {
136+
drv_uart_pin_set(LCD_UART_TX_PIN, LCD_UART_RX_PIN);
109137
uart_reset();
110138
uart_init_baudrate(LCD_UART_BAUD, UART_CLOCK_SOURCE, PARITY_NONE, STOP_BIT_ONE);
111139
uart_dma_enable(0, 0);
112140
dma_chn_irq_enable(0, 0);
113141
uart_irq_enable(0,0);
114142
uart_ndma_irq_triglevel(0,0);
115143
}
144+
else if (lcd_version == LCD_SPI) {
145+
gpio_set_func(LCD_SPI_SCK_PIN, AS_GPIO);
146+
gpio_set_func(LCD_SPI_SDO_PIN, AS_GPIO);
147+
}
116148

117149
}
118150

@@ -127,6 +159,37 @@ void uart_send_lcd(u8 byte1, u8 byte2, u8 byte3, u8 byte4, u8 byte5, u8 byte6){
127159
};
128160
}
129161

162+
163+
static void lcd_send_spi_byte(u8 b) {
164+
u32 x = b;
165+
for(int i = 0; i < 8; i++) {
166+
drv_gpio_write(LCD_SPI_SCK_PIN, 0);
167+
drv_gpio_write(LCD_SPI_SDO_PIN, x & 1); // MOSI
168+
sleep_us(CLK_DELAY_US);
169+
170+
drv_gpio_write(LCD_SPI_SCK_PIN, 1);
171+
sleep_us(CLK_DELAY_US);
172+
x >>= 1;
173+
}
174+
sleep_us(CLK_DELAY_US);
175+
}
176+
177+
178+
_attribute_ram_code_
179+
static void spi_send_lcd(u8 byte1, u8 byte2, u8 byte3, u8 byte4, u8 byte5, u8 byte6) {
180+
gpio_set_output_en(LCD_SPI_SCK_PIN, 1); // CLK output enable
181+
gpio_set_output_en(LCD_SPI_SDO_PIN, 1); // SDI output enable
182+
183+
unsigned char r = irq_disable();
184+
u8 trans_buff[9] = {0xAA,byte6,byte5,byte4,byte3,byte2,byte1,(byte1 ^byte2 ^byte3 ^byte4 ^byte5 ^byte6),0x55};
185+
186+
for (int i = 0; i < sizeof(trans_buff); i++) {
187+
lcd_send_spi_byte(trans_buff[i]);
188+
}
189+
irq_restore(r);
190+
}
191+
192+
130193
u8 reverse(u8 revByte) {
131194
revByte = (revByte & 0xF0) >> 4 | (revByte & 0x0F) << 4;
132195
revByte = (revByte & 0xCC) >> 2 | (revByte & 0x33) << 2;
@@ -135,27 +198,31 @@ u8 reverse(u8 revByte) {
135198
}
136199

137200
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-
}
201+
if(lcd_version == LCD_UART){// B1.6 Hardware
202+
uart_send_lcd(byte1,byte2,byte3,byte4,byte5,byte6);
203+
} else if (lcd_version == LCD_SPI){// B1.6 Hardware
204+
spi_send_lcd(byte1,byte2,byte3,byte4,byte5,byte6);
205+
} else if(lcd_version == LCD_I2C_3C){// B1.4 Hardware
206+
u8 lcd_set_segments[] = {0x80,0x40,0xC0,byte1,0xC0,byte2,0xC0,byte3,0xC0,byte4,0xC0,byte5,0xC0,byte6,0xC0,0x00,0xC0,0x00};
207+
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
208+
} else if(lcd_version == LCD_I2C_3E){// B1.9 Hardware
209+
u8 lcd_set_segments[] = {0x04,reverse(byte1),reverse(byte2),0x00,0x00,reverse(byte3),reverse(byte4),0x00,0x00,reverse(byte5),reverse(byte6), 0xc8};
210+
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
211+
}
147212
}
148213

149214
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-
}
215+
if(lcd_version == LCD_UART){// B1.6 Hardware
216+
uart_send_lcd(byte1,byte2,byte3,byte4,byte5,byte6);
217+
}else if(lcd_version == LCD_SPI){// B1.6 Hardware
218+
spi_send_lcd(byte1,byte2,byte3,byte4,byte5,byte6);
219+
} else if(lcd_version == LCD_I2C_3C){// B1.4 Hardware
220+
u8 lcd_set_segments[] = {0x80,0x40,0xC0,byte1,0xC0,byte2,0xC0,byte3,0xC0,byte4,0xC0,byte5,0xC0,byte6};
221+
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
222+
}else if(lcd_version == LCD_I2C_3E){// B1.9 Hardware
223+
u8 lcd_set_segments[] = {0x04,reverse(byte1),reverse(byte2),0x00,0x00,reverse(byte3),reverse(byte4),0x00,0x00,reverse(byte5),reverse(byte6), 0xc8};
224+
send_i2c(i2c_address_lcd,lcd_set_segments, sizeof(lcd_set_segments));
225+
}
159226
}
160227

161228
void update_lcd(){
@@ -164,7 +231,7 @@ void update_lcd(){
164231

165232
void show_number(u8 position,u8 number){
166233
if(position>5 || position == 2 || number >9)return;
167-
display_buff[position] = display_numbers[number] & 0xF7;
234+
display_buff[position] = display_numbers[number] & 0xF7;
168235
}
169236

170237
void show_temp_symbol(u8 symbol){/*1 = C, 2 = F*/
@@ -232,13 +299,13 @@ void show_big_number(int16_t number, bool point){
232299
if(number > 99)display_buff[5] |= display_numbers[number / 100 % 10] & 0xF7;
233300
if(number > 9)display_buff[4] |= display_numbers[number / 10 % 10] & 0xF7;
234301
if(number < 9)display_buff[4] |= display_numbers[0] & 0xF7;
235-
display_buff[3] = display_numbers[number %10] & 0xF7;
302+
display_buff[3] = display_numbers[number %10] & 0xF7;
236303
}
237304

238305
void show_small_number(u16 number, bool percent){
239306
if(number >99)return;
240307
display_buff[0] = percent?0x08:0x00;
241308
display_buff[1] = display_buff[1] & 0x08;
242309
if(number > 9)display_buff[1] |= display_numbers[number / 10 % 10] & 0xF7;
243-
display_buff[0] |= display_numbers[number %10] & 0xF7;
310+
display_buff[0] |= display_numbers[number %10] & 0xF7;
244311
}

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)