1 #include "lcd.h"
2 #include "font.h"
3
4 #define DRV_DEBUG
5 #define LOG_TAG "spi.lcd"
6 #include <drv_log.h>
7
8 static int32_t lcd_init(void);
9 static int32_t lcd_writereg(uint8_t reg,uint8_t* pdata,uint32_t length);
10 static int32_t lcd_readreg(uint8_t reg,uint8_t* pdata);
11 static int32_t lcd_senddata(uint8_t* pdata,uint32_t length);
12 static int32_t lcd_recvdata(uint8_t* pdata,uint32_t length);
13
14 ST7735_IO_t st7735_pIO = {
15 lcd_init,
16 RT_NULL,
17 RT_NULL,
18 lcd_writereg,
19 lcd_readreg,
20 lcd_senddata,
21 lcd_recvdata,
22 RT_NULL
23 };
24 ST7735_Object_t st7735_pObj;
25 uint32_t st7735_id;
26 static struct rt_spi_device *spi_dev_lcd;
27 #ifdef LCD_BACKLIGHT_USING_PWM
28 static struct rt_device_pwm *lcd_pwm_dev;
29 static uint32_t NowBrightness;
30 #endif
31 extern unsigned char WeActStudiologo[];
32
33 //LCD_RS
34 #define LCD_RS_SET rt_pin_write(WR_RS_PIN, PIN_HIGH)
35 #define LCD_RS_RESET rt_pin_write(WR_RS_PIN, PIN_LOW)
36 //LCD_CS
37 #define LCD_CS_SET rt_pin_write(CS_PIN, PIN_HIGH)
38 #define LCD_CS_RESET rt_pin_write(CS_PIN, PIN_LOW)
39
40
LCD_SetBrightness(uint32_t Brightness)41 void LCD_SetBrightness(uint32_t Brightness)
42 {
43 #ifdef LCD_BACKLIGHT_USING_PWM
44 Brightness = ((Brightness >= MAX_BRIGHTNESS)?(MAX_BRIGHTNESS-1):Brightness);
45 rt_pwm_set(lcd_pwm_dev, LCD_PWM_DEV_CHANNEL, MAX_BRIGHTNESS, Brightness);
46 NowBrightness = Brightness;
47 #else
48 rt_pin_mode(LCD_DISP_GPIO_NUM, PIN_MODE_OUTPUT);
49 rt_pin_write(LCD_DISP_GPIO_NUM, PIN_LOW);
50 #endif
51 }
52
LCD_GetBrightness(void)53 uint32_t LCD_GetBrightness(void)
54 {
55 #ifdef LCD_BACKLIGHT_USING_PWM
56 return NowBrightness;
57 #else
58 return 0;
59 #endif
60 }
61
62 //在指定位置显示一个字符
63 //x,y:起始坐标
64 //num:要显示的字符:" "--->"~"
65 //size:字体大小 12/16
66 //mode:叠加方式(1)还是非叠加方式(0)
LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint8_t size,uint8_t mode)67 void LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint8_t size,uint8_t mode)
68 {
69 uint8_t temp,t1,t;
70 uint16_t y0=y;
71 uint16_t x0=x;
72 uint32_t h,w;
73
74 uint16_t write[size][size==12?6:8];
75 uint16_t count;
76
77 ST7735_GetXSize(&st7735_pObj,&w);
78 ST7735_GetYSize(&st7735_pObj,&h);
79
80 //设置窗口
81 num=num-' ';//得到偏移后的值
82 count = 0;
83
84 if(!mode) //非叠加方式
85 {
86 for(t=0;t<size;t++)
87 {
88 if(size==12)temp=asc2_1206[num][t]; //调用1206字体
89 else temp=asc2_1608[num][t]; //调用1608字体
90
91 for(t1=0;t1<8;t1++)
92 {
93 if(temp&0x80)
94 write[count][t/2]=(BRUSH_POINT_COLOR&0xFF)<<8|BRUSH_POINT_COLOR>>8;
95 else
96 write[count][t/2]=(BRUSH_BACK_COLOR&0xFF)<<8|BRUSH_BACK_COLOR>>8;
97
98 count ++;
99 if(count >= size) count =0;
100
101 temp<<=1;
102 y++;
103 if(y>=h){return;}//超区域了
104 if((y-y0)==size)
105 {
106 y=y0;
107 x++;
108 if(x>=w){return;}//超区域了
109 break;
110 }
111 }
112 }
113 }
114 else//叠加方式
115 {
116 for(t=0;t<size;t++)
117 {
118 if(size==12)temp=asc2_1206[num][t]; //调用1206字体
119 else temp=asc2_1608[num][t]; //调用1608字体
120 for(t1=0;t1<8;t1++)
121 {
122 if(temp&0x80)
123 write[count][t/2]=(BRUSH_POINT_COLOR&0xFF)<<8|BRUSH_POINT_COLOR>>8;
124 count ++;
125 if(count >= size) count =0;
126
127 temp<<=1;
128 y++;
129 if(y>=h){return;}//超区域了
130 if((y-y0)==size)
131 {
132 y=y0;
133 x++;
134 if(x>=w){return;}//超区域了
135 break;
136 }
137 }
138 }
139 }
140 ST7735_FillRGBRect(&st7735_pObj,x0,y0,(uint8_t *)&write,size==12?6:8,size);
141 }
142
143 //显示字符串
144 //x,y:起点坐标
145 //width,height:区域大小
146 //size:字体大小
147 //*p:字符串起始地址
LCD_ShowString(uint16_t x,uint16_t y,uint16_t width,uint16_t height,uint8_t size,uint8_t * p)148 void LCD_ShowString(uint16_t x,uint16_t y,uint16_t width,uint16_t height,uint8_t size,uint8_t *p)
149 {
150 uint8_t x0=x;
151 width+=x;
152 height+=y;
153 while((*p<='~')&&(*p>=' '))//判断是不是非法字符!
154 {
155 if(x>=width){x=x0;y+=size;}
156 if(y>=height)break;//退出
157 LCD_ShowChar(x,y,*p,size,0);
158 x+=size/2;
159 p++;
160 }
161 }
162
LCD_FillRGBRect(uint32_t Xpos,uint32_t Ypos,uint8_t * pData,uint32_t Width,uint32_t Height)163 void LCD_FillRGBRect(uint32_t Xpos, uint32_t Ypos, uint8_t *pData, uint32_t Width, uint32_t Height)
164 {
165 ST7735_LCD_Driver.FillRGBRect(&st7735_pObj, Xpos, Ypos, pData, Width, Height);
166 }
167
lcd_init(void)168 static int32_t lcd_init(void)
169 {
170 return ST7735_OK;
171 }
172
lcd_writereg(uint8_t reg,uint8_t * pdata,uint32_t length)173 static int32_t lcd_writereg(uint8_t reg,uint8_t* pdata,uint32_t length)
174 {
175 int32_t result;
176 LCD_CS_RESET;
177 LCD_RS_RESET;
178 result = rt_spi_send(spi_dev_lcd, ®, 1);
179 LCD_RS_SET;
180 if(length > 0)
181 result += rt_spi_send(spi_dev_lcd, pdata, length);
182 LCD_CS_SET;
183 return ((result == length+1)?0:-1);
184 }
185
lcd_readreg(uint8_t reg,uint8_t * pdata)186 static int32_t lcd_readreg(uint8_t reg,uint8_t* pdata)
187 {
188 int32_t result;
189 LCD_CS_RESET;
190 LCD_RS_RESET;
191
192 result = rt_spi_send(spi_dev_lcd, ®, 1);
193 LCD_RS_SET;
194 result += rt_spi_recv(spi_dev_lcd, pdata, 1);
195 LCD_CS_SET;
196 return ((result == 2)?0:-1);
197 }
198
lcd_senddata(uint8_t * pdata,uint32_t length)199 static int32_t lcd_senddata(uint8_t* pdata,uint32_t length)
200 {
201 int32_t result;
202 LCD_CS_RESET;
203 //LCD_RS_SET;
204 result =rt_spi_send(spi_dev_lcd, pdata, length);
205 LCD_CS_SET;
206 return ((result == length)?0:-1);
207 }
208
lcd_recvdata(uint8_t * pdata,uint32_t length)209 static int32_t lcd_recvdata(uint8_t* pdata,uint32_t length)
210 {
211 int32_t result;
212 LCD_CS_RESET;
213 //LCD_RS_SET;
214 result = rt_spi_recv(spi_dev_lcd, pdata, length);
215 LCD_CS_SET;
216 return ((result == length)?0:-1);
217 }
218
LCD_Init(void)219 static int LCD_Init(void)
220 {
221 rt_pin_mode(WR_RS_PIN, PIN_MODE_OUTPUT);
222 rt_pin_mode(CS_PIN, PIN_MODE_OUTPUT);
223
224 spi_dev_lcd = (struct rt_spi_device *)rt_device_find(LCD_SPI_DEVICE_NAME);
225 if (!spi_dev_lcd)
226 {
227 LOG_E("tft-lcd init failed! can't find %s device!\n", LCD_SPI_DEVICE_NAME);
228 return -RT_ERROR;
229 }
230
231 ST7735_RegisterBusIO(&st7735_pObj,&st7735_pIO);
232 if(ST7735_ERROR == ST7735_LCD_Driver.Init(&st7735_pObj,ST7735_FORMAT_RBG565,ST7735_ORIENTATION_LANDSCAPE_ROT180))
233 {
234 LOG_E("st7735 init failed!");
235 // return ;
236 }
237 ST7735_LCD_Driver.FillRect(&st7735_pObj,0,0,160,80,BLACK);
238 ST7735_LCD_Driver.ReadID(&st7735_pObj,&st7735_id);
239 ST7735_LCD_Driver.DisplayOn(&st7735_pObj);
240 LOG_D("lcd id:0X%08X", st7735_id);
241 LOG_D("chip id:0X%08X", HAL_GetDEVID());
242
243 #ifdef LCD_BACKLIGHT_USING_PWM
244 /* turn on the LCD backlight */
245 lcd_pwm_dev = (struct rt_device_pwm *)rt_device_find(LCD_PWM_DEV_NAME);
246 if (!lcd_pwm_dev)
247 {
248 LOG_E("lcd pwm pin init failed! can't find %s device!\n", LCD_SPI_DEVICE_NAME);
249 return -RT_ERROR;
250 }
251 /* pwm frequency:100K = 10000ns */
252 rt_pwm_set(lcd_pwm_dev, LCD_PWM_DEV_CHANNEL, LCD_PWM_DEV_TIME, 5000);
253 rt_pwm_enable(lcd_pwm_dev, LCD_PWM_DEV_CHANNEL);
254 #endif
255 LCD_SetBrightness(MAX_BRIGHTNESS);
256
257 ST7735_LCD_Driver.DrawBitmap(&st7735_pObj,0,0,WeActStudiologo);
258 return RT_EOK;
259 }
260 INIT_COMPONENT_EXPORT(LCD_Init);
261
262 #ifdef DRV_DEBUG
263 #ifdef FINSH_USING_MSH
show_logo(int argc,char ** argv)264 static int show_logo(int argc, char **argv)
265 {
266 uint8_t text[20];
267
268 LCD_SetBrightness(MAX_BRIGHTNESS);
269
270 ST7735_LCD_Driver.DrawBitmap(&st7735_pObj,0,0,WeActStudiologo);
271 rt_thread_mdelay(1000);
272
273 ST7735_LCD_Driver.FillRect(&st7735_pObj,0,0,160,80,BLACK);
274
275 sprintf((char *)&text,"WeAct Studio");
276 LCD_ShowString(4,4,160,16,16,text);
277 sprintf((char *)&text,"STM32H7xx 0x%X",HAL_GetDEVID());
278 LCD_ShowString(4,22,160,16,16,text);
279 sprintf((char *)&text,"LCD ID: 0x%X",st7735_id);
280 LCD_ShowString(4,40,160,16,16,text);
281 return 0;
282 }
283 MSH_CMD_EXPORT(show_logo, show logo);
284 #endif /* FINSH_USING_MSH */
285 #endif /* DRV_DEBUG */
286
287