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, &reg, 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, &reg, 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