/* * Lcm_Update.c * * Created on: 2022年1月3日 * Author: 8513 */ #include /*標準輸入輸出定義*/ #include /*標準函數庫定義*/ #include #include #include #include #include #include #include #include #include #include #include #include "cbmp.h" #include "Module_LcmControl.h" #include "../Log/log.h" #include "../ShareMemory/shmMem.h" #include "../Define/define.h" #include "../Config.h" #include "../SelectGun/SelectGun.h" #include "../CSU/main.h" DcCommonInfo *ShmDcCommonData = NULL; int _port; void displayMessageDgus(uint8_t *data, uint16_t len, uint8_t isRX) { uint8_t output[8192]; memset(output, 0x00, ARRAY_SIZE(output)); sprintf((char*)output, "%s", (isRX?"RX: ":"TX: ")); for(uint16_t idx = 0;idx= ARRAY_SIZE(tx)) { if(tx[3] == CMD_REG_WRITE_DATA) { len = read(fd, rx, rx_len); if(len > 0) { if((rx[0] == CMD_HEADER_1) && (rx[1] == CMD_HEADER_2)) { if((rx[3] == CMD_REG_WRITE_DATA) && (rx[4] == 0x4f) && (rx[5] == 0x4b)) { displayMessageDgus(rx, len, YES); result = PASS; } } } } else if(tx[3] == CMD_REG_READ_DATA) { len = read(fd, rx, rx_len); if(len > 0) { if((rx[0] == CMD_HEADER_1) && (rx[1] == CMD_HEADER_2)) { if(rx[3] == CMD_REG_READ_DATA) { displayMessageDgus(rx, len, YES); result = PASS; } else {} } else {} } else {} } else {} } else {} return result; } int8_t lcdRegisterWrite(int32_t fd, uint8_t regType, uint16_t address, uint8_t *data, uint16_t dataLen) { int8_t result = FAIL; uint8_t tx[(regType == REG_TYPE_CONTROL? 8 : 6) + dataLen]; uint8_t rx[6]; memset(tx, 0x00, sizeof(tx)); memset(rx, 0x00, sizeof(rx)); tx[0] = CMD_HEADER_1; tx[1] = CMD_HEADER_2; tx[2] = (regType == REG_TYPE_CONTROL? 7 : (3 + dataLen)); tx[3] = CMD_REG_WRITE_DATA; tx[4] = (address >> 8) & 0xff; tx[5] = (address >> 0) & 0xff; if(regType == REG_TYPE_CONTROL) { if(address == REG_ADDRESS_SET_PAGE_ID) { tx[6] = 0x5A; tx[7] = 0x01; memcpy(&tx[8], data, dataLen); } } else { memcpy(&tx[6], data, dataLen); } if(fd > 0) { if(transceiverDgus(fd, tx, ARRAY_SIZE(tx), rx, ARRAY_SIZE(rx)) == PASS) { result = PASS; } else {} } else {} return result; } void ResetLCM() { uint8_t cmd_reset[] = { 0x55, 0xaa, 0x5a, 0xa5 }; while (lcdRegisterWrite(_port, REG_TYPE_RAM, 0x04, cmd_reset, ARRAY_SIZE(cmd_reset)) != PASS) { log_error("LCD reset fail.\n"); sleep(1); } sleep(1); } //======================================= // LCD upgrade //======================================= int downloadBMP(uint8_t picIdx, char *filename) { int result = PASS; BMP *bmp; struct stat fileSt; uint32_t pageSize = 0xf0; uint32_t pixelSize; uint32_t transferedByte=0; uint16_t bufferRamAddr = 0x8000; uint32_t dataLen = 0; uint32_t startAddr=0; // Reset LCD ResetLCM(); // Get image file size stat(filename, &fileSt); bmp = bopen(filename); uint8_t buf[bmp->width*bmp->height*2]; log_info("Target address: %d\n", picIdx); log_info("Image filename: %s\n", filename); log_info("Image width: %d height: %d\n", bmp->width, bmp->height); log_info("Image data size: %d\n", ARRAY_SIZE(buf)); // Get bmp pixel data and convert to 16 bit color for(uint16_t idxY=0 ; idxYheight ; idxY++) { for(uint16_t idxX=0 ; idxXwidth ; idxX++) { uint8_t r, g, b; get_pixel_rgb(bmp, idxX, (bmp->height-idxY-1), &r, &g, &b); buf[(2*((idxY*bmp->width) + idxX)) + 0] = ((((r>>3)<<11) | ((g>>2)<<5) | (b>>3)) >> 8) & 0xff; buf[(2*((idxY*bmp->width) + idxX)) + 1] = ((((r>>3)<<11) | ((g>>2)<<5) | (b>>3)) >> 0) & 0xff; } } bclose(bmp); // Transfer pixel to screen page pixelSize = ARRAY_SIZE(buf); for(uint16_t idxSrcData=0;idxSrcData<(((pixelSize%pageSize)==0)?(pixelSize/pageSize):(pixelSize/pageSize)+1);idxSrcData++) { //log_info("Buffer start data address: 0x%08X\n", (idxSrcData*pageSize)); //log_info(" Image start ram address: 0x%08X\n", ((idxSrcData*pageSize) >> 1)); uint8_t display_cmd[] ={0x5a, (bufferRamAddr>>8)&0xff, (bufferRamAddr>>0)&0xff, 0x00, 0x00, 0x00, 0x00, 0x00}; if((idxSrcData+1) != (((pixelSize%pageSize)==0)?(pixelSize/pageSize):(pixelSize/pageSize)+1)) { // Data transfer while(lcdRegisterWrite(_port, REG_TYPE_RAM, (bufferRamAddr+(dataLen>>1)), &buf[(idxSrcData*pageSize)], pageSize) != PASS) { log_info("Transfer data to ram 0x%04X fail.\n", transferedByte); } transferedByte += pageSize; dataLen += pageSize; } else { // Last data transfer while(lcdRegisterWrite(_port, REG_TYPE_RAM, (bufferRamAddr+(dataLen>>1)), &buf[(idxSrcData*pageSize)], (pixelSize-(idxSrcData*pageSize))) != PASS) { log_info("Transfer data to ram 0x%04X fail.\n", transferedByte); } transferedByte += (pixelSize-(idxSrcData*pageSize)); dataLen += (pixelSize-(idxSrcData*pageSize)); } // Move data from ram to flash if((dataLen >= (pageSize*10)) || (idxSrcData == (((pixelSize%pageSize)==0)?(pixelSize/pageSize):(pixelSize/pageSize)+1)-1)) { display_cmd[3] = ((dataLen>>1) >> 8) & 0xff; // Data length high byte display_cmd[4] = ((dataLen>>1) >> 0) & 0xff; // Data length low byte display_cmd[5] = (((startAddr)>>1) >> 16) & 0xff; // Screen on ram address 1st byte display_cmd[6] = (((startAddr)>>1) >> 8) & 0xff; // Screen on ram address 2nd byte display_cmd[7] = (((startAddr)>>1) >> 0) & 0xff; // Screen on ram address 3th byte while(lcdRegisterWrite(_port, REG_TYPE_RAM, 0xa2, display_cmd, ARRAY_SIZE(display_cmd)) != PASS) { log_info("Write data to display buffer 0x%04X fail.\n", transferedByte); } startAddr += dataLen; dataLen = 0; } } // Save image to target address uint8_t save_cmd[] ={0x5a, 0x02, ((picIdx>>8)&0xff), (picIdx&0xff)}; while(lcdRegisterWrite(_port, REG_TYPE_RAM, 0x84, save_cmd, ARRAY_SIZE(save_cmd)) != PASS) { log_info("Save image fail.\n"); } log_info("Save image success.\n"); sleep(1); return result; } int downloadBIN(uint8_t targetAddr, char *filename) { int result = PASS; int fd; struct stat fileSt; uint32_t pageSize = 128; uint32_t blocklSize = 32768; uint32_t transferedByte=0; uint16_t bufferRamAddr = 0x8000; // Reset LCD ResetLCM(); // Get image file size stat(filename, &fileSt); if(S_ISDIR(fileSt.st_mode)) { return FAIL; } uint8_t buf[(fileSt.st_size%32768==0?(fileSt.st_size/32768)*32768:(fileSt.st_size/32768)+1)*32768]; log_info("Target address: %d\n", targetAddr); log_info("Bin filename: %s\n", filename); log_info("Bin data size: %ld\n", fileSt.st_size); fd = open(filename, O_RDWR); if (fd < 0) { log_info("Bin can not be open.\n"); result = FAIL; } else { // Read data from bin file memset(buf, 0x00, ARRAY_SIZE(buf)); read(fd, buf, ARRAY_SIZE(buf)); close(fd); for(uint8_t idxBinSrc=0;idxBinSrc<(fileSt.st_size%32768==0?fileSt.st_size/32768:(fileSt.st_size/32768)+1);idxBinSrc++) { // Transfer data to ram for(uint16_t idxSrcData=0;idxSrcData<(((blocklSize%pageSize)==0)?(blocklSize/pageSize):(blocklSize/pageSize)+1);idxSrcData++) { log_info("Buffer start data address: 0x%08X\n", (idxBinSrc*blocklSize)+(idxSrcData*pageSize)); log_info(" Image start ram address: 0x%08X\n", ((idxSrcData*pageSize) >> 1)); if((idxSrcData+1) != (((blocklSize%pageSize)==0)?(blocklSize/pageSize):(blocklSize/pageSize)+1)) { // Data transfer while(lcdRegisterWrite(_port, REG_TYPE_RAM, bufferRamAddr+((idxSrcData*pageSize)>>1), &buf[(idxBinSrc*blocklSize)+(idxSrcData*pageSize)], pageSize) != PASS) { //log_info("Transfer data to ram 0x%04X fail.\n", transferedByte); } transferedByte += pageSize; } else { // Last data transfer while(lcdRegisterWrite(_port, REG_TYPE_RAM, bufferRamAddr+((idxSrcData*pageSize)>>1), &buf[(idxBinSrc*blocklSize)+(idxSrcData*pageSize)], (blocklSize-(idxSrcData*pageSize)))!= PASS) { //log_info("Transfer data to ram 0x%04X fail.\n", transferedByte); } transferedByte += (blocklSize-(idxSrcData*pageSize)); } } // Move data from ram to flash 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}; while(lcdRegisterWrite(_port, REG_TYPE_RAM, 0xaa, save_cmd, ARRAY_SIZE(save_cmd)) != PASS) { log_info("Save bin file to 0x%04X fail.\n", ((targetAddr*8)+idxBinSrc)); } log_info("Save bin file on 0x%04X success.\n", ((targetAddr*8)+idxBinSrc)); sleep(1); } } return result; } uint8_t lcdUpgrade(char *forlder) { int result = _LCM_UPGRADE_RESULT_PASS; DIR *dir; struct dirent *file; struct stat fileSt; log_info("forlder = %s \n", forlder); if ((dir = opendir (forlder)) != NULL) { /* print all the files and directories within directory */ while ((file = readdir (dir)) != NULL) { //log_error("file->d_name = %s \n", file->d_name); if((strlen(file->d_name) > 2) && (file->d_type == DT_REG)) { int targetAddr; stat(file->d_name, &fileSt); if(sscanf(file->d_name, "%d", &targetAddr) == 1) { char targetFile[384]; sprintf(targetFile, "/mnt/lcd/DWIN_SET/%s", file->d_name); log_info("targetFile = %s \n", targetFile); if(strstr(file->d_name, ".bmp") != NULL) { downloadBMP(targetAddr, targetFile); } else { downloadBIN(targetAddr, targetFile); } } else { log_error("%s can not parse target address.\n", file->d_name); } } else { if(strlen(file->d_name) >= 3) { log_error("File name error.\n"); result = _LCM_UPGRADE_RESULT_FAIL; } else { log_error("Searching file.\n"); } } sleep(1); } closedir (dir); } else { log_error("%s does not valid.\n", forlder); result = _LCM_UPGRADE_RESULT_FAIL; } return result; } void UpdateLcmFunction(DcCommonInfo *ShmDcCommonData,int _lcmport) { _port = _lcmport; if(ShmDcCommonData->_upgrade_lcm_flag) { log_info("Update LCM Start"); // 固定路徑 /mnt/lcd/DWIN_SET ShmDcCommonData->_upgrade_lcm_result = lcdUpgrade("/mnt/lcd/DWIN_SET"); ResetLCM(); ShmDcCommonData->_upgrade_lcm_flag = NO; } }