lark1fq/bootloader/src/file.c

231 lines
7.3 KiB
C
Raw Normal View History

2024-03-16 22:28:04 +08:00
#include "ff.h"
#include "file.h"
#include "sdio_sd.h"
#include "partition.h"
#include "led.h"
2024-03-16 22:28:04 +08:00
#define RETRY_MAX (5)
FATFS fs;
FIL f;
uint8_t file_buffer[FILE_BUFF_SIZE];
TCHAR file_name[FILE_IDX_MAX][FILE_NAME_LEN];
static void file_copy_name(TCHAR *dst, TCHAR *src)
{
for (uint32_t i=0; i<FILE_NAME_LEN; i++) {
dst[i] = src[i];
}
}
static uint32_t file_compare(TCHAR *name)
{
if (name[0] == '\0') {
return FILE_IDX_END;
} else if ((name[0] == 'C' || name[0] == 'c') && \
(name[1] == 'O' || name[1] == 'o') && \
(name[2] == 'N' || name[2] == 'n') && \
(name[3] == 'F' || name[3] == 'f') && \
(name[4] == 'I' || name[4] == 'i') && \
(name[5] == 'G' || name[5] == 'g') && \
(name[6] == '.' ) && \
(name[7] == 'T' || name[7] == 't') && \
(name[8] == 'X' || name[8] == 'x') && \
(name[9] == 'T' || name[9] == 't')) {
return FILE_IDX_CONFIG;
} else if ((name[0] == 'M' || name[0] == 'm') && \
(name[1] == 'A' || name[1] == 'a') && \
(name[2] == 'I' || name[2] == 'i') && \
(name[3] == 'N' || name[3] == 'n') && \
(name[8] == '.' ) && \
(name[9] == 'B' || name[9] == 'b') && \
(name[10] == 'I' || name[10] == 'i') && \
(name[11] == 'N' || name[11] == 'n')) {
return FILE_IDX_MAIN;
} else if ((name[0] == 'G' || name[0] == 'g') && \
(name[1] == 'A' || name[1] == 'a') && \
(name[2] == 'S' || name[2] == 's') && \
(name[8] == '.' ) && \
(name[9] == 'B' || name[9] == 'b') && \
(name[10] == 'I' || name[10] == 'i') && \
(name[11] == 'N' || name[11] == 'n')) {
if (name[3] == '1') {
return FILE_IDX_GAS1;
} else if (name[3] == '2') {
return FILE_IDX_GAS2;
} else if (name[3] == '3') {
return FILE_IDX_GAS3;
} else if (name[3] == '4') {
return FILE_IDX_GAS4;
} else {
return FILE_IDX_OTHER;
}
} else if ((name[0] == 'L' || name[0] == 'l') && \
(name[1] == 'A' || name[1] == 'a') && \
(name[2] == 'R' || name[2] == 'r') && \
(name[3] == 'K' || name[3] == 'k') && \
(name[4] == '1' ) && \
(name[5] == 'F' || name[5] == 'f') && \
(name[6] == 'Q' || name[6] == 'q') && \
(name[7] == '.' || name[7] == '.') && \
(name[8] == 'B' || name[8] == 'b') && \
(name[9] == 'I' || name[9] == 'i') && \
(name[10] == 'N' || name[10] == 'n')) {
return FILE_IDX_FW;
} else {
return FILE_IDX_OTHER;
}
}
uint32_t file_init(void)
{
SD_Error sd_err;
FRESULT ret;
uint32_t retry;
DIR dir;
FILINFO fileinfo;
TCHAR name[FILE_NAME_LEN];
uint32_t mask = FILE_MASK_NULL;
retry = RETRY_MAX;
while (retry--) {
sd_err = SD_Init();
if (sd_err == SD_OK) {
break;
} else if (retry == 0) {
return FILE_MASK_NULL;
}
}
retry = RETRY_MAX;
while (retry--) {
ret = f_mount(0, &fs);
if (ret == FR_OK) {
break;
} else {
return FILE_MASK_NULL;
}
}
retry = RETRY_MAX;
while (retry--) {
ret = f_getcwd (name, sizeof(name));
if (ret == FR_OK) {
break;
} else {
return FILE_MASK_NULL;
}
}
retry = RETRY_MAX;
while (retry--) {
ret = f_opendir(&dir, name);
if (ret == FR_OK) {
break;
} else {
return FILE_MASK_NULL;
}
}
while (1) {
ret = f_readdir(&dir, &fileinfo);
if (ret == FR_OK) {
uint32_t idx = file_compare(fileinfo.fname);
if (idx == FILE_IDX_OTHER) {
continue;
} else if (idx == FILE_IDX_END) {
return mask;
} else if (idx == FILE_IDX_CONFIG) {
file_copy_name(file_name[idx], fileinfo.fname);
mask |= FILE_MASK_CONFIG;
} else if (idx == FILE_IDX_MAIN) {
file_copy_name(file_name[idx], fileinfo.fname);
mask |= FILE_MASK_MAIN;
} else if (idx == FILE_IDX_GAS1) {
file_copy_name(file_name[idx], fileinfo.fname);
mask |= FILE_MASK_GAS1;
} else if (idx == FILE_IDX_GAS2) {
file_copy_name(file_name[idx], fileinfo.fname);
mask |= FILE_MASK_GAS2;
} else if (idx == FILE_IDX_GAS3) {
file_copy_name(file_name[idx], fileinfo.fname);
mask |= FILE_MASK_GAS3;
} else if (idx == FILE_IDX_GAS4) {
file_copy_name(file_name[idx], fileinfo.fname);
mask |= FILE_MASK_GAS4;
} else if (idx == FILE_IDX_FW) {
file_copy_name(file_name[idx], fileinfo.fname);
mask |= FILE_MASK_FW;
}
} else {
return FILE_MASK_NULL;
}
}
return FILE_MASK_NULL;
}
void file_secctor_erase(uint16_t sector)
{
uint32_t addr, size;
if (sector == SECTOR_CONFIG) {
addr = ADDR_CONFIG;
size = SIZE_CONFIG;
} else if (sector == SECTOR_BITMAP) {
addr = ADDR_BITMAP;
size = SIZE_BITMAP;
} else if (sector == SECTOR_FW0) {
addr = ADDR_FW + SIZE_FW_SECTOR * 0;
size = SIZE_FW_SECTOR;
} else if (sector == SECTOR_FW1) {
addr = ADDR_FW + SIZE_FW_SECTOR * 1;
size = SIZE_FW_SECTOR;
} else if (sector == SECTOR_FW2) {
addr = ADDR_FW + SIZE_FW_SECTOR * 2;
size = SIZE_FW_SECTOR;
} else {
return;
}
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | \
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
if (FLASH_EraseSector(sector, VoltageRange_3) != FLASH_COMPLETE) {
led_indicate_error();
2024-03-16 22:28:04 +08:00
}
FLASH_Lock();
for (uint32_t i = 0; i < size; i += 4) {
if (*(volatile uint32_t *)(addr + i) == 0xFFFFFFFF) {
continue;
} else {
led_indicate_error();
2024-03-16 22:28:04 +08:00
}
}
}
/* unit of len is byte, len must multiple of 4 */
void file_write_flash(uint32_t flash, uint8_t *buff, uint32_t len)
{
uint32_t i;
uint32_t *p_buff;
volatile uint32_t *p_flash;
/* program data */
p_buff = (uint32_t *)buff;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | \
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
for (i = 0; i < len / 4; i++) {
if (FLASH_ProgramWord(flash + i * 4, p_buff[i]) != FLASH_COMPLETE) {
led_indicate_error();
2024-03-16 22:28:04 +08:00
}
}
FLASH_Lock();
/* check data */
p_flash = (volatile uint32_t *)flash;
for (i = 0; i < len / 4; i++) {
if (p_flash[i] != p_buff[i]) {
led_indicate_error();
2024-03-16 22:28:04 +08:00
}
}
}