Lcm_Update.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*
  2. * Lcm_Update.c
  3. *
  4. * Created on: 2022年1月3日
  5. * Author: 8513
  6. */
  7. #include <stdio.h> /*標準輸入輸出定義*/
  8. #include <stdlib.h> /*標準函數庫定義*/
  9. #include <stdint.h>
  10. #include <string.h>
  11. #include <unistd.h>
  12. #include <termios.h>
  13. #include <fcntl.h>
  14. #include <time.h>
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <sys/ioctl.h>
  18. #include <sys/timeb.h>
  19. #include <dirent.h>
  20. #include "cbmp.h"
  21. #include "Module_LcmControl.h"
  22. #include "../Log/log.h"
  23. #include "../ShareMemory/shmMem.h"
  24. #include "../Define/define.h"
  25. #include "../Config.h"
  26. #include "../SelectGun/SelectGun.h"
  27. #include "../CSU/main.h"
  28. DcCommonInfo *ShmDcCommonData = NULL;
  29. int _port;
  30. void displayMessageDgus(uint8_t *data, uint16_t len, uint8_t isRX)
  31. {
  32. uint8_t output[8192];
  33. memset(output, 0x00, ARRAY_SIZE(output));
  34. sprintf((char*)output, "%s", (isRX?"RX: ":"TX: "));
  35. for(uint16_t idx = 0;idx<len;idx++)
  36. {
  37. sprintf((char*)output, "%s%02x ", output, data[idx]);
  38. }
  39. #ifdef isDebugPrint
  40. log_info("%s\n", output);
  41. #endif
  42. }
  43. int transceiverDgus(int32_t fd, uint8_t *tx, uint16_t tx_len, uint8_t *rx, uint16_t rx_len)
  44. {
  45. int result = FAIL;
  46. int len;
  47. tcflush(fd,TCIOFLUSH);
  48. #ifdef isDebugPrint
  49. displayMessageDgus(tx, tx_len, NO);
  50. #endif
  51. usleep(10000);
  52. if(write(fd, tx, tx_len) >= ARRAY_SIZE(tx))
  53. {
  54. if(tx[3] == CMD_REG_WRITE_DATA)
  55. {
  56. len = read(fd, rx, rx_len);
  57. if(len > 0)
  58. {
  59. if((rx[0] == CMD_HEADER_1) && (rx[1] == CMD_HEADER_2))
  60. {
  61. if((rx[3] == CMD_REG_WRITE_DATA) && (rx[4] == 0x4f) && (rx[5] == 0x4b))
  62. {
  63. displayMessageDgus(rx, len, YES);
  64. result = PASS;
  65. }
  66. }
  67. }
  68. }
  69. else if(tx[3] == CMD_REG_READ_DATA)
  70. {
  71. len = read(fd, rx, rx_len);
  72. if(len > 0)
  73. {
  74. if((rx[0] == CMD_HEADER_1) && (rx[1] == CMD_HEADER_2))
  75. {
  76. if(rx[3] == CMD_REG_READ_DATA)
  77. {
  78. displayMessageDgus(rx, len, YES);
  79. result = PASS;
  80. }
  81. else
  82. {}
  83. }
  84. else
  85. {}
  86. }
  87. else
  88. {}
  89. }
  90. else
  91. {}
  92. }
  93. else
  94. {}
  95. return result;
  96. }
  97. int8_t lcdRegisterWrite(int32_t fd, uint8_t regType, uint16_t address, uint8_t *data, uint16_t dataLen)
  98. {
  99. int8_t result = FAIL;
  100. uint8_t tx[(regType == REG_TYPE_CONTROL? 8 : 6) + dataLen];
  101. uint8_t rx[6];
  102. memset(tx, 0x00, sizeof(tx));
  103. memset(rx, 0x00, sizeof(rx));
  104. tx[0] = CMD_HEADER_1;
  105. tx[1] = CMD_HEADER_2;
  106. tx[2] = (regType == REG_TYPE_CONTROL? 7 : (3 + dataLen));
  107. tx[3] = CMD_REG_WRITE_DATA;
  108. tx[4] = (address >> 8) & 0xff;
  109. tx[5] = (address >> 0) & 0xff;
  110. if(regType == REG_TYPE_CONTROL)
  111. {
  112. if(address == REG_ADDRESS_SET_PAGE_ID)
  113. {
  114. tx[6] = 0x5A;
  115. tx[7] = 0x01;
  116. memcpy(&tx[8], data, dataLen);
  117. }
  118. }
  119. else
  120. {
  121. memcpy(&tx[6], data, dataLen);
  122. }
  123. if(fd > 0)
  124. {
  125. if(transceiverDgus(fd, tx, ARRAY_SIZE(tx), rx, ARRAY_SIZE(rx)) == PASS)
  126. {
  127. result = PASS;
  128. }
  129. else
  130. {}
  131. }
  132. else
  133. {}
  134. return result;
  135. }
  136. void ResetLCM()
  137. {
  138. uint8_t cmd_reset[] = { 0x55, 0xaa, 0x5a, 0xa5 };
  139. while (lcdRegisterWrite(_port, REG_TYPE_RAM, 0x04, cmd_reset, ARRAY_SIZE(cmd_reset)) != PASS)
  140. {
  141. log_error("LCD reset fail.\n");
  142. sleep(1);
  143. }
  144. sleep(1);
  145. }
  146. //=======================================
  147. // LCD upgrade
  148. //=======================================
  149. int downloadBMP(uint8_t picIdx, char *filename)
  150. {
  151. int result = PASS;
  152. BMP *bmp;
  153. struct stat fileSt;
  154. uint32_t pageSize = 0xf0;
  155. uint32_t pixelSize;
  156. uint32_t transferedByte=0;
  157. uint16_t bufferRamAddr = 0x8000;
  158. uint32_t dataLen = 0;
  159. uint32_t startAddr=0;
  160. // Reset LCD
  161. ResetLCM();
  162. // Get image file size
  163. stat(filename, &fileSt);
  164. bmp = bopen(filename);
  165. uint8_t buf[bmp->width*bmp->height*2];
  166. log_info("Target address: %d\n", picIdx);
  167. log_info("Image filename: %s\n", filename);
  168. log_info("Image width: %d height: %d\n", bmp->width, bmp->height);
  169. log_info("Image data size: %d\n", ARRAY_SIZE(buf));
  170. // Get bmp pixel data and convert to 16 bit color
  171. for(uint16_t idxY=0 ; idxY<bmp->height ; idxY++)
  172. {
  173. for(uint16_t idxX=0 ; idxX<bmp->width ; idxX++)
  174. {
  175. uint8_t r, g, b;
  176. get_pixel_rgb(bmp, idxX, (bmp->height-idxY-1), &r, &g, &b);
  177. buf[(2*((idxY*bmp->width) + idxX)) + 0] = ((((r>>3)<<11) | ((g>>2)<<5) | (b>>3)) >> 8) & 0xff;
  178. buf[(2*((idxY*bmp->width) + idxX)) + 1] = ((((r>>3)<<11) | ((g>>2)<<5) | (b>>3)) >> 0) & 0xff;
  179. }
  180. }
  181. bclose(bmp);
  182. // Transfer pixel to screen page
  183. pixelSize = ARRAY_SIZE(buf);
  184. for(uint16_t idxSrcData=0;idxSrcData<(((pixelSize%pageSize)==0)?(pixelSize/pageSize):(pixelSize/pageSize)+1);idxSrcData++)
  185. {
  186. //log_info("Buffer start data address: 0x%08X\n", (idxSrcData*pageSize));
  187. //log_info(" Image start ram address: 0x%08X\n", ((idxSrcData*pageSize) >> 1));
  188. uint8_t display_cmd[] ={0x5a, (bufferRamAddr>>8)&0xff, (bufferRamAddr>>0)&0xff, 0x00, 0x00, 0x00, 0x00, 0x00};
  189. if((idxSrcData+1) != (((pixelSize%pageSize)==0)?(pixelSize/pageSize):(pixelSize/pageSize)+1))
  190. {
  191. // Data transfer
  192. while(lcdRegisterWrite(_port, REG_TYPE_RAM, (bufferRamAddr+(dataLen>>1)), &buf[(idxSrcData*pageSize)], pageSize) != PASS)
  193. {
  194. log_info("Transfer data to ram 0x%04X fail.\n", transferedByte);
  195. }
  196. transferedByte += pageSize;
  197. dataLen += pageSize;
  198. }
  199. else
  200. {
  201. // Last data transfer
  202. while(lcdRegisterWrite(_port, REG_TYPE_RAM, (bufferRamAddr+(dataLen>>1)), &buf[(idxSrcData*pageSize)], (pixelSize-(idxSrcData*pageSize))) != PASS)
  203. {
  204. log_info("Transfer data to ram 0x%04X fail.\n", transferedByte);
  205. }
  206. transferedByte += (pixelSize-(idxSrcData*pageSize));
  207. dataLen += (pixelSize-(idxSrcData*pageSize));
  208. }
  209. // Move data from ram to flash
  210. if((dataLen >= (pageSize*10)) || (idxSrcData == (((pixelSize%pageSize)==0)?(pixelSize/pageSize):(pixelSize/pageSize)+1)-1))
  211. {
  212. display_cmd[3] = ((dataLen>>1) >> 8) & 0xff; // Data length high byte
  213. display_cmd[4] = ((dataLen>>1) >> 0) & 0xff; // Data length low byte
  214. display_cmd[5] = (((startAddr)>>1) >> 16) & 0xff; // Screen on ram address 1st byte
  215. display_cmd[6] = (((startAddr)>>1) >> 8) & 0xff; // Screen on ram address 2nd byte
  216. display_cmd[7] = (((startAddr)>>1) >> 0) & 0xff; // Screen on ram address 3th byte
  217. while(lcdRegisterWrite(_port, REG_TYPE_RAM, 0xa2, display_cmd, ARRAY_SIZE(display_cmd)) != PASS)
  218. {
  219. log_info("Write data to display buffer 0x%04X fail.\n", transferedByte);
  220. }
  221. startAddr += dataLen;
  222. dataLen = 0;
  223. }
  224. }
  225. // Save image to target address
  226. uint8_t save_cmd[] ={0x5a, 0x02, ((picIdx>>8)&0xff), (picIdx&0xff)};
  227. while(lcdRegisterWrite(_port, REG_TYPE_RAM, 0x84, save_cmd, ARRAY_SIZE(save_cmd)) != PASS)
  228. {
  229. log_info("Save image fail.\n");
  230. }
  231. log_info("Save image success.\n");
  232. sleep(1);
  233. return result;
  234. }
  235. int downloadBIN(uint8_t targetAddr, char *filename)
  236. {
  237. int result = PASS;
  238. int fd;
  239. struct stat fileSt;
  240. uint32_t pageSize = 128;
  241. uint32_t blocklSize = 32768;
  242. uint32_t transferedByte=0;
  243. uint16_t bufferRamAddr = 0x8000;
  244. // Reset LCD
  245. ResetLCM();
  246. // Get image file size
  247. stat(filename, &fileSt);
  248. if(S_ISDIR(fileSt.st_mode))
  249. {
  250. return FAIL;
  251. }
  252. uint8_t buf[(fileSt.st_size%32768==0?(fileSt.st_size/32768)*32768:(fileSt.st_size/32768)+1)*32768];
  253. log_info("Target address: %d\n", targetAddr);
  254. log_info("Bin filename: %s\n", filename);
  255. log_info("Bin data size: %ld\n", fileSt.st_size);
  256. fd = open(filename, O_RDWR);
  257. if (fd < 0)
  258. {
  259. log_info("Bin can not be open.\n");
  260. result = FAIL;
  261. }
  262. else
  263. {
  264. // Read data from bin file
  265. memset(buf, 0x00, ARRAY_SIZE(buf));
  266. read(fd, buf, ARRAY_SIZE(buf));
  267. close(fd);
  268. for(uint8_t idxBinSrc=0;idxBinSrc<(fileSt.st_size%32768==0?fileSt.st_size/32768:(fileSt.st_size/32768)+1);idxBinSrc++)
  269. {
  270. // Transfer data to ram
  271. for(uint16_t idxSrcData=0;idxSrcData<(((blocklSize%pageSize)==0)?(blocklSize/pageSize):(blocklSize/pageSize)+1);idxSrcData++)
  272. {
  273. log_info("Buffer start data address: 0x%08X\n", (idxBinSrc*blocklSize)+(idxSrcData*pageSize));
  274. log_info(" Image start ram address: 0x%08X\n", ((idxSrcData*pageSize) >> 1));
  275. if((idxSrcData+1) != (((blocklSize%pageSize)==0)?(blocklSize/pageSize):(blocklSize/pageSize)+1))
  276. {
  277. // Data transfer
  278. while(lcdRegisterWrite(_port, REG_TYPE_RAM, bufferRamAddr+((idxSrcData*pageSize)>>1), &buf[(idxBinSrc*blocklSize)+(idxSrcData*pageSize)], pageSize) != PASS)
  279. {
  280. //log_info("Transfer data to ram 0x%04X fail.\n", transferedByte);
  281. }
  282. transferedByte += pageSize;
  283. }
  284. else
  285. {
  286. // Last data transfer
  287. while(lcdRegisterWrite(_port, REG_TYPE_RAM, bufferRamAddr+((idxSrcData*pageSize)>>1), &buf[(idxBinSrc*blocklSize)+(idxSrcData*pageSize)], (blocklSize-(idxSrcData*pageSize)))!= PASS)
  288. {
  289. //log_info("Transfer data to ram 0x%04X fail.\n", transferedByte);
  290. }
  291. transferedByte += (blocklSize-(idxSrcData*pageSize));
  292. }
  293. }
  294. // Move data from ram to flash
  295. uint8_t save_cmd[] ={0x5a, 0x02, ((((targetAddr*8)+idxBinSrc)>>8)&0xff), ((((targetAddr*8)+idxBinSrc)>>0)&0xff), ((bufferRamAddr>>8)&0xff), ((bufferRamAddr>>0)&0xff), 0x00, 0x01, 0x00, 0x00, 0x00, 0x00};
  296. while(lcdRegisterWrite(_port, REG_TYPE_RAM, 0xaa, save_cmd, ARRAY_SIZE(save_cmd)) != PASS)
  297. {
  298. log_info("Save bin file to 0x%04X fail.\n", ((targetAddr*8)+idxBinSrc));
  299. }
  300. log_info("Save bin file on 0x%04X success.\n", ((targetAddr*8)+idxBinSrc));
  301. sleep(1);
  302. }
  303. }
  304. return result;
  305. }
  306. uint8_t lcdUpgrade(char *forlder)
  307. {
  308. int result = _LCM_UPGRADE_RESULT_PASS;
  309. DIR *dir;
  310. struct dirent *file;
  311. struct stat fileSt;
  312. log_info("forlder = %s \n", forlder);
  313. if ((dir = opendir (forlder)) != NULL)
  314. {
  315. /* print all the files and directories within directory */
  316. while ((file = readdir (dir)) != NULL)
  317. {
  318. //log_error("file->d_name = %s \n", file->d_name);
  319. if((strlen(file->d_name) > 2) && (file->d_type == DT_REG))
  320. {
  321. int targetAddr;
  322. stat(file->d_name, &fileSt);
  323. if(sscanf(file->d_name, "%d", &targetAddr) == 1)
  324. {
  325. char targetFile[384];
  326. sprintf(targetFile, "/mnt/lcd/DWIN_SET/%s", file->d_name);
  327. log_info("targetFile = %s \n", targetFile);
  328. if(strstr(file->d_name, ".bmp") != NULL)
  329. {
  330. downloadBMP(targetAddr, targetFile);
  331. }
  332. else
  333. {
  334. downloadBIN(targetAddr, targetFile);
  335. }
  336. }
  337. else
  338. {
  339. log_error("%s can not parse target address.\n", file->d_name);
  340. }
  341. }
  342. else
  343. {
  344. if(strlen(file->d_name) >= 3)
  345. {
  346. log_error("File name error.\n");
  347. result = _LCM_UPGRADE_RESULT_FAIL;
  348. }
  349. else
  350. {
  351. log_error("Searching file.\n");
  352. }
  353. }
  354. sleep(1);
  355. }
  356. closedir (dir);
  357. }
  358. else
  359. {
  360. log_error("%s does not valid.\n", forlder);
  361. result = _LCM_UPGRADE_RESULT_FAIL;
  362. }
  363. return result;
  364. }
  365. void UpdateLcmFunction(DcCommonInfo *ShmDcCommonData,int _lcmport)
  366. {
  367. _port = _lcmport;
  368. if(ShmDcCommonData->_upgrade_lcm_flag)
  369. {
  370. log_info("Update LCM Start");
  371. // 固定路徑 /mnt/lcd/DWIN_SET
  372. ShmDcCommonData->_upgrade_lcm_result = lcdUpgrade("/mnt/lcd/DWIN_SET");
  373. ResetLCM();
  374. ShmDcCommonData->_upgrade_lcm_flag = NO;
  375. }
  376. }