mirror of
https://gitee.com/Vancouver2017/luban-lite.git
synced 2025-12-29 01:06:56 +00:00
v1.0.3
This commit is contained in:
@@ -43,6 +43,11 @@ config AIC_FATFS_SECTOR_COUNT_FOR_0
|
||||
int "sector count"
|
||||
depends on !AIC_FATFS_AUTO_SIZE_FOR_0
|
||||
default 2048
|
||||
|
||||
config AIC_FATFS_ENABLE_WRITE_IN_SPINOR
|
||||
bool "FATFS enable write func in spinor"
|
||||
depends on AIC_SPINOR_DRV
|
||||
default n
|
||||
endif
|
||||
|
||||
# Parameters for LittleFS
|
||||
@@ -114,8 +119,49 @@ if AIC_USING_FS_IMAGE_TYPE_FATFS_FOR_0 || AIC_USING_FS_IMAGE_TYPE_FATFS_FOR_1
|
||||
default 8
|
||||
endif
|
||||
|
||||
config GENERATE_BURNER_IMAGE
|
||||
bool "Generate burner format image"
|
||||
default n
|
||||
|
||||
comment "LVGL demo select related"
|
||||
|
||||
# Kconfig file for package LVGL
|
||||
menuconfig LPKG_USING_LVGL
|
||||
bool "LVGL (official): powerful and easy-to-use embedded GUI library"
|
||||
default n
|
||||
|
||||
if LPKG_USING_LVGL
|
||||
|
||||
config LPKG_LVGL_PATH
|
||||
string
|
||||
default "/packages/multimedia/LVGL/LVGL"
|
||||
|
||||
config LPKG_LVGL_THREAD_PRIO
|
||||
int "Priority of LVGL thread"
|
||||
default 20
|
||||
|
||||
config LPKG_LVGL_THREAD_STACK_SIZE
|
||||
int "Stack size of LVGL thread"
|
||||
default 4096
|
||||
|
||||
config LPKG_LVGL_DISP_REFR_PERIOD
|
||||
int "Display refresh period (ms)"
|
||||
default 5 # official suggestion
|
||||
|
||||
config LPKG_USING_LVGL_SQUARELINE
|
||||
bool "Support SquareLine Studio"
|
||||
default n
|
||||
|
||||
config LPKG_LVGL_USING_EXAMPLES
|
||||
bool "Enable built-in examples"
|
||||
default n
|
||||
|
||||
config LPKG_LVGL_USING_DEMOS
|
||||
bool "Enable built-in demos"
|
||||
default n
|
||||
|
||||
endif
|
||||
|
||||
menuconfig AIC_LVGL_DEMO
|
||||
tristate "ArtInChip LVGL demo"
|
||||
select LPKG_USING_LVGL
|
||||
@@ -133,9 +179,14 @@ config AIC_LVGL_BASE_DEMO
|
||||
config AIC_LVGL_METER_DEMO
|
||||
bool "LVGL demo of meter"
|
||||
|
||||
config AIC_LVGL_MUSIC_DEMO
|
||||
bool "LVGL music demo"
|
||||
select LPKG_USING_LV_MUSIC_DEMO
|
||||
config AIC_LVGL_LAUNCHER_DEMO
|
||||
bool "LVGL launcher demo"
|
||||
|
||||
if KERNEL_BAREMETAL
|
||||
config AIC_LVGL_GIF_DEMO
|
||||
bool "LVGL gif demo"
|
||||
endif
|
||||
|
||||
endchoice
|
||||
|
||||
config LV_COLOR_DEPTH
|
||||
@@ -146,11 +197,16 @@ config LV_CACHE_IMG_NUM
|
||||
int "LVGL image cached number"
|
||||
default 2
|
||||
depends on LPKG_USING_LVGL
|
||||
# Parameters for LVGL meter demo
|
||||
if AIC_LVGL_METER_DEMO
|
||||
config LV_METER_SIMPLE_POINT
|
||||
bool "LVGL meter demo use simple point"
|
||||
default n
|
||||
endif
|
||||
endif
|
||||
|
||||
config LVGL_STORAGE_PATH
|
||||
string "LVGL Resource Directory"
|
||||
default "/rodata/lvgl_data"
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
@@ -97,6 +97,11 @@ menu "Upgrading"
|
||||
select AIC_BOOTLOADER_UDISK_SUPPORT
|
||||
select AIC_BOOTLOADER_FATFS_SUPPORT
|
||||
|
||||
config AICUPG_UDISK_VERSION3_SUPPORT
|
||||
bool "Support USB 3.0 Udisk"
|
||||
default n
|
||||
depends on AICUPG_UDISK_ENABLE
|
||||
|
||||
config AICUPG_USB_CONTROLLER_MAX_NUM
|
||||
int "USB Host controller count"
|
||||
default 1
|
||||
@@ -158,6 +163,10 @@ menu "Commands"
|
||||
bool "mem"
|
||||
default y
|
||||
|
||||
config AIC_BOOTLOADER_CMD_PART
|
||||
bool "part"
|
||||
default y
|
||||
|
||||
config AIC_BOOTLOADER_CMD_PROGRESS_BAR
|
||||
bool "boot progress bar"
|
||||
default n
|
||||
|
||||
@@ -27,6 +27,8 @@ if GetDepend('AIC_BOOTLOADER_CMD_PSRAM_TEST'):
|
||||
src += Glob('psram_test.c')
|
||||
if GetDepend('AIC_BOOTLOADER_CMD_XIP_BOOT'):
|
||||
src += Glob('xip_boot.c')
|
||||
if GetDepend('AIC_BOOTLOADER_CMD_PART'):
|
||||
src += Glob('part.c')
|
||||
|
||||
CPPPATH = [cwd]
|
||||
ASFLAGS = ''
|
||||
|
||||
@@ -24,21 +24,27 @@
|
||||
#include <mmc.h>
|
||||
#include <hal_syscfg.h>
|
||||
#include <upg_uart.h>
|
||||
#include <hal_rtc.h>
|
||||
#include <wdt.h>
|
||||
|
||||
#define AICUPG_HELP \
|
||||
"ArtInChip upgrading command:\n" \
|
||||
"aicupg [devtype] [interface]\n" \
|
||||
" - devtype: should be usb, uart, mmc, fat, brom\n" \
|
||||
" - interface: specify the controller id\n" \
|
||||
"e.g.\n" \
|
||||
" aicupg usb 0\n" \
|
||||
" aicupg mmc 1\n" \
|
||||
"when devtype is fat: \n" \
|
||||
"aicupg [devtype] [blkdev] [interface]\n" \
|
||||
"- blkdev: should be udisk,mmc \n" \
|
||||
"e.g.: \n" \
|
||||
" aicupg fat udisk 0\n" \
|
||||
" aicupg fat mmc 1\n" \
|
||||
"when devtype is brom, device will reset to Boot ROM upgrade mode\n" \
|
||||
" aicupg brom\n" \
|
||||
" aicupg\n"
|
||||
|
||||
#define AICUPG_HELP \
|
||||
"ArtInChip upgrading command:\n" \
|
||||
"aicupg [devtype] [interface]\n" \
|
||||
" - devtype: should be usb, uart, mmc, fat\n" \
|
||||
" - interface: specify the controller id\n" \
|
||||
"e.g.\n" \
|
||||
" aicupg usb 0\n" \
|
||||
" aicupg mmc 1\n" \
|
||||
"when devtype is fat: \n" \
|
||||
"aicupg [devtype] [blkdev] [interface]\n" \
|
||||
"- blkdev: should be udisk,mmc \n" \
|
||||
"e.g.: \n" \
|
||||
" aicupg fat udisk 0\n" \
|
||||
" aicupg fat mmc 1\n"
|
||||
static void aicupg_help(void)
|
||||
{
|
||||
puts(AICUPG_HELP);
|
||||
@@ -140,6 +146,7 @@ static int do_fat_upg(int intf, char *const blktype)
|
||||
file_buf = (char *)aicos_malloc_align(0, 1024, CACHE_LINE_SIZE);
|
||||
if (!file_buf) {
|
||||
pr_err("Error, malloc buf failed.\n");
|
||||
ret = -1;
|
||||
goto err;
|
||||
}
|
||||
memset((void *)file_buf, 0, 1024);
|
||||
@@ -149,6 +156,7 @@ static int do_fat_upg(int intf, char *const blktype)
|
||||
#if defined(AICUPG_UDISK_ENABLE)
|
||||
if (usbh_initialize(intf) < 0) {
|
||||
pr_err("usbh init failed!\n");
|
||||
ret = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -227,6 +235,19 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void do_brom_upg(void)
|
||||
{
|
||||
aic_set_reboot_reason(REBOOT_REASON_UPGRADE);
|
||||
|
||||
#ifdef AIC_WDT_DRV
|
||||
wdt_init();
|
||||
printf("Going to reboot ...\n");
|
||||
wdt_expire_now();
|
||||
while(1)
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int do_aicupg(int argc, char *argv[])
|
||||
{
|
||||
char *devtype = NULL;
|
||||
@@ -234,6 +255,11 @@ static int do_aicupg(int argc, char *argv[])
|
||||
|
||||
aic_get_reboot_reason();
|
||||
|
||||
if ((argc == 1) || ((argc == 2) && (!strcmp(argv[1], "brom")))) {
|
||||
do_brom_upg();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((argc < 3) || (argc > AICUPG_ARGS_MAX))
|
||||
goto help;
|
||||
devtype = argv[1]; /* mmc usb fat */
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <console.h>
|
||||
#include <aic_common.h>
|
||||
#include <aic_errno.h>
|
||||
#include <boot_param.h>
|
||||
#include <mmc.h>
|
||||
#include <image.h>
|
||||
#include <boot.h>
|
||||
@@ -20,16 +21,23 @@
|
||||
#include "fitimage.h"
|
||||
|
||||
#define APPLICATION_PART "os"
|
||||
#define MMC_BOOT_CONTROL_ID 0
|
||||
|
||||
static int do_mmc_boot(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0, mmc_id = MMC_BOOT_CONTROL_ID;
|
||||
int ret = 0, mmc_id = 0;
|
||||
enum boot_device bd;
|
||||
struct aic_sdmc *host = NULL;
|
||||
struct aic_partition *part = NULL, *parts = NULL;
|
||||
struct spl_load_info info;
|
||||
ulong entry_point;
|
||||
|
||||
bd = aic_get_boot_device();
|
||||
if (BD_SDMC0 == bd) {
|
||||
mmc_id = 0;
|
||||
} else if (BD_SDMC1 == bd) {
|
||||
mmc_id = 1;
|
||||
}
|
||||
|
||||
ret = mmc_init(mmc_id);
|
||||
if (ret) {
|
||||
printf("sdmc %d init failed.\n", mmc_id);
|
||||
|
||||
@@ -13,17 +13,18 @@
|
||||
#include <console.h>
|
||||
#include <aic_common.h>
|
||||
#include <aic_errno.h>
|
||||
#include <boot_param.h>
|
||||
#include <mmc.h>
|
||||
#include <image.h>
|
||||
#include <boot.h>
|
||||
#include <hexdump.h>
|
||||
|
||||
#define APPLICATION_PART "os"
|
||||
#define MMC_BOOT_CONTROL_ID 0
|
||||
|
||||
static int do_mmc_boot(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0, mmc_id = MMC_BOOT_CONTROL_ID;
|
||||
int ret = 0, mmc_id = 0;
|
||||
enum boot_device bd;
|
||||
struct image_header *head = NULL;
|
||||
struct aic_sdmc *host = NULL;
|
||||
struct aic_partition *part = NULL, *parts = NULL;
|
||||
@@ -31,6 +32,13 @@ static int do_mmc_boot(int argc, char *argv[])
|
||||
u64 blkstart, blkcnt;
|
||||
u32 start_us;
|
||||
|
||||
bd = aic_get_boot_device();
|
||||
if (BD_SDMC0 == bd) {
|
||||
mmc_id = 0;
|
||||
} else if (BD_SDMC1 == bd) {
|
||||
mmc_id = 1;
|
||||
}
|
||||
|
||||
ret = mmc_init(mmc_id);
|
||||
if (ret) {
|
||||
printf("sdmc %d init failed.\n", mmc_id);
|
||||
|
||||
167
application/baremetal/bootloader/cmd/part.c
Normal file
167
application/baremetal/bootloader/cmd/part.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Artinchip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Wu Dehuang <dehuang.wu@artinchip.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <console.h>
|
||||
#include <mmc.h>
|
||||
#include <disk_part.h>
|
||||
#include <hexdump.h>
|
||||
|
||||
static struct aic_sdmc *mmc_host = NULL;
|
||||
|
||||
#define PART_HELP \
|
||||
"Partition command:\n" \
|
||||
" part init <id> \n" \
|
||||
" <id> is mmc id." \
|
||||
" part list\n" \
|
||||
" part dump\n" \
|
||||
" part gptwrite [partition string]\n" \
|
||||
" e.g.: \n" \
|
||||
" part init 0\n" \
|
||||
" part list\n" \
|
||||
" part dump\n" \
|
||||
" part gptwrite 256k@0x4400(spl),8m(os),12m(rodata),35m(data)\n"
|
||||
|
||||
static void cmd_part_help(void)
|
||||
{
|
||||
puts(PART_HELP);
|
||||
}
|
||||
|
||||
static unsigned long mmc_write(struct blk_desc *block_dev, u64 start,
|
||||
u64 blkcnt, void *buffer)
|
||||
{
|
||||
return mmc_bwrite(block_dev->priv, start, blkcnt, buffer);
|
||||
}
|
||||
|
||||
static unsigned long mmc_read(struct blk_desc *block_dev, u64 start, u64 blkcnt,
|
||||
const void *buffer)
|
||||
{
|
||||
return mmc_bread(block_dev->priv, start, blkcnt, (void *)buffer);
|
||||
}
|
||||
|
||||
static int cmd_part_init(int id)
|
||||
{
|
||||
struct aic_sdmc *host = NULL;
|
||||
struct disk_blk_ops ops;
|
||||
int ret;
|
||||
|
||||
ret = mmc_init(id);
|
||||
if (ret) {
|
||||
printf("sdmc %d init failed.\n", id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
host = find_mmc_dev_by_index(id);
|
||||
if (!host) {
|
||||
pr_err("find mmc dev failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mmc_host = host;
|
||||
|
||||
ops.blk_write = mmc_write;
|
||||
ops.blk_read = mmc_read;
|
||||
aic_disk_part_set_ops(&ops);
|
||||
|
||||
printf("mmc controller id %d\n", id);
|
||||
printf("Capacity %d MB\n", mmc_host->dev->card_capacity >> 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_part_list(void)
|
||||
{
|
||||
struct blk_desc dev_desc;
|
||||
struct aic_partition *parts, *p;
|
||||
dev_desc.blksz = 512;
|
||||
dev_desc.lba_count = mmc_host->dev->card_capacity * 2;
|
||||
dev_desc.priv = mmc_host;
|
||||
|
||||
parts = aic_disk_get_parts(&dev_desc);
|
||||
|
||||
p = parts;
|
||||
while (p) {
|
||||
printf("Start: 0x%08llx; Size: 0x%08llx; %s\n", p->start, p->size, p->name);
|
||||
p = p->next;
|
||||
}
|
||||
if (parts)
|
||||
aic_part_free(parts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_part_dump_gpt(void)
|
||||
{
|
||||
struct blk_desc dev_desc;
|
||||
dev_desc.blksz = 512;
|
||||
dev_desc.lba_count = mmc_host->dev->card_capacity * 2;
|
||||
dev_desc.priv = mmc_host;
|
||||
|
||||
aic_disk_dump_parts(&dev_desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_gpt_write(char *partstr)
|
||||
{
|
||||
struct aic_partition *partition;
|
||||
struct blk_desc dev_desc;
|
||||
int ret;
|
||||
|
||||
partition = aic_part_gpt_parse(partstr);
|
||||
|
||||
if (partition == NULL)
|
||||
return -1;
|
||||
dev_desc.blksz = 512;
|
||||
dev_desc.lba_count = mmc_host->dev->card_capacity * 2;
|
||||
dev_desc.priv = mmc_host;
|
||||
|
||||
ret = aic_disk_write_gpt(&dev_desc, partition);
|
||||
if (ret) {
|
||||
printf("Write PART table failed.\n");
|
||||
}
|
||||
aic_part_free(partition);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_part(int argc, char *argv[])
|
||||
{
|
||||
char *cmd = NULL, *part;
|
||||
unsigned long id;
|
||||
|
||||
cmd = argv[1];
|
||||
if (argc == 2) {
|
||||
if (!strcmp(cmd, "list")) {
|
||||
cmd_part_list();
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(cmd, "dump")) {
|
||||
cmd_part_dump_gpt();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (argc >= 3) {
|
||||
if (!strcmp(cmd, "init")) {
|
||||
id = strtol(argv[2], NULL, 0);
|
||||
cmd_part_init(id);
|
||||
return 0;
|
||||
} else if (!strcmp(cmd, "gptwrite")) {
|
||||
part = argv[2];
|
||||
printf("Part: %s\n", part);
|
||||
cmd_gpt_write(part);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_part_help();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CONSOLE_CMD(part, do_part, "Partition util");
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <boot.h>
|
||||
#include <aic_core.h>
|
||||
#include <aic_flash_xip_def.h>
|
||||
#include "fitimage.h"
|
||||
|
||||
#if defined(AIC_BOOTLOADER_CMD_XIP_BOOT) && defined(AIC_QSPI_DRV_V11)
|
||||
|
||||
@@ -49,7 +50,7 @@ static int aic_xip_init(struct mtd_dev *mtd, u32 msk, u32 val)
|
||||
id = ((flash->chip.mf_id << 16) | (flash->chip.type_id << 8) |
|
||||
(flash->chip.capacity_id << 0));
|
||||
|
||||
printf("XIP flasd ID: 0x%x\n", id);
|
||||
printf("XIP flash ID: 0x%x\n", id);
|
||||
|
||||
xip_cfg = get_xip_device_cfg(id, msk, val);
|
||||
if (xip_cfg == NULL) {
|
||||
@@ -82,34 +83,37 @@ static struct mtd_dev *nor_flash_init(void)
|
||||
return mtd;
|
||||
}
|
||||
|
||||
static void *get_start_entry(struct mtd_dev *mtd)
|
||||
{
|
||||
return (void *)((unsigned long)mtd->start + FLASH_XIP_BASE + AIC_HEAD_SIZE);
|
||||
}
|
||||
|
||||
static int do_xip_boot(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
struct mtd_dev *mtd;
|
||||
void (*ep)(void);
|
||||
ulong entry_point;
|
||||
struct spl_load_info info;
|
||||
|
||||
mtd = nor_flash_init();
|
||||
if (!mtd) {
|
||||
printf("XIP boot failed ...\n");
|
||||
}
|
||||
|
||||
//msk = CMD_PROTO_QIO; //val = CMD_PROTO_QIO;
|
||||
aic_xip_init(mtd, CMD_PROTO_QIO, CMD_PROTO_QIO);
|
||||
ep = get_start_entry(mtd);
|
||||
|
||||
// need to delay, otherwise bootup unstable.
|
||||
aicos_udelay(1000 * 100);
|
||||
|
||||
printf("XIP boot, start entry: 0x%lx, used %llu us...\n", (unsigned long)ep, aic_get_time_us());
|
||||
info.dev = (void *)mtd;
|
||||
info.dev_type = DEVICE_XIPNOR;
|
||||
info.bl_len = 1;
|
||||
info.priv = (void *)((unsigned long)mtd->start + FLASH_XIP_BASE);
|
||||
|
||||
ret = spl_load_simple_fit(&info, &entry_point);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* boot */
|
||||
aicos_dcache_clean();
|
||||
ep();
|
||||
boot_app((void *)entry_point);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ typedef enum
|
||||
DEVICE_MMC,
|
||||
DEVICE_SPINAND,
|
||||
DEVICE_SPINOR,
|
||||
DEVICE_XIPNOR,
|
||||
} boot_dev_type;
|
||||
|
||||
/**
|
||||
|
||||
59
application/baremetal/bootloader/include/sparse_format.h
Normal file
59
application/baremetal/bootloader/include/sparse_format.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* This is from the Android Project,
|
||||
* Repository: https://android.googlesource.com/platform/system/core
|
||||
* File: libsparse/sparse_format.h
|
||||
* Commit: 28fa5bc347390480fe190294c6c385b6a9f0d68b
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*/
|
||||
|
||||
#ifndef _LIBSPARSE_SPARSE_FORMAT_H_
|
||||
#define _LIBSPARSE_SPARSE_FORMAT_H_
|
||||
#include <aic_common.h>
|
||||
|
||||
typedef struct sparse_header {
|
||||
u32 magic; /* 0xed26ff3a */
|
||||
u16 major_version; /* (0x1) - reject images with higher major versions */
|
||||
u16 minor_version; /* (0x0) - allow images with higer minor versions */
|
||||
u16 file_hdr_sz; /* 28 bytes for first revision of the file format */
|
||||
u16 chunk_hdr_sz; /* 12 bytes for first revision of the file format */
|
||||
u32 blk_sz; /* block size in bytes, must be a multiple of 4 (4096) */
|
||||
u32 total_blks; /* total blocks in the non-sparse output image */
|
||||
u32 total_chunks; /* total chunks in the sparse input image */
|
||||
u32 image_checksum; /* CRC32 checksum of the original data, counting "don't care" */
|
||||
/* as 0. Standard 802.3 polynomial, use a Public Domain */
|
||||
/* table implementation */
|
||||
} sparse_header_t;
|
||||
|
||||
#define SPARSE_HEADER_MAGIC 0xed26ff3a
|
||||
|
||||
#define CHUNK_TYPE_RAW 0xCAC1
|
||||
#define CHUNK_TYPE_FILL 0xCAC2
|
||||
#define CHUNK_TYPE_DONT_CARE 0xCAC3
|
||||
#define CHUNK_TYPE_CRC32 0xCAC4
|
||||
|
||||
typedef struct chunk_header {
|
||||
u16 chunk_type; /* 0xCAC1 -> raw; 0xCAC2 -> fill; 0xCAC3 -> don't care */
|
||||
u16 reserved1;
|
||||
u32 chunk_sz; /* in blocks in output image */
|
||||
u32 total_sz; /* in bytes of chunk input file including chunk header and data */
|
||||
} chunk_header_t;
|
||||
|
||||
/* Following a Raw or Fill or CRC32 chunk is data.
|
||||
* For a Raw chunk, it's the data in chunk_sz * blk_sz.
|
||||
* For a Fill chunk, it's 4 bytes of the fill data.
|
||||
* For a CRC32 chunk, it's 4 bytes of CRC32
|
||||
*/
|
||||
|
||||
static inline int is_sparse_image(void *buf)
|
||||
{
|
||||
sparse_header_t *s_header = (sparse_header_t *)buf;
|
||||
|
||||
if ((le32_to_cpu(s_header->magic) == SPARSE_HEADER_MAGIC) &&
|
||||
(le16_to_cpu(s_header->major_version) == 1))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -120,6 +120,8 @@ static void CMD_SET_FWC_META_end(struct upg_cmd *cmd)
|
||||
set_current_device_id(0);
|
||||
}
|
||||
|
||||
fwc->start_us = aic_get_time_us();
|
||||
|
||||
dev_type = get_current_device_type();
|
||||
printf(" Media: %s(%d)\n", get_current_device_name(dev_type),
|
||||
dev_type);
|
||||
@@ -338,6 +340,8 @@ static void CMD_SEND_FWC_DATA_end(struct upg_cmd *cmd)
|
||||
{
|
||||
enum upg_dev_type dev_type;
|
||||
struct fwc_info *fwc;
|
||||
u64 total_len = 0;
|
||||
u32 start_us;
|
||||
|
||||
fwc = (struct fwc_info *)cmd->priv;
|
||||
|
||||
@@ -371,6 +375,15 @@ static void CMD_SEND_FWC_DATA_end(struct upg_cmd *cmd)
|
||||
cmd->priv = 0;
|
||||
cmd_state_set_next(cmd, CMD_STATE_IDLE);
|
||||
}
|
||||
|
||||
total_len = fwc->trans_size;
|
||||
start_us = aic_get_time_us() - fwc->start_us;
|
||||
pr_info(" Partition: %s programming done.\n", fwc->meta.partition);
|
||||
pr_info(" Used time: %u.%u sec, Speed: %lu.%lu KB/s.\n",
|
||||
start_us / 1000000, start_us / 1000 % 1000,
|
||||
(ulong)((total_len * 1000000) / start_us / 1024),
|
||||
(ulong)((total_len * 1000000) / start_us % 1024));
|
||||
|
||||
pr_debug("%s, l: %d\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,17 +7,29 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <aic_common.h>
|
||||
#include <aic_core.h>
|
||||
#include <aicupg.h>
|
||||
#include <mmc.h>
|
||||
#include <sparse_format.h>
|
||||
#include <partition_table.h>
|
||||
#include <disk_part.h>
|
||||
#include "upg_internal.h"
|
||||
|
||||
#define MMC_BLOCK_SIZE 512
|
||||
#define SPARSE_FILLBUF_SIZE (1024 * 1024)
|
||||
|
||||
struct aicupg_mmc_priv {
|
||||
struct aic_sdmc *host;
|
||||
struct aic_partition *parts;
|
||||
sparse_header_t sparse_header;
|
||||
chunk_header_t chunk_header;
|
||||
unsigned char remain_data[MMC_BLOCK_SIZE];
|
||||
unsigned int remain_len;
|
||||
ulong blkstart;
|
||||
int cur_chunk;
|
||||
int cur_chunk_remain_data_sz;
|
||||
int cur_chunk_burned_data_sz;
|
||||
int is_sparse;
|
||||
};
|
||||
|
||||
int mmc_is_exist()
|
||||
@@ -38,10 +50,24 @@ s32 mmc_fwc_prepare(struct fwc_info *fwc, u32 mmc_id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned long mmc_write(struct blk_desc *block_dev, u64 start,
|
||||
u64 blkcnt, void *buffer)
|
||||
{
|
||||
return mmc_bwrite(block_dev->priv, start, blkcnt, buffer);
|
||||
}
|
||||
|
||||
static unsigned long mmc_read(struct blk_desc *block_dev, u64 start, u64 blkcnt,
|
||||
const void *buffer)
|
||||
{
|
||||
return mmc_bread(block_dev->priv, start, blkcnt, (void *)buffer);
|
||||
}
|
||||
|
||||
void mmc_fwc_start(struct fwc_info *fwc)
|
||||
{
|
||||
struct aicupg_mmc_priv *priv;
|
||||
int mmc_id = 0;
|
||||
struct disk_blk_ops ops;
|
||||
struct blk_desc dev_desc;
|
||||
int mmc_id = 0, ret;
|
||||
|
||||
mmc_id = get_current_device_id();
|
||||
|
||||
@@ -67,6 +93,19 @@ void mmc_fwc_start(struct fwc_info *fwc)
|
||||
fwc->burn_result = 0;
|
||||
fwc->run_result = 0;
|
||||
|
||||
ops.blk_write = mmc_write;
|
||||
ops.blk_read = mmc_read;
|
||||
aic_disk_part_set_ops(&ops);
|
||||
dev_desc.blksz = MMC_BLOCK_SIZE;
|
||||
dev_desc.lba_count = priv->host->dev->card_capacity * 2;
|
||||
dev_desc.priv = priv->host;
|
||||
|
||||
ret = aic_disk_write_gpt(&dev_desc, priv->parts);
|
||||
if (ret) {
|
||||
printf("Write PART table failed.\n");
|
||||
}
|
||||
|
||||
mmc_block_refresh(priv->host);
|
||||
return;
|
||||
out:
|
||||
if (priv->parts)
|
||||
@@ -76,7 +115,333 @@ out:
|
||||
free(priv);
|
||||
}
|
||||
|
||||
s32 mmc_fwc_data_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
s32 mmc_fwc_sparse_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
{
|
||||
struct aicupg_mmc_priv *priv;
|
||||
struct aic_partition *parts;
|
||||
sparse_header_t *sheader;
|
||||
chunk_header_t *cheader;
|
||||
u8 *wbuf, *p;
|
||||
s32 clen = 0, remain, total_len;
|
||||
u32 chunk;
|
||||
u64 chunk_data_sz, chunk_blkcnt, remain_blkcnt;
|
||||
u32 total_blocks = 0, blks;
|
||||
u32 remain_blks, redund_blks, erase_group;
|
||||
u32 *fill_buf, fill_val, fill_buf_num_blks;
|
||||
int i, j, break_flag = 0;
|
||||
|
||||
wbuf = malloc(ROUNDUP(len + MMC_BLOCK_SIZE, fwc->block_size));
|
||||
if (!wbuf) {
|
||||
pr_err("malloc failed.\n");
|
||||
return 0;
|
||||
}
|
||||
p = wbuf;
|
||||
|
||||
priv = (struct aicupg_mmc_priv *)fwc->priv;
|
||||
if (!priv) {
|
||||
pr_err("MMC FWC get priv failed.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (priv->remain_len > 0) {
|
||||
memcpy(wbuf, priv->remain_data, priv->remain_len);
|
||||
memcpy(wbuf + priv->remain_len, buf, len);
|
||||
} else {
|
||||
memcpy(wbuf, buf, len);
|
||||
}
|
||||
|
||||
total_len = (priv->remain_len + len);
|
||||
remain = total_len;
|
||||
|
||||
parts = priv->parts;
|
||||
while (parts) {
|
||||
if (!strcmp(parts->name, fwc->meta.partition))
|
||||
break;
|
||||
|
||||
parts = parts->next;
|
||||
}
|
||||
|
||||
if (!parts)
|
||||
pr_err("not find %s part info.\n", fwc->meta.partition);
|
||||
|
||||
sheader = &(priv->sparse_header);
|
||||
if (is_sparse_image(wbuf)) {
|
||||
priv->is_sparse = 1;
|
||||
memcpy(sheader, wbuf, sizeof(sparse_header_t));
|
||||
wbuf += sheader->file_hdr_sz;
|
||||
clen += sheader->file_hdr_sz;
|
||||
remain -= sheader->file_hdr_sz;
|
||||
if (sheader->file_hdr_sz > sizeof(sparse_header_t)) {
|
||||
wbuf += (sheader->file_hdr_sz - sizeof(sparse_header_t));
|
||||
clen += (sheader->file_hdr_sz - sizeof(sparse_header_t));
|
||||
remain -= (sheader->file_hdr_sz - sizeof(sparse_header_t));
|
||||
}
|
||||
pr_info("=== Sparse Image Header ===\n");
|
||||
pr_info("magic: 0x%x\n", sheader->magic);
|
||||
pr_info("major_version: 0x%x\n", sheader->major_version);
|
||||
pr_info("minor_version: 0x%x\n", sheader->minor_version);
|
||||
pr_info("file_hdr_sz: %d\n", sheader->file_hdr_sz);
|
||||
pr_info("chunk_hdr_sz: %d\n", sheader->chunk_hdr_sz);
|
||||
pr_info("blk_sz: %d\n", sheader->blk_sz);
|
||||
pr_info("total_blks: %d\n", sheader->total_blks);
|
||||
pr_info("total_chunks: %d\n", sheader->total_chunks);
|
||||
}
|
||||
|
||||
pr_debug("Flashing Sparse Image\n");
|
||||
|
||||
/* Start processing chunks */
|
||||
for (chunk = priv->cur_chunk; chunk < sheader->total_chunks; chunk++) {
|
||||
/* Read and skip over chunk header */
|
||||
cheader = (chunk_header_t *)wbuf;
|
||||
|
||||
if (cheader->chunk_type != CHUNK_TYPE_RAW) {
|
||||
pr_debug("=== Chunk Header ===\n");
|
||||
pr_debug("chunk_type: 0x%x\n", cheader->chunk_type);
|
||||
pr_debug("chunk_data_sz: 0x%x\n", cheader->chunk_sz);
|
||||
pr_debug("total_size: 0x%x\n", cheader->total_sz);
|
||||
}
|
||||
|
||||
if (cheader->chunk_type != CHUNK_TYPE_RAW &&
|
||||
cheader->chunk_type != CHUNK_TYPE_FILL &&
|
||||
cheader->chunk_type != CHUNK_TYPE_DONT_CARE &&
|
||||
cheader->chunk_type != CHUNK_TYPE_CRC32) {
|
||||
cheader = &(priv->chunk_header);
|
||||
chunk_data_sz = priv->cur_chunk_remain_data_sz;
|
||||
} else {
|
||||
wbuf += sheader->chunk_hdr_sz;
|
||||
clen += sheader->chunk_hdr_sz;
|
||||
remain -= sheader->chunk_hdr_sz;
|
||||
memcpy(&(priv->chunk_header), cheader, sizeof(chunk_header_t));
|
||||
if (sheader->chunk_hdr_sz > sizeof(chunk_header_t)) {
|
||||
/*
|
||||
* Skip the remaining bytes in a header that is longer
|
||||
* than we expected.
|
||||
*/
|
||||
wbuf += (sheader->chunk_hdr_sz - sizeof(chunk_header_t));
|
||||
clen += (sheader->chunk_hdr_sz - sizeof(chunk_header_t));
|
||||
remain -= (sheader->chunk_hdr_sz - sizeof(chunk_header_t));
|
||||
}
|
||||
chunk_data_sz = ((u64)sheader->blk_sz) * cheader->chunk_sz;
|
||||
priv->cur_chunk_remain_data_sz = chunk_data_sz;
|
||||
priv->cur_chunk_burned_data_sz = 0;
|
||||
}
|
||||
|
||||
chunk_blkcnt = DIV_ROUND_UP(chunk_data_sz, MMC_BLOCK_SIZE);
|
||||
remain_blkcnt = remain / MMC_BLOCK_SIZE;
|
||||
switch (cheader->chunk_type) {
|
||||
case CHUNK_TYPE_RAW:
|
||||
if (cheader->total_sz !=
|
||||
(sheader->chunk_hdr_sz + chunk_data_sz +
|
||||
priv->cur_chunk_burned_data_sz)) {
|
||||
pr_err("Bogus chunk size for chunk type Raw\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (priv->blkstart + chunk_blkcnt >
|
||||
(parts->size / MMC_BLOCK_SIZE)) {
|
||||
pr_err("Request would exceed partition size!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (remain_blkcnt > chunk_blkcnt &&
|
||||
(remain - chunk_data_sz) >= 16) {
|
||||
blks = mmc_bwrite(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
chunk_blkcnt, wbuf);
|
||||
if (blks <
|
||||
chunk_blkcnt) { /* blks might be > blkcnt (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%u]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
blks);
|
||||
goto out;
|
||||
}
|
||||
remain = remain - chunk_data_sz;
|
||||
priv->cur_chunk_remain_data_sz = 0;
|
||||
priv->cur_chunk_burned_data_sz += chunk_data_sz;
|
||||
} else {
|
||||
blks = mmc_bwrite(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
remain_blkcnt, wbuf);
|
||||
if (blks <
|
||||
remain_blkcnt) { /* blks might be > blkcnt (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%u]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
blks);
|
||||
goto out;
|
||||
}
|
||||
priv->cur_chunk_remain_data_sz -=
|
||||
remain_blkcnt * MMC_BLOCK_SIZE;
|
||||
priv->cur_chunk_burned_data_sz +=
|
||||
remain_blkcnt * MMC_BLOCK_SIZE;
|
||||
remain = remain % MMC_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
priv->blkstart += blks;
|
||||
total_blocks += blks;
|
||||
wbuf += blks * MMC_BLOCK_SIZE;
|
||||
clen += blks * MMC_BLOCK_SIZE;
|
||||
if ((priv->cur_chunk_remain_data_sz > 0 &&
|
||||
(remain > 0 && remain < MMC_BLOCK_SIZE)) ||
|
||||
remain < sizeof(chunk_header_t))
|
||||
break_flag = 1;
|
||||
|
||||
break;
|
||||
|
||||
case CHUNK_TYPE_FILL:
|
||||
if (cheader->total_sz !=
|
||||
(sheader->chunk_hdr_sz + sizeof(uint32_t))) {
|
||||
pr_err("Bogus chunk size for chunk type FILL\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
fill_buf = (u32 *)aicos_malloc_align(
|
||||
0, ROUNDUP(SPARSE_FILLBUF_SIZE, CACHE_LINE_SIZE),
|
||||
CACHE_LINE_SIZE);
|
||||
if (!fill_buf) {
|
||||
pr_err("Malloc failed for: CHUNK_TYPE_FILL\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
fill_val = *(uint32_t *)wbuf;
|
||||
wbuf = (u8 *)wbuf + sizeof(u32);
|
||||
clen += sizeof(uint32_t);
|
||||
remain -= sizeof(uint32_t);
|
||||
if (remain < sizeof(chunk_header_t))
|
||||
break_flag = 1;
|
||||
|
||||
if (priv->blkstart + chunk_blkcnt >
|
||||
(parts->size / MMC_BLOCK_SIZE)) {
|
||||
pr_err("Request would exceed partition size!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < (SPARSE_FILLBUF_SIZE / sizeof(fill_val)); i++)
|
||||
fill_buf[i] = fill_val;
|
||||
|
||||
remain_blks =
|
||||
ROUNDUP((parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
0x400) -
|
||||
((parts->start / MMC_BLOCK_SIZE) + priv->blkstart);
|
||||
if (chunk_blkcnt >= (remain_blks + 0x400) &&
|
||||
fill_val == 0x0) { // 512K
|
||||
blks = mmc_bwrite(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
remain_blks, (u8 *)fill_buf);
|
||||
if (blks <
|
||||
remain_blks) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%d]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
remain_blks);
|
||||
free(fill_buf);
|
||||
goto out;
|
||||
}
|
||||
priv->blkstart += blks;
|
||||
|
||||
erase_group = (chunk_blkcnt - remain_blks) / 0x400;
|
||||
blks = mmc_berase(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
erase_group * 0x400);
|
||||
if (blks !=
|
||||
(erase_group *
|
||||
0x400)) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Erase failed, block %llu[%d]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
erase_group * 0x400);
|
||||
free(fill_buf);
|
||||
goto out;
|
||||
}
|
||||
priv->blkstart += blks;
|
||||
|
||||
redund_blks =
|
||||
chunk_blkcnt - remain_blks - (erase_group * 0x400);
|
||||
blks = mmc_bwrite(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
redund_blks, (u8 *)fill_buf);
|
||||
if (blks <
|
||||
redund_blks) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%d]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) + priv->blkstart,
|
||||
redund_blks);
|
||||
free(fill_buf);
|
||||
goto out;
|
||||
}
|
||||
priv->blkstart += blks;
|
||||
} else {
|
||||
fill_buf_num_blks = SPARSE_FILLBUF_SIZE / MMC_BLOCK_SIZE;
|
||||
for (i = 0; i < chunk_blkcnt;) {
|
||||
j = chunk_blkcnt - i;
|
||||
if (j > fill_buf_num_blks)
|
||||
j = fill_buf_num_blks;
|
||||
|
||||
blks = mmc_bwrite(priv->host,
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
j, (u8 *)fill_buf);
|
||||
if (blks <
|
||||
j) { /* blks might be > j (eg. NAND bad-blocks) */
|
||||
pr_err("Write failed, block %llu[%d]\n",
|
||||
(parts->start / MMC_BLOCK_SIZE) +
|
||||
priv->blkstart,
|
||||
j);
|
||||
free(fill_buf);
|
||||
goto out;
|
||||
}
|
||||
priv->blkstart += blks;
|
||||
i += j;
|
||||
}
|
||||
}
|
||||
total_blocks += DIV_ROUND_UP(chunk_data_sz, sheader->blk_sz);
|
||||
|
||||
free(fill_buf);
|
||||
break;
|
||||
|
||||
case CHUNK_TYPE_DONT_CARE:
|
||||
priv->blkstart += chunk_blkcnt;
|
||||
total_blocks += cheader->chunk_sz;
|
||||
break;
|
||||
|
||||
case CHUNK_TYPE_CRC32:
|
||||
if (cheader->total_sz != sheader->chunk_hdr_sz) {
|
||||
pr_err("Bogus chunk size for chunk type Dont Care\n");
|
||||
goto out;
|
||||
}
|
||||
total_blocks += cheader->chunk_sz;
|
||||
wbuf += chunk_data_sz;
|
||||
clen += chunk_data_sz;
|
||||
remain -= chunk_data_sz;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown chunk type: %x\n", cheader->chunk_type);
|
||||
cheader = &(priv->chunk_header);
|
||||
}
|
||||
|
||||
if (break_flag)
|
||||
break;
|
||||
}
|
||||
|
||||
priv->remain_len = remain;
|
||||
if (priv->remain_len) {
|
||||
priv->cur_chunk = chunk;
|
||||
memcpy(priv->remain_data, wbuf, priv->remain_len);
|
||||
}
|
||||
|
||||
fwc->trans_size += clen;
|
||||
|
||||
pr_debug("%s, data len %d, trans len %d\n", __func__, len, fwc->trans_size);
|
||||
|
||||
out:
|
||||
if (p)
|
||||
free(p);
|
||||
return len;
|
||||
}
|
||||
|
||||
s32 mmc_fwc_raw_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
{
|
||||
struct aicupg_mmc_priv *priv;
|
||||
struct aic_partition *parts = NULL;
|
||||
@@ -106,7 +471,7 @@ s32 mmc_fwc_data_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
if (len % MMC_BLOCK_SIZE)
|
||||
blkcnt++;
|
||||
|
||||
if ((blkstart + blkcnt) > parts->size) {
|
||||
if ((blkstart + blkcnt) > (parts->size / MMC_BLOCK_SIZE)) {
|
||||
pr_err("Data size exceed the partition size.\n");
|
||||
goto out;
|
||||
}
|
||||
@@ -129,6 +494,20 @@ out:
|
||||
return clen;
|
||||
}
|
||||
|
||||
s32 mmc_fwc_data_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
{
|
||||
struct aicupg_mmc_priv *priv;
|
||||
|
||||
priv = (struct aicupg_mmc_priv *)fwc->priv;
|
||||
if (!is_sparse_image(buf) && !priv->is_sparse) {
|
||||
pr_debug("Not a sparse image\n");
|
||||
return mmc_fwc_raw_write(fwc, buf, len);
|
||||
} else {
|
||||
pr_debug("A sparse image\n");
|
||||
return mmc_fwc_sparse_write(fwc, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
s32 mmc_fwc_data_read(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -196,8 +196,8 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
struct aicupg_nand_priv *priv;
|
||||
struct mtd_dev *mtd;
|
||||
unsigned long offset, erase_offset;
|
||||
int i, dolen = 0, ret = 0, pages = 0;
|
||||
int total_len = 0, data_len = 0, remain_offset = 0;
|
||||
int i, dolen = 0, ret = 0;
|
||||
int total_len = 0, remain_offset = 0;
|
||||
u8 *wbuf = NULL, *pbuf = NULL;
|
||||
|
||||
wbuf = malloc(ROUNDUP(len, fwc->block_size));
|
||||
@@ -215,7 +215,6 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
}
|
||||
|
||||
total_len = (priv->remain_len + len);
|
||||
pages = total_len / fwc->block_size;
|
||||
if (total_len % fwc->block_size) {
|
||||
priv->remain_len = total_len % fwc->block_size;
|
||||
remain_offset = total_len - priv->remain_len;
|
||||
@@ -230,23 +229,23 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
if (!mtd)
|
||||
continue;
|
||||
|
||||
data_len = pages * mtd->writesize;
|
||||
offset = priv->start_offset[i];
|
||||
if ((offset + data_len) > (mtd->size)) {
|
||||
if ((offset + len) > (mtd->size)) {
|
||||
pr_err("Not enough space to write mtd %s\n", mtd->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* erase 1 sector when offset+len more than erased address */
|
||||
erase_offset = priv->erase_offset[i];
|
||||
while ((offset + data_len) > erase_offset) {
|
||||
while ((offset + len) > erase_offset) {
|
||||
if (mtd_block_isbad(mtd, erase_offset)) {
|
||||
pr_err("Erase block is bad, skip it.\n");
|
||||
priv->erase_offset[i] = erase_offset + mtd->erasesize;
|
||||
erase_offset = priv->erase_offset[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = mtd_erase(mtd, erase_offset, mtd->erasesize);
|
||||
ret = mtd_erase(mtd, erase_offset, ROUNDUP(len, mtd->erasesize));
|
||||
if (ret) {
|
||||
pr_err("Erase block is bad, mark it.\n");
|
||||
ret = mtd_block_markbad(mtd, erase_offset);
|
||||
@@ -255,12 +254,12 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
|
||||
continue;
|
||||
}
|
||||
priv->erase_offset[i] = erase_offset + mtd->erasesize;
|
||||
priv->erase_offset[i] = erase_offset + ROUNDUP(len, mtd->erasesize);
|
||||
erase_offset = priv->erase_offset[i];
|
||||
}
|
||||
|
||||
pbuf = wbuf;
|
||||
while (dolen < data_len) {
|
||||
while (dolen < len) {
|
||||
if (!data_is_blank(offset + dolen, pbuf + mtd->writesize, 64)) {
|
||||
if (mtd_block_isbad(mtd, ALIGN_DOWN(offset, mtd->erasesize))) {
|
||||
pr_err(" Write block is bad, skip it.\n");
|
||||
@@ -283,7 +282,7 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
pbuf += fwc->block_size;
|
||||
dolen += mtd->writesize;
|
||||
}
|
||||
priv->start_offset[i] = offset + data_len;
|
||||
priv->start_offset[i] = offset + len;
|
||||
}
|
||||
|
||||
pr_debug("%s, data len %d, trans len %d\n", __func__, len, fwc->trans_size);
|
||||
@@ -325,9 +324,10 @@ s32 nand_fwc_mtd_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
pr_err("Erase block is bad, skip it.\n");
|
||||
priv->erase_offset[i] = erase_offset + mtd->erasesize;
|
||||
erase_offset = priv->erase_offset[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = mtd_erase(mtd, erase_offset, mtd->erasesize);
|
||||
ret = mtd_erase(mtd, erase_offset, ROUNDUP(len, mtd->erasesize));
|
||||
if (ret) {
|
||||
pr_err("Erase block is bad, mark it.\n");
|
||||
ret = mtd_block_markbad(mtd, erase_offset);
|
||||
@@ -336,7 +336,7 @@ s32 nand_fwc_mtd_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
|
||||
continue;
|
||||
}
|
||||
priv->erase_offset[i] = erase_offset + mtd->erasesize;
|
||||
priv->erase_offset[i] = erase_offset + ROUNDUP(len, mtd->erasesize);
|
||||
erase_offset = priv->erase_offset[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -65,12 +65,21 @@ static s32 get_good_blocks_for_spl(struct mtd_dev *mtd, u32 *spl_blocks,
|
||||
ulong offset;
|
||||
s32 i, blkidx, ret = 0, cnt = 0;
|
||||
u8 buf[2];
|
||||
struct aic_spinand *flash = (struct aic_spinand *)mtd->priv;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
spl_blocks[i] = SPL_INVALID_BLOCK_IDX;
|
||||
|
||||
for (i = 0; i < SPL_CANDIDATE_BLOCK_NUM; i++) {
|
||||
blkidx = spl_candidate_block_table[i];
|
||||
|
||||
/* For multi-plane device, don't use block 1 & 3, because
|
||||
* boot rom cannot read data from block 1 and 3
|
||||
*/
|
||||
if ((flash->info->planes_per_lun != 1) &&
|
||||
(blkidx == 1 || blkidx == 3))
|
||||
continue;
|
||||
|
||||
offset = mtd->erasesize * blkidx;
|
||||
if (mtd_block_isbad(mtd, offset)) {
|
||||
pr_err("Block %d is bad.\n", blkidx);
|
||||
|
||||
@@ -142,12 +142,12 @@ s32 nor_fwc_data_write(struct fwc_info *fwc, u8 *buf, s32 len)
|
||||
/* erase 1 sector when offset+len more than erased address */
|
||||
erase_offset = priv->erase_offset[i];
|
||||
while ((offset + len) > erase_offset) {
|
||||
ret = mtd_erase(mtd, erase_offset, mtd->erasesize);
|
||||
ret = mtd_erase(mtd, erase_offset, ROUNDUP(len, mtd->erasesize));
|
||||
if (ret) {
|
||||
pr_err("MTD erase sector failed!\n");
|
||||
return 0;
|
||||
}
|
||||
priv->erase_offset[i] = erase_offset + mtd->erasesize;
|
||||
priv->erase_offset[i] = erase_offset + ROUNDUP(len, mtd->erasesize);
|
||||
erase_offset = priv->erase_offset[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ s32 aicupg_fat_write(char *image_name, char *protection,
|
||||
int i, cnt, ret;
|
||||
u32 start_us;
|
||||
ulong actread, write_len = 0;
|
||||
u64 total_len = 0;
|
||||
|
||||
pmeta = NULL;
|
||||
pmeta = (struct fwc_meta *)aicos_malloc_align(0, header->meta_size, FRAME_LIST_SIZE);
|
||||
@@ -155,12 +156,13 @@ s32 aicupg_fat_write(char *image_name, char *protection,
|
||||
write_len += ret;
|
||||
}
|
||||
|
||||
total_len = write_len;
|
||||
start_us = aic_get_time_us() - start_us;
|
||||
printf("All firmaware components programming done.\n");
|
||||
printf(" Used time: %d.%d sec, Speed: %ld.%ld MB/s.\n",
|
||||
printf(" Used time: %u.%u sec, Speed: %lu.%lu MB/s.\n",
|
||||
start_us / 1000000, start_us / 1000 % 1000,
|
||||
(write_len * 1000000 / start_us) / 1024 / 1024,
|
||||
(write_len * 1000000 / start_us) / 1024 % 1024);
|
||||
(ulong)((total_len * 1000000 / start_us) / 1024 / 1024),
|
||||
(ulong)((total_len * 1000000 / start_us) / 1024 % 1024));
|
||||
|
||||
aicos_free_align(0, pmeta);
|
||||
return write_len;
|
||||
|
||||
@@ -115,6 +115,7 @@ struct fwc_info {
|
||||
u32 calc_partition_crc;
|
||||
s32 burn_result;
|
||||
s32 run_result;
|
||||
u32 start_us;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
|
||||
@@ -651,7 +651,7 @@ static s32 fat_read_from_fatfs(struct fat_volume *vol, char *filename,
|
||||
s32 ret;
|
||||
|
||||
/* Reuse one global var to reduce memory use */
|
||||
file = malloc(sizeof(struct fat_file));
|
||||
file = aicos_malloc_align(0, sizeof(struct fat_file), CACHE_LINE_SIZE);
|
||||
if (!file) {
|
||||
pr_err("malloc fat file failed.\n");
|
||||
return -1;
|
||||
@@ -695,12 +695,12 @@ static s32 fat_read_from_fatfs(struct fat_volume *vol, char *filename,
|
||||
|
||||
*actread = min((u32)file->size, (u32)maxsize);
|
||||
|
||||
free(file);
|
||||
aicos_free(0, file);
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if (file)
|
||||
free(file);
|
||||
aicos_free(0, file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
#include <aic_core.h>
|
||||
#include <libfdt.h>
|
||||
#include <hexdump.h>
|
||||
#include <aic_crc32.h>
|
||||
#include "fitimage.h"
|
||||
|
||||
//#define CRC32_MTD_READ
|
||||
|
||||
int fit_find_config_node(const void *fdt)
|
||||
{
|
||||
const char *name;
|
||||
@@ -237,6 +240,9 @@ int fit_image_get_entry(const void *fit, int noffset, ulong *entry)
|
||||
return fit_image_get_address(fit, noffset, FIT_ENTRY_PROP, entry);
|
||||
}
|
||||
|
||||
/*
|
||||
* offset: The offset relative to the itb file start location
|
||||
*/
|
||||
static int spl_read(struct spl_load_info *info, ulong offset, void *buf, int size)
|
||||
{
|
||||
int rdlen = 0;
|
||||
@@ -261,6 +267,14 @@ static int spl_read(struct spl_load_info *info, ulong offset, void *buf, int siz
|
||||
rdlen = info->bl_len * blkcnt;
|
||||
rdlen = min(rdlen, size);
|
||||
#endif
|
||||
} else if (info->dev_type == DEVICE_XIPNOR) {
|
||||
ulong xip_base = (ulong)info->priv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
*(u8 *)(buf + i) = *(u8 *)(xip_base + offset + i);
|
||||
|
||||
rdlen = size;
|
||||
}
|
||||
|
||||
return rdlen;
|
||||
@@ -294,22 +308,27 @@ int spl_load_fit_image(struct spl_load_info *info, struct spl_fit_info *ctx, int
|
||||
if (external_data)
|
||||
{
|
||||
if (fit_image_get_data_size(fit, node, &length))
|
||||
return -1;
|
||||
goto __get_entry;
|
||||
|
||||
start_us = aic_get_time_us();
|
||||
ret = spl_read(info, offset, (u8 *)load_addr, length);
|
||||
show_speed("spl read", length, aic_get_time_us() - start_us);
|
||||
if (info->dev_type == DEVICE_XIPNOR && load_addr >= 0x60000000)
|
||||
goto __get_entry;
|
||||
else
|
||||
{
|
||||
start_us = aic_get_time_us();
|
||||
ret = spl_read(info, offset, (u8 *)load_addr, length);
|
||||
show_speed("spl read", length, aic_get_time_us() - start_us);
|
||||
|
||||
#ifdef CRC32_MTD_READ
|
||||
unsigned int crc32_val = crc32(0, NULL, 0);
|
||||
crc32_val = crc32(crc32_val, (u8 *)load_addr, length);
|
||||
printf("mtd read crc32 = 0x%x KB/s\n", crc32_val);
|
||||
unsigned int crc32_val = crc32(0, NULL, 0);
|
||||
crc32_val = crc32(crc32_val, (u8 *)load_addr, length);
|
||||
printf("mtd read crc32 = 0x%x KB/s\n", crc32_val);
|
||||
#endif
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("spl read external_data error\n");
|
||||
return -1;
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("spl read external_data error\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -318,6 +337,7 @@ int spl_load_fit_image(struct spl_load_info *info, struct spl_fit_info *ctx, int
|
||||
return -1;
|
||||
}
|
||||
|
||||
__get_entry:
|
||||
if (entry_point)
|
||||
{
|
||||
if (fit_image_get_entry(fit, node, entry_point))
|
||||
|
||||
@@ -64,11 +64,6 @@ static int board_init(enum boot_device bd)
|
||||
aic_board_pinmux_init();
|
||||
boot_time_trace("Clock and pinmux done");
|
||||
|
||||
#ifdef AIC_BOOTLOADER_PSRAM_EN
|
||||
/* psram init */
|
||||
aic_xspi_psram_init();
|
||||
boot_time_trace("PSRAM init done");
|
||||
#endif
|
||||
|
||||
#ifdef AIC_BOOTLOADER_AXICFG_SUPPORT
|
||||
for (int i = 0; i < HAL_AXICFG_PORT_MAX; i++) {
|
||||
@@ -106,6 +101,7 @@ int main(void)
|
||||
enum boot_device bd;
|
||||
int ctrlc = -1;
|
||||
s32 id = -1;
|
||||
s32 __attribute__((unused)) ret = -1;
|
||||
|
||||
boot_time_trace("Enter main");
|
||||
|
||||
@@ -133,10 +129,16 @@ int main(void)
|
||||
#if defined(AICUPG_UDISK_ENABLE)
|
||||
id = usbh_get_connect_id();
|
||||
boot_time_trace("UDISK checked");
|
||||
if (id < 0)
|
||||
if (id < 0) {
|
||||
pr_err("Not find udisk.\n");
|
||||
else
|
||||
bd = BD_UDISK;
|
||||
} else {
|
||||
if (id == 0)
|
||||
ret = console_run_cmd("aicupg fat udisk 0");
|
||||
else if (id == 1)
|
||||
ret = console_run_cmd("aicupg fat udisk 1");
|
||||
if (!ret)
|
||||
console_loop();
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
|
||||
@@ -20,13 +20,17 @@
|
||||
|
||||
static int do_reset_boot(int argc, char *argv[])
|
||||
{
|
||||
#ifdef AIC_WDT_DRV
|
||||
wdt_init();
|
||||
printf("Going to reboot ...\n");
|
||||
#endif
|
||||
#ifdef AIC_WRI_DRV
|
||||
aic_set_reboot_reason(REBOOT_REASON_CMD_REBOOT);
|
||||
#endif
|
||||
#ifdef AIC_WDT_DRV
|
||||
wdt_expire_now();
|
||||
while(1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
#include "drv_dma.h"
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_CHERRYUSB_HOST
|
||||
#include <usbh_core.h>
|
||||
#include <usbh_hub.h>
|
||||
#include <usb_hc.h>
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_USING_DFS
|
||||
#include <dfs.h>
|
||||
#include <dfs_fs.h>
|
||||
@@ -106,24 +112,51 @@ int main(void)
|
||||
pr_err("Failed to mount romfs\n");
|
||||
#endif
|
||||
|
||||
#ifdef AIC_SDMC_DRV
|
||||
#ifdef AIC_USING_SDMC0
|
||||
mmc_init(0);
|
||||
#endif
|
||||
#ifdef AIC_USING_SDMC1
|
||||
mmc_init(1);
|
||||
sdcard_hotplug_init();
|
||||
#endif
|
||||
|
||||
#if defined(LPKG_USING_DFS_ELMFAT) && defined(AIC_USING_SDMC0)
|
||||
if (dfs_mount("mmc0p2", "/rodata", "elm", 0, DEVICE_TYPE_SDMC_DISK) < 0)
|
||||
pr_err("Failed to mount mmc0p2 with FatFS\n");
|
||||
else
|
||||
printf("mount mmc0p2 ok\n");
|
||||
if (dfs_mount("mmc0p3", "/data", "elm", 0, DEVICE_TYPE_SDMC_DISK) < 0)
|
||||
pr_err("Failed to mount mmc0p3 with FatFS\n");
|
||||
else
|
||||
printf("mount mmc0p3 ok\n");
|
||||
#endif
|
||||
|
||||
#if defined(LPKG_USING_DFS_ELMFAT) && defined(AIC_SDMC_DRV)
|
||||
if (dfs_mount("sdmc", "/sdcard", "elm", 0, (const void *)SDMC_DISK) < 0)
|
||||
if (dfs_mount("sd1", "/sdcard", "elm", 0, DEVICE_TYPE_SDMC_DISK) < 0)
|
||||
pr_err("Failed to mount sdmc with FatFS\n");
|
||||
#endif
|
||||
|
||||
#ifdef AIC_SPINAND_DRV
|
||||
#if defined(AIC_SPINAND_DRV) || defined(AIC_SPINOR_DRV)
|
||||
mtd_probe();
|
||||
#endif
|
||||
|
||||
#if defined(LPKG_USING_DFS_ELMFAT) && defined(AIC_SPINAND_DRV)
|
||||
if (dfs_mount("rodata", "/rodata", "elm", 0,(const void *)SPINAND_DISK) < 0)
|
||||
#if defined(LPKG_USING_DFS_ELMFAT) && defined(AIC_USING_FS_IMAGE_TYPE_FATFS_FOR_0)
|
||||
#if defined(AIC_SPINAND_DRV)
|
||||
if (dfs_mount("rodata", "/rodata", "elm", 0, DEVICE_TYPE_SPINAND_DISK) < 0)
|
||||
pr_err("Failed to mount spinand with FatFS\n");
|
||||
#endif
|
||||
#if defined(AIC_SPINOR_DRV)
|
||||
if (dfs_mount("rodata", "/rodata", "elm", 0, DEVICE_TYPE_SPINOR_DISK) < 0)
|
||||
pr_err("Failed to mount spinor with FatFS\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LPKG_USING_DFS_ELMFAT) && defined(AIC_USING_FS_IMAGE_TYPE_FATFS_FOR_1)
|
||||
#if defined(AIC_SPINAND_DRV)
|
||||
if (dfs_mount("data", "/data", "elm", 0, DEVICE_TYPE_SPINAND_DISK) < 0)
|
||||
pr_err("Failed to mount spinand with FatFS\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef AIC_DISPLAY_DRV
|
||||
aicfb_probe();
|
||||
@@ -138,6 +171,22 @@ int main(void)
|
||||
aic_get_reboot_reason();
|
||||
aic_show_startup_time();
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_CHERRYUSB_DEVICE
|
||||
#ifdef LPKG_CHERRYUSB_DEVICE_MSC_TEMPLATE
|
||||
extern void msc_ram_init(void);
|
||||
msc_ram_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_CHERRYUSB_HOST
|
||||
usbh_init();
|
||||
while(1)
|
||||
{
|
||||
usbh_hub_poll();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_LWIP_EXAMPLES
|
||||
/* LwIP test loop */
|
||||
lwip_test_example_main_loop(NULL);
|
||||
@@ -149,26 +198,28 @@ int main(void)
|
||||
#endif /* LV_USE_LOG */
|
||||
lv_init();
|
||||
lv_port_disp_init();
|
||||
int end_flag = 0;
|
||||
#ifdef AIC_LVGL_GIF_DEMO
|
||||
void gif_ui_init(int *end_flag);
|
||||
gif_ui_init(&end_flag);
|
||||
#else
|
||||
lv_user_gui_init();
|
||||
|
||||
while(1)
|
||||
#endif
|
||||
while(!end_flag)
|
||||
{
|
||||
lv_task_handler();
|
||||
aicos_mdelay(1);
|
||||
}
|
||||
#endif /* AIC_LVGL_DEMO */
|
||||
#ifdef AIC_VE_TEST
|
||||
|
||||
#ifdef AIC_VE_TEST
|
||||
extern int do_pic_dec_test(int argc, char **argv);
|
||||
/* Main loop */
|
||||
aicos_mdelay(2000);
|
||||
while (1) {
|
||||
do_pic_dec_test(0,NULL);
|
||||
//break;
|
||||
}
|
||||
#else
|
||||
while (1) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef AIC_CONSOLE_BARE_DRV
|
||||
/* Console shell loop */
|
||||
|
||||
21
application/freertos/helloworld/SConscript
Normal file
21
application/freertos/helloworld/SConscript
Normal file
@@ -0,0 +1,21 @@
|
||||
Import('RTT_ROOT')
|
||||
Import('rtconfig')
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
CPPPATH = [cwd, ]
|
||||
|
||||
CFLAGS = ' -c -ffunction-sections'
|
||||
|
||||
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH, CFLAGS=CFLAGS)
|
||||
|
||||
lst = os.listdir(cwd)
|
||||
|
||||
for item in lst:
|
||||
ipath = '{}/SConscript'.format(item)
|
||||
if os.path.isfile(cwd + '/' + ipath) == False:
|
||||
continue
|
||||
group = group + SConscript(ipath)
|
||||
|
||||
Return('group')
|
||||
15
application/freertos/helloworld/cmd/SConscript
Normal file
15
application/freertos/helloworld/cmd/SConscript
Normal file
@@ -0,0 +1,15 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
Import('rtconfig')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
|
||||
CPPPATH = [cwd]
|
||||
ASFLAGS = ''
|
||||
|
||||
group = DefineGroup('BLCMD', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
|
||||
|
||||
Return('group')
|
||||
119
application/freertos/helloworld/cmd/hexdump.c
Normal file
119
application/freertos/helloworld/cmd/hexdump.c
Normal file
@@ -0,0 +1,119 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <aic_common.h>
|
||||
|
||||
static void hex_dump_1(unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i && (i % 16) == 0)
|
||||
printf("\n");
|
||||
if ((i % 16) == 0)
|
||||
printf("0x%08lx : ", (unsigned long)&buf[i]);
|
||||
printf("%02x ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void hex_dump_2(unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long i;
|
||||
unsigned short data;
|
||||
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
if (i && (i % 16) == 0)
|
||||
printf("\n");
|
||||
if ((i % 16) == 0)
|
||||
printf("0x%08lx : ", (unsigned long)&buf[i]);
|
||||
data = 0;
|
||||
if ((i + 2) <= len) {
|
||||
memcpy(&data, &buf[i], 2);
|
||||
i += 2;
|
||||
} else {
|
||||
memcpy(&data, &buf[i], 1);
|
||||
i += 1;
|
||||
}
|
||||
printf("%04x ", data);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void hex_dump_4(unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long i;
|
||||
unsigned long data;
|
||||
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
if (i && (i % 16) == 0)
|
||||
printf("\n");
|
||||
if ((i % 16) == 0)
|
||||
printf("0x%08lx : ", (unsigned long)&buf[i]);
|
||||
data = 0;
|
||||
if ((i + 4) <= len) {
|
||||
memcpy(&data, &buf[i], 4);
|
||||
i += 4;
|
||||
} else {
|
||||
memcpy(&data, &buf[i], len - i);
|
||||
i += (len - i);
|
||||
}
|
||||
printf("%08lx ", data);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void hex_dump_8(unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long i;
|
||||
unsigned long long data;
|
||||
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
if (i && (i % 16) == 0)
|
||||
printf("\n");
|
||||
if ((i % 16) == 0)
|
||||
printf("0x%08lx : ", (unsigned long)&buf[i]);
|
||||
data = 0;
|
||||
if ((i + 8) <= len) {
|
||||
memcpy(&data, &buf[i], 8);
|
||||
i += 8;
|
||||
} else {
|
||||
memcpy(&data, &buf[i], len - i);
|
||||
i += (len - i);
|
||||
}
|
||||
printf("%16llx ", data);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void hexdump(unsigned char *buf, unsigned long len, int groupsize)
|
||||
{
|
||||
if (groupsize <= 1) {
|
||||
hex_dump_1(buf, len);
|
||||
} else if (groupsize <= 2) {
|
||||
hex_dump_2(buf, len);
|
||||
} else if (groupsize <= 4) {
|
||||
hex_dump_4(buf, len);
|
||||
} else if (groupsize <= 8) {
|
||||
hex_dump_8(buf, len);
|
||||
} else {
|
||||
hex_dump_1(buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
void show_speed(char *msg, u32 len, u32 us)
|
||||
{
|
||||
u32 tmp, speed;
|
||||
|
||||
/* Split to serval step to avoid overflow */
|
||||
tmp = 1000 * len;
|
||||
tmp = tmp / us;
|
||||
tmp = 1000 * tmp;
|
||||
speed = tmp / 1024;
|
||||
|
||||
printf("%s: %d byte, %d us -> %d KB/s\n", msg, len, us, speed);
|
||||
}
|
||||
|
||||
21
application/freertos/helloworld/cmd/hexdump.h
Normal file
21
application/freertos/helloworld/cmd/hexdump.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Artinchip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __BL_HEXDUMP_H_
|
||||
#define __BL_HEXDUMP_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void hexdump(unsigned char *buf, unsigned long len, int groupsize);
|
||||
void show_speed(char *msg, u32 len, u32 us);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BL_HEXDUMP_H_ */
|
||||
113
application/freertos/helloworld/cmd/mem.c
Normal file
113
application/freertos/helloworld/cmd/mem.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Artinchip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Wu Dehuang <dehuang.wu@artinchip.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <console.h>
|
||||
#include <aic_common.h>
|
||||
#include <hexdump.h>
|
||||
|
||||
#define MD_HELP \
|
||||
"memory display command:\n" \
|
||||
" p <addr> <count> [mode]\n" \
|
||||
" addr: hex address string\n" \
|
||||
" count: display unit count\n" \
|
||||
" mode: should be 1/2/4 (default is 4)\n" \
|
||||
" e.g.: \n" \
|
||||
" p 0x40000000 64\n" \
|
||||
" p 0x40000000 64 1\n" \
|
||||
" p 0x40000000 64 2\n"
|
||||
|
||||
static void mem_display_help(void)
|
||||
{
|
||||
puts(MD_HELP);
|
||||
}
|
||||
|
||||
static int do_mem_display(int argc, char *argv[])
|
||||
{
|
||||
int groupsize;
|
||||
unsigned long addr, cnt;
|
||||
|
||||
cnt = 1;
|
||||
if (argc < 3) {
|
||||
goto help;
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
addr = strtol(argv[1], NULL, 0);
|
||||
cnt = strtol(argv[2], NULL, 0);
|
||||
groupsize = strtol(argv[3], NULL, 0);
|
||||
if ((groupsize != 1) && (groupsize != 2) && (groupsize != 4))
|
||||
goto help;
|
||||
} else {
|
||||
groupsize = 4;
|
||||
addr = strtol(argv[1], NULL, 0);
|
||||
cnt = strtol(argv[2], NULL, 0);
|
||||
}
|
||||
|
||||
hexdump((void *)addr, cnt * groupsize, groupsize);
|
||||
|
||||
return 0;
|
||||
|
||||
help:
|
||||
mem_display_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MW_HELP \
|
||||
"memory write command:\n" \
|
||||
" m <addr> <value> [mode]\n" \
|
||||
" addr: hex address string\n" \
|
||||
" value: value going to write\n" \
|
||||
" mode: should be 1/2/4 (default is 4)\n" \
|
||||
" e.g.: \n" \
|
||||
" m 0x40000000 0x64\n" \
|
||||
" m 0x40000000 0x64 1\n" \
|
||||
" m 0x40000000 0x64 2\n"
|
||||
|
||||
static void mem_write_help(void)
|
||||
{
|
||||
puts(MW_HELP);
|
||||
}
|
||||
|
||||
static int do_mem_write(int argc, char *argv[])
|
||||
{
|
||||
unsigned long addr, val;
|
||||
unsigned char *p;
|
||||
int groupsize;
|
||||
|
||||
val = 0;
|
||||
if (argc < 3) {
|
||||
goto help;
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
addr = strtol(argv[1], NULL, 0);
|
||||
val = strtol(argv[2], NULL, 0);
|
||||
groupsize = strtol(argv[3], NULL, 0);
|
||||
if ((groupsize != 1) && (groupsize != 2) && (groupsize != 4))
|
||||
goto help;
|
||||
} else {
|
||||
groupsize = 4;
|
||||
addr = strtol(argv[1], NULL, 0);
|
||||
val = strtol(argv[2], NULL, 0);
|
||||
}
|
||||
|
||||
p = (unsigned char *)addr;
|
||||
memcpy(p, &val, groupsize);
|
||||
return 0;
|
||||
|
||||
help:
|
||||
mem_write_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CONSOLE_CMD(p, do_mem_display, "Memory display");
|
||||
CONSOLE_CMD(m, do_mem_write, "Memory write");
|
||||
50
application/freertos/helloworld/cmd/reset.c
Normal file
50
application/freertos/helloworld/cmd/reset.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Artinchip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Wu Dehuang <dehuang.wu@artinchip.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <console.h>
|
||||
#include <aic_core.h>
|
||||
#include <aic_common.h>
|
||||
#include <aic_errno.h>
|
||||
#include <aic_hal.h>
|
||||
#include <hal_rtc.h>
|
||||
#include <wdt.h>
|
||||
|
||||
static int do_reset_boot(int argc, char *argv[])
|
||||
{
|
||||
#ifdef AIC_WDT_DRV
|
||||
wdt_init();
|
||||
printf("Going to reboot ...\n");
|
||||
#endif
|
||||
#ifdef AIC_WRI_DRV
|
||||
aic_set_reboot_reason(REBOOT_REASON_CMD_REBOOT);
|
||||
#endif
|
||||
#ifdef AIC_WDT_DRV
|
||||
wdt_expire_now();
|
||||
while(1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
CONSOLE_CMD(reset, do_reset_boot, "Reboot device.");
|
||||
CONSOLE_CMD(reboot, do_reset_boot, "Reboot device.");
|
||||
|
||||
static int cmd_aicupg(int argc, char **argv)
|
||||
{
|
||||
#ifdef AIC_WRI_DRV
|
||||
aic_set_reboot_reason(REBOOT_REASON_UPGRADE);
|
||||
#endif
|
||||
do_reset_boot(0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CONSOLE_CMD(aicupg, cmd_aicupg, "Reboot to the upgrade mode.");
|
||||
|
||||
219
application/freertos/helloworld/main.c
Normal file
219
application/freertos/helloworld/main.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 2022, ArtInChip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Authors: weilin.peng@artinchip.com
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <board.h>
|
||||
#include <hal_syscfg.h>
|
||||
#include <aic_core.h>
|
||||
#include <aic_drv_bare.h>
|
||||
#include <artinchip_fb.h>
|
||||
#include "aic_hal_ve.h"
|
||||
#include "aic_reboot_reason.h"
|
||||
#include <aic_log.h>
|
||||
#ifdef AIC_DMA_DRV
|
||||
#include "drv_dma.h"
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_CHERRYUSB_HOST
|
||||
#include <usbh_core.h>
|
||||
#include <usbh_hub.h>
|
||||
#include <usb_hc.h>
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_USING_DFS
|
||||
#include <dfs.h>
|
||||
#include <dfs_fs.h>
|
||||
#ifdef LPKG_USING_DFS_ELMFAT
|
||||
#include <dfs_elm.h>
|
||||
#endif
|
||||
#ifdef LPKG_USING_DFS_ROMFS
|
||||
#include <dfs_romfs.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef AIC_SDMC_DRV
|
||||
#include "mmc.h"
|
||||
#endif
|
||||
|
||||
#ifdef AIC_LVGL_DEMO
|
||||
#include "lvgl.h"
|
||||
|
||||
extern void lv_port_disp_init(void);
|
||||
extern void lv_port_indev_init(void);
|
||||
extern void lv_user_gui_init(void);
|
||||
#endif
|
||||
|
||||
void show_banner(void)
|
||||
{
|
||||
printf("%s\n", BANNER);
|
||||
printf("Welcome to ArtInChip Luban-Lite %d.%d [FreeRTOS - Built on %s %s]\n",
|
||||
LL_VERSION, LL_SUBVERSION, __DATE__, __TIME__);
|
||||
}
|
||||
|
||||
static void console_loop_thread(void *arg)
|
||||
{
|
||||
#ifdef AIC_CONSOLE_BARE_DRV
|
||||
/* Console shell loop */
|
||||
console_init();
|
||||
console_loop();
|
||||
#endif
|
||||
|
||||
/* FreeRTOS Task exit */
|
||||
aicos_thread_delete(NULL);
|
||||
}
|
||||
|
||||
static int board_init(void)
|
||||
{
|
||||
int cons_uart;
|
||||
aicos_thread_t tshell = NULL;
|
||||
|
||||
hal_syscfg_probe();
|
||||
|
||||
aicos_local_irq_enable();
|
||||
|
||||
cons_uart = AIC_BAREMETAL_CONSOLE_UART;
|
||||
uart_init(cons_uart);
|
||||
stdio_set_uart(cons_uart);
|
||||
|
||||
show_banner();
|
||||
|
||||
#ifdef AIC_CONSOLE_BARE_DRV
|
||||
tshell = aicos_thread_create("shell", 4096, configMAX_PRIORITIES-20, console_loop_thread, NULL);
|
||||
if (tshell == NULL) {
|
||||
pr_err("Failed to create shell thread\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LV_USE_LOG
|
||||
static void lv_rt_log(const char *buf)
|
||||
{
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
#endif /* LV_USE_LOG */
|
||||
|
||||
extern void lwip_test_example_main_loop(void * data);
|
||||
int main(void)
|
||||
{
|
||||
board_init();
|
||||
|
||||
#ifdef AIC_DMA_DRV
|
||||
drv_dma_init();
|
||||
#endif
|
||||
|
||||
#ifdef TLSF_MEM_HEAP
|
||||
aic_tlsf_heap_test();
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_USING_DFS
|
||||
dfs_init();
|
||||
#ifdef LPKG_USING_DFS_ROMFS
|
||||
dfs_romfs_init();
|
||||
#endif
|
||||
#ifdef LPKG_USING_DFS_ELMFAT
|
||||
elm_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_USING_DFS_ROMFS
|
||||
if (dfs_mount(NULL, "/", "rom", 0, &romfs_root) < 0)
|
||||
pr_err("Failed to mount romfs\n");
|
||||
#endif
|
||||
|
||||
#ifdef AIC_SDMC_DRV
|
||||
mmc_init(1);
|
||||
sdcard_hotplug_init();
|
||||
#endif
|
||||
|
||||
#if defined(LPKG_USING_DFS_ELMFAT) && defined(AIC_SDMC_DRV)
|
||||
if (dfs_mount("sd1", "/sdcard", "elm", 0, DEVICE_TYPE_SDMC_DISK) < 0)
|
||||
pr_err("Failed to mount sdmc with FatFS\n");
|
||||
#endif
|
||||
|
||||
#if defined(AIC_SPINAND_DRV) || defined(AIC_SPINOR_DRV)
|
||||
mtd_probe();
|
||||
#endif
|
||||
|
||||
#if defined(LPKG_USING_DFS_ELMFAT) && defined(AIC_USING_FS_IMAGE_TYPE_FATFS_FOR_0)
|
||||
#if defined(AIC_SPINAND_DRV)
|
||||
if (dfs_mount("rodata", "/rodata", "elm", 0, DEVICE_TYPE_SPINAND_DISK) < 0)
|
||||
pr_err("Failed to mount spinand with FatFS\n");
|
||||
#endif
|
||||
#if defined(AIC_SPINOR_DRV)
|
||||
if (dfs_mount("rodata", "/rodata", "elm", 0, DEVICE_TYPE_SPINOR_DISK) < 0)
|
||||
pr_err("Failed to mount spinor with FatFS\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef AIC_DISPLAY_DRV
|
||||
aicfb_probe();
|
||||
#endif
|
||||
#ifdef AIC_GE_DRV
|
||||
hal_ge_init();
|
||||
#endif
|
||||
#ifdef AIC_VE_DRV
|
||||
hal_ve_probe();
|
||||
#endif
|
||||
#ifdef AIC_WRI_DRV
|
||||
aic_get_reboot_reason();
|
||||
aic_show_startup_time();
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_CHERRYUSB_DEVICE
|
||||
#ifdef LPKG_CHERRYUSB_DEVICE_MSC_TEMPLATE
|
||||
extern void msc_ram_init(void);
|
||||
msc_ram_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_CHERRYUSB_HOST
|
||||
usbh_init();
|
||||
while(1)
|
||||
{
|
||||
usbh_hub_poll();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LPKG_LWIP_EXAMPLES
|
||||
/* LwIP test loop */
|
||||
lwip_test_example_main_loop(NULL);
|
||||
#endif
|
||||
|
||||
#ifdef AIC_LVGL_DEMO
|
||||
#if LV_USE_LOG
|
||||
lv_log_register_print_cb(lv_rt_log);
|
||||
#endif /* LV_USE_LOG */
|
||||
lv_init();
|
||||
lv_port_disp_init();
|
||||
lv_user_gui_init();
|
||||
|
||||
while(1)
|
||||
{
|
||||
lv_task_handler();
|
||||
}
|
||||
#endif /* AIC_LVGL_DEMO */
|
||||
|
||||
#ifdef AIC_VE_TEST
|
||||
extern int do_pic_dec_test(int argc, char **argv);
|
||||
/* Main loop */
|
||||
aicos_mdelay(2000);
|
||||
while (1) {
|
||||
do_pic_dec_test(0,NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FreeRTOS Task exit */
|
||||
aicos_thread_delete(NULL);
|
||||
return 0;
|
||||
}
|
||||
0
application/rt-thread/helloworld/Kconfig
Normal file
0
application/rt-thread/helloworld/Kconfig
Normal file
Reference in New Issue
Block a user