mirror of
https://github.com/Fishwaldo/bl808_coprocessor.git
synced 2025-03-15 11:21:28 +00:00
initial commit
This commit is contained in:
commit
5cc0f0c8b3
25 changed files with 3044 additions and 0 deletions
1
README.md
Normal file
1
README.md
Normal file
|
@ -0,0 +1 @@
|
|||
# bl808_coprocessor
|
18
m0/.vscode/c_cpp_properties.json
vendored
Normal file
18
m0/.vscode/c_cpp_properties.json
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
"cStandard": "gnu17",
|
||||
"cppStandard": "gnu++14",
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
|
||||
"configurationProvider": "ms-vscode.cmake-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
63
m0/.vscode/launch.json
vendored
Normal file
63
m0/.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "gdb",
|
||||
"request": "attach",
|
||||
"name": "Debug Microcontroller",
|
||||
"target": "extended-remote 10.100.201.177:1025",
|
||||
"executable": "${workspaceRoot}/build/build_out/ox64_coproc_bl808_m0.elf",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"gdbpath": "gdb-multiarch",
|
||||
"showDevDebugOutput": false,
|
||||
"printCalls": false,
|
||||
"valuesFormatting": "parseText",
|
||||
"autorun": [
|
||||
// "monitor tpwr enable",
|
||||
// "monitor swdp_scan",
|
||||
// "attach 1",
|
||||
//"file ${workspaceRoot}/build/build_out/ox64_coproc_bl808_m0.elf",
|
||||
"set mem inaccessible-by-default off",
|
||||
//"set architecture riscv:rv32",
|
||||
"set remotetimeout 250",
|
||||
//"#set disassemble-next-line on",
|
||||
//"#mon gdb_breakpoint_override [hard|soft|disable]",
|
||||
//"#mon reset",
|
||||
//"set $pc=0x58000000",
|
||||
//"set $mie=0",
|
||||
//"set $mstatus=0x1880",
|
||||
"thb main",
|
||||
"mem 0x40000000 0x40004000 rw",
|
||||
"mem 0x3f000000 0x3f018000 rw",
|
||||
"mem 0x3efe8000 0x3f068000 rw",
|
||||
"mem 0x22030000 0x22058000 rw",
|
||||
"mem 0x22020000 0x22030000 rw",
|
||||
//"#rom",
|
||||
"mem 0x90000000 0x90020000 ro",
|
||||
//"#psram",
|
||||
"mem 0x50000000 0x58000000 rw",
|
||||
//"#flash",
|
||||
"mem 0x58000000 0x60000000 ro",
|
||||
"set $pc=0x58000000",
|
||||
"set $mie=0",
|
||||
"set $mstatus=0x1880",
|
||||
]
|
||||
},
|
||||
// {
|
||||
// "name": "GDB",
|
||||
// "type": "cppdbg",
|
||||
// "request": "launch",
|
||||
// "cwd": "${workspaceRoot}",
|
||||
// "target": "${workspaceRoot}/build/build_out/ox64_coproc_bl808_m0.elf",
|
||||
// "gdbpath" : "/usr/bin/gdb-multiarch",
|
||||
// "autorun": [
|
||||
// "target remote 10.100.201.177:1025",
|
||||
// "symbol-file ./build/build_out/ox64_coproc_bl808_m0.elf",
|
||||
// "monitor reset"
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
}
|
12
m0/.vscode/settings.json
vendored
Normal file
12
m0/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"*.tpl": "html",
|
||||
"array": "c",
|
||||
"*.tcc": "c",
|
||||
"memory": "c",
|
||||
"istream": "c",
|
||||
"functional": "c",
|
||||
"tuple": "c",
|
||||
"utility": "c"
|
||||
}
|
||||
}
|
29
m0/CMakeLists.txt
Normal file
29
m0/CMakeLists.txt
Normal file
|
@ -0,0 +1,29 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
include(proj.conf)
|
||||
|
||||
find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
|
||||
|
||||
sdk_add_include_directories(include)
|
||||
|
||||
target_sources(app PRIVATE
|
||||
src/usb_descriptors.c
|
||||
src/usbd_dfu.c
|
||||
src/flash.c
|
||||
src/console.c
|
||||
src/cmd/cmd_memory.c
|
||||
src/cmd/cmd_sensors.c
|
||||
src/partition.c
|
||||
src/softcrc.c)
|
||||
|
||||
target_compile_definitions(app PRIVATE -DUSBD_DFU_XFER_SIZE=1024)
|
||||
target_compile_definitions(app PRIVATE -DUSBD_DFU_APP_DEFAULT_ADD=0x58000000)
|
||||
target_compile_options(app PRIVATE -ggdb -O0)
|
||||
# we need to set it on the shell library instead
|
||||
#target_compile_definitions(app PRIVATE -DSHELL_DEFAULT_NAME="0x64>")
|
||||
|
||||
|
||||
sdk_set_main_file(src/main.c)
|
||||
sdk_set_linker_script(bl808_flash_m0.ld)
|
||||
message(STATUS "Sources: ${SOURCES}")
|
||||
project(ox64_coproc)
|
20
m0/Makefile
Normal file
20
m0/Makefile
Normal file
|
@ -0,0 +1,20 @@
|
|||
SDK_DEMO_PATH ?= .
|
||||
BL_SDK_BASE ?= /home/fish/bl808/bl_mcu_sdk
|
||||
|
||||
export BL_SDK_BASE
|
||||
|
||||
CHIP ?= bl808
|
||||
BOARD ?= bl808dk
|
||||
CPU_ID ?= m0
|
||||
CROSS_COMPILE ?= riscv64-unknown-elf-
|
||||
|
||||
# add custom cmake definition
|
||||
#cmake_definition+=-Dxxx=sss
|
||||
|
||||
include $(BL_SDK_BASE)/project.build
|
||||
|
||||
flash:
|
||||
bflb-mcu-tool --chipname=bl808 --firmware build/build_out/ox64_coproc_bl808_m0.bin
|
||||
|
||||
monitor:
|
||||
screen /dev/ttyACM0 2000000
|
264
m0/bl808_flash_m0.ld
Normal file
264
m0/bl808_flash_m0.ld
Normal file
|
@ -0,0 +1,264 @@
|
|||
/****************************************************************************************
|
||||
* @file flash.ld
|
||||
*
|
||||
* @brief This file is the link script file (gnuarm or armgcc).
|
||||
*
|
||||
* Copyright (C) BouffaloLab 2021
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/* configure the CPU type */
|
||||
OUTPUT_ARCH( "riscv" )
|
||||
/* link with the standard c library */
|
||||
INPUT(-lc)
|
||||
/* link with the standard GCC library */
|
||||
INPUT(-lgcc)
|
||||
/* configure the entry point */
|
||||
ENTRY(__start)
|
||||
|
||||
StackSize = 0x0400; /* 1KB */
|
||||
HeapMinSize = 0x1000; /* 4KB */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
xip_memory (rx) : ORIGIN = 0x58000000, LENGTH = 32M
|
||||
itcm_memory (rx) : ORIGIN = 0x62020000, LENGTH = 32K
|
||||
dtcm_memory (rx) : ORIGIN = 0x62028000, LENGTH = 4K
|
||||
nocache_ram_memory (!rx) : ORIGIN = 0x22026000, LENGTH = 40K
|
||||
ram_memory (!rx) : ORIGIN = 0x62030000, LENGTH = 160K + 64K - 20K - 4K - 40K
|
||||
xram_memory (!rx) : ORIGIN = 0x40000000, LENGTH = 16K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__text_code_start__ = .;
|
||||
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
KEEP (*(SORT_NONE(.vector)))
|
||||
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
|
||||
/* section information for shell */
|
||||
. = ALIGN(4);
|
||||
__fsymtab_start = .;
|
||||
KEEP(*(FSymTab))
|
||||
__fsymtab_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__vsymtab_start = .;
|
||||
KEEP(*(VSymTab))
|
||||
__vsymtab_end = .;
|
||||
|
||||
/* section information for usb usbh_class_info */
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_end__ = .;
|
||||
|
||||
/*put .rodata**/
|
||||
*(EXCLUDE_FILE( *bl808_glb*.o* \
|
||||
*bl808_glb_gpio*.o* \
|
||||
*bl808_pds*.o* \
|
||||
*bl808_aon*.o* \
|
||||
*bl808_hbn*.o* \
|
||||
*bl808_l1c*.o* \
|
||||
*bl808_common*.o* \
|
||||
*bl808_clock*.o* \
|
||||
*bl808_ef_ctrl*.o* \
|
||||
*bl808_sf_cfg*.o* \
|
||||
*bl808_sf_ctrl*.o* \
|
||||
*bl808_sflash*.o* \
|
||||
*bl808_xip_sflash*.o* \
|
||||
*bl808_romapi_patch*.o* ) .rodata*)
|
||||
*(.srodata)
|
||||
*(.srodata.*)
|
||||
|
||||
. = ALIGN(4);
|
||||
__text_code_end__ = .;
|
||||
} > xip_memory
|
||||
|
||||
. = ALIGN(4);
|
||||
__itcm_load_addr = .;
|
||||
|
||||
.itcm_region : AT (__itcm_load_addr)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__tcm_code_start__ = .;
|
||||
|
||||
*(.tcm_code.*)
|
||||
*(.tcm_const.*)
|
||||
*(.sclock_rlt_code.*)
|
||||
*(.sclock_rlt_const.*)
|
||||
|
||||
*bl808_glb*.o*(.rodata*)
|
||||
*bl808_glb_gpio*.o*(.rodata*)
|
||||
*bl808_pds*.o*(.rodata*)
|
||||
*bl808_aon*.o*(.rodata*)
|
||||
*bl808_hbn*.o*(.rodata*)
|
||||
*bl808_l1c*.o*(.rodata*)
|
||||
*bl808_common*.o*(.rodata*)
|
||||
*bl808_clock*.o*(.rodata*)
|
||||
*bl808_ef_ctrl*.o*(.rodata*)
|
||||
*bl808_sf_cfg*.o*(.rodata*)
|
||||
*bl808_sf_ctrl*.o*(.rodata*)
|
||||
*bl808_sflash*.o*(.rodata*)
|
||||
*bl808_xip_sflash*.o*(.rodata*)
|
||||
*bl808_romapi_patch*.o*(.rodata*)
|
||||
|
||||
. = ALIGN(4);
|
||||
__tcm_code_end__ = .;
|
||||
} > itcm_memory
|
||||
|
||||
__dtcm_load_addr = __itcm_load_addr + SIZEOF(.itcm_region);
|
||||
|
||||
.dtcm_region : AT (__dtcm_load_addr)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__tcm_data_start__ = .;
|
||||
|
||||
*(.tcm_data)
|
||||
/* *finger_print.o(.data*) */
|
||||
|
||||
. = ALIGN(4);
|
||||
__tcm_data_end__ = .;
|
||||
} > dtcm_memory
|
||||
|
||||
/*************************************************************************/
|
||||
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||
* used for linker to calculate size of stack sections, and assign
|
||||
* values to stack symbols later */
|
||||
.stack_dummy (NOLOAD):
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
. = . + StackSize;
|
||||
. = ALIGN(0x4);
|
||||
} > dtcm_memory
|
||||
|
||||
/* Set stack top to end of RAM, and stack limit move down by
|
||||
* size of stack_dummy section */
|
||||
__StackTop = ORIGIN(dtcm_memory) + LENGTH(dtcm_memory);
|
||||
PROVIDE( __freertos_irq_stack_top = __StackTop);
|
||||
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||
|
||||
/* Check if data + heap + stack exceeds RAM limit */
|
||||
ASSERT(__StackLimit >= __tcm_data_end__, "region RAM overflowed with stack")
|
||||
/*************************************************************************/
|
||||
__nocache_ram_load_addr = __dtcm_load_addr + SIZEOF(.dtcm_region);
|
||||
|
||||
.nocache_ram_region : AT (__nocache_ram_load_addr)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__nocache_ram_data_start__ = .;
|
||||
|
||||
*(.nocache_ram)
|
||||
|
||||
. = ALIGN(4);
|
||||
__nocache_ram_data_end__ = .;
|
||||
} > nocache_ram_memory
|
||||
|
||||
__system_ram_load_addr = __nocache_ram_load_addr + SIZEOF(.nocache_ram_region);
|
||||
|
||||
.system_ram_data_region : AT (__system_ram_load_addr)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__system_ram_data_start__ = .;
|
||||
|
||||
*(.system_ram)
|
||||
|
||||
. = ALIGN(4);
|
||||
__system_ram_data_end__ = .;
|
||||
} > ram_memory
|
||||
|
||||
.system_ram_noinit_data_region (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.system_ram_noinit)
|
||||
|
||||
. = ALIGN(4);
|
||||
} > ram_memory
|
||||
|
||||
__ram_load_addr = __system_ram_load_addr + SIZEOF(.system_ram_data_region);
|
||||
|
||||
/* Data section */
|
||||
RAM_DATA : AT (__ram_load_addr)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__ram_data_start__ = .;
|
||||
|
||||
PROVIDE( __global_pointer$ = . + 0x800 );
|
||||
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
|
||||
. = ALIGN(4);
|
||||
__ram_data_end__ = .;
|
||||
} > ram_memory
|
||||
|
||||
__etext_final = (__ram_load_addr + SIZEOF (RAM_DATA));
|
||||
ASSERT(__etext_final <= ORIGIN(xip_memory) + LENGTH(xip_memory), "code memory overflow")
|
||||
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start__ = .;
|
||||
|
||||
*(.bss*)
|
||||
*(.sbss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
} > ram_memory
|
||||
|
||||
.noinit_data (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__noinit_data_start__ = .;
|
||||
|
||||
*(.noinit_data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
__noinit_data_end__ = .;
|
||||
} > ram_memory
|
||||
|
||||
.nocache_noinit_ram_region (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__nocache_noinit_ram_data_start__ = .;
|
||||
|
||||
*(.nocache_noinit_ram)
|
||||
*(.noncacheable)
|
||||
|
||||
. = ALIGN(4);
|
||||
__nocache_noinit_ram_data_end__ = .;
|
||||
} > nocache_ram_memory
|
||||
|
||||
.heap (NOLOAD):
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__HeapBase = .;
|
||||
|
||||
/*__end__ = .;*/
|
||||
/*end = __end__;*/
|
||||
KEEP(*(.heap*))
|
||||
|
||||
. = ALIGN(4);
|
||||
__HeapLimit = .;
|
||||
} > ram_memory
|
||||
|
||||
__HeapLimit = ORIGIN(ram_memory) + LENGTH(ram_memory);
|
||||
ASSERT(__HeapLimit - __HeapBase >= HeapMinSize, "heap region overflow")
|
||||
|
||||
}
|
||||
|
127
m0/include/FreeRTOSConfig.h
Normal file
127
m0/include/FreeRTOSConfig.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
*
|
||||
* See http://www.freertos.org/a00110.html.
|
||||
*----------------------------------------------------------*/
|
||||
#include "stdio.h"
|
||||
|
||||
#ifdef BL702
|
||||
#define configMTIME_BASE_ADDRESS (0x02000000UL + 0xBFF8UL)
|
||||
#define configMTIMECMP_BASE_ADDRESS (0x02000000UL + 0x4000UL)
|
||||
#else
|
||||
#define configMTIME_BASE_ADDRESS (0xE0000000UL + 0xBFF8UL)
|
||||
#define configMTIMECMP_BASE_ADDRESS (0xE0000000UL + 0x4000UL)
|
||||
#endif
|
||||
|
||||
// #define configSUPPORT_STATIC_ALLOCATION 1
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCPU_CLOCK_HZ ((uint32_t)(1 * 1000 * 1000))
|
||||
#define configTICK_RATE_HZ ((TickType_t)1000)
|
||||
#define configMAX_PRIORITIES (7)
|
||||
#define configMINIMAL_STACK_SIZE ((unsigned short)1024) /* Only needs to be this high as some demo tasks also use this constant. In production only the idle task would use this. */
|
||||
#define configTOTAL_HEAP_SIZE ((size_t)6 * 1024)
|
||||
#define configMAX_TASK_NAME_LEN (16)
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 0
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 8
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
#define configUSE_APPLICATION_TASK_TAG 0
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_TICKLESS_IDLE 0
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES (2)
|
||||
|
||||
/* Software timer definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1)
|
||||
#define configTIMER_QUEUE_LENGTH 4
|
||||
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE)
|
||||
|
||||
/* Task priorities. Allow these to be overridden. */
|
||||
#ifndef uartPRIMARY_PRIORITY
|
||||
#define uartPRIMARY_PRIORITY (configMAX_PRIORITIES - 3)
|
||||
#endif
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
to exclude the API function. */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskCleanUpResources 1
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xTaskAbortDelay 1
|
||||
#define INCLUDE_xTaskGetHandle 1
|
||||
#define INCLUDE_xSemaphoreGetMutexHolder 1
|
||||
|
||||
/* Normal assert() semantics without relying on the provision of an assert.h
|
||||
header file. */
|
||||
void vApplicationMallocFailedHook(void);
|
||||
void vAssertCalled(void);
|
||||
#define configASSERT(x) \
|
||||
if ((x) == 0) { \
|
||||
printf("file [%s]\r\n", __FILE__); \
|
||||
printf("func [%s]\r\n", __FUNCTION__); \
|
||||
printf("line [%d]\r\n", __LINE__); \
|
||||
printf("%s\r\n", (const char *)(#x)); \
|
||||
vAssertCalled(); \
|
||||
}
|
||||
|
||||
#if (configUSE_TICKLESS_IDLE != 0)
|
||||
void vApplicationSleep(uint32_t xExpectedIdleTime);
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime) vApplicationSleep(xExpectedIdleTime)
|
||||
#endif
|
||||
|
||||
// #define portUSING_MPU_WRAPPERS
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
6
m0/include/console.h
Normal file
6
m0/include/console.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
void console_init(void);
|
||||
|
||||
#endif
|
210
m0/include/partition.h
Normal file
210
m0/include/partition.h
Normal file
|
@ -0,0 +1,210 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file partition.h
|
||||
* @version V1.0
|
||||
* @date
|
||||
* @brief This file is the standard driver header file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __PARTITION_H__
|
||||
#define __PARTITION_H__
|
||||
|
||||
//#include "blsp_port.h"
|
||||
#include "bl808_common.h"
|
||||
|
||||
/** @addtogroup BFLB_Common_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PARTITION
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PARTITION_Public_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Partition table error type definition
|
||||
*/
|
||||
typedef enum {
|
||||
PT_ERROR_SUCCESS, /*!< Partition table error type:success */
|
||||
PT_ERROR_TABLE_NOT_VALID, /*!< Partition table error type:table not found */
|
||||
PT_ERROR_ENTRY_NOT_FOUND, /*!< Partition table error type:entry not found */
|
||||
PT_ERROR_ENTRY_UPDATE_FAIL, /*!< Partition table error type:entry update fail */
|
||||
PT_ERROR_CRC32, /*!< Partition table error type:crc32 error */
|
||||
PT_ERROR_PARAMETER, /*!< Partition table error type:input parameter error */
|
||||
PT_ERROR_FALSH_READ, /*!< Partition table error type:flash read error */
|
||||
PT_ERROR_FALSH_WRITE, /*!< Partition table error type:flash write error */
|
||||
PT_ERROR_FALSH_ERASE, /*!< Partition table error type:flash erase error */
|
||||
} pt_table_error_type;
|
||||
|
||||
/**
|
||||
* @brief Partition id type definition
|
||||
*/
|
||||
typedef enum {
|
||||
PT_TABLE_ID_0, /*!< Partition table ID 0 */
|
||||
PT_TABLE_ID_1, /*!< Partition table ID 1 */
|
||||
PT_TABLE_ID_INVALID, /*!< Partition table ID invalid */
|
||||
} pt_table_id_type;
|
||||
|
||||
/**
|
||||
* @brief Partition id type definition
|
||||
*/
|
||||
typedef enum {
|
||||
PT_ENTRY_FW_CPU0, /*!< Partition entry type:CPU0 firmware */
|
||||
PT_ENTRY_FW_CPU1, /*!< Partition entry type:CPU1 firmware */
|
||||
PT_ENTRY_MAX = 16, /*!< Partition entry type:Max */
|
||||
} pt_table_entry_type;
|
||||
|
||||
/**
|
||||
* @brief Partition table config definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t magicCode; /*!< Partition table magic code */
|
||||
uint16_t version; /*!< Partition table verdion */
|
||||
uint16_t entryCnt; /*!< Partition table entry count */
|
||||
uint32_t age; /*!< Partition table age */
|
||||
uint32_t crc32; /*!< Partition table CRC32 value */
|
||||
} pt_table_config;
|
||||
|
||||
/**
|
||||
* @brief Partition table entry config definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t type; /*!< Partition entry type */
|
||||
uint8_t device; /*!< Partition entry device */
|
||||
uint8_t active_index; /*!< Partition entry active index */
|
||||
uint8_t name[9]; /*!< Partition entry name */
|
||||
uint32_t start_address[2]; /*!< Partition entry start address */
|
||||
uint32_t max_len[2]; /*!< Partition entry max length */
|
||||
uint32_t len; /*!< Partition entry length */
|
||||
uint32_t age; /*!< Partition entry age */
|
||||
} pt_table_entry_config;
|
||||
|
||||
/**
|
||||
* @brief Partition table stuff config definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
pt_table_config pt_table; /*!< Partition table */
|
||||
pt_table_entry_config pt_entries[PT_ENTRY_MAX]; /*!< Partition entries */
|
||||
uint32_t crc32; /*!< Partition entries crc32 */
|
||||
} pt_table_stuff_config;
|
||||
|
||||
/**
|
||||
* @brief Partition table iap param definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t iap_start_addr;
|
||||
uint32_t iap_write_addr;
|
||||
uint32_t iap_img_len;
|
||||
uint8_t inactive_index;
|
||||
uint8_t inactive_table_index;
|
||||
} pt_table_iap_param_type;
|
||||
|
||||
/*@} end of group PARTITION_Public_Types */
|
||||
|
||||
/** @defgroup PARTITION_Public_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup pt_table_error_type
|
||||
* @{
|
||||
*/
|
||||
#define IS_PTTABLE_ERROR_TYPE(type) (((type) == PT_ERROR_SUCCESS) || \
|
||||
((type) == PT_ERROR_TABLE_NOT_VALID) || \
|
||||
((type) == PT_ERROR_ENTRY_NOT_FOUND) || \
|
||||
((type) == PT_ERROR_ENTRY_UPDATE_FAIL) || \
|
||||
((type) == PT_ERROR_CRC32) || \
|
||||
((type) == PT_ERROR_PARAMETER) || \
|
||||
((type) == PT_ERROR_FALSH_READ) || \
|
||||
((type) == PT_ERROR_FALSH_WRITE) || \
|
||||
((type) == PT_ERROR_FALSH_ERASE))
|
||||
|
||||
/** @defgroup pt_table_id_type
|
||||
* @{
|
||||
*/
|
||||
#define IS_PTTABLE_ID_TYPE(type) (((type) == PT_TABLE_ID_0) || \
|
||||
((type) == PT_TABLE_ID_1) || \
|
||||
((type) == PT_TABLE_ID_INVALID))
|
||||
|
||||
/** @defgroup pt_table_entry_type
|
||||
* @{
|
||||
*/
|
||||
#define IS_PTTABLE_ENTRY_TYPE(type) (((type) == PT_ENTRY_FW_CPU0) || \
|
||||
((type) == PT_ENTRY_FW_CPU1) || \
|
||||
((type) == PT_ENTRY_MAX))
|
||||
|
||||
/*@} end of group PARTITION_Public_Constants */
|
||||
|
||||
/** @defgroup PARTITION_Public_Macros
|
||||
* @{
|
||||
*/
|
||||
#define BFLB_PT_TABLE0_ADDRESS 0xE000
|
||||
#define BFLB_PT_TABLE1_ADDRESS 0xF000
|
||||
#define BFLB_PT_MAGIC_CODE 0x54504642
|
||||
typedef int (*p_pt_table_flash_erase)(uint32_t startaddr, uint32_t endaddr);
|
||||
typedef int (*p_pt_table_flash_write)(uint32_t addr, uint8_t *data, uint32_t len);
|
||||
typedef int (*p_pt_table_flash_read)(uint32_t addr, uint8_t *data, uint32_t len);
|
||||
|
||||
/*@} end of group PARTITION_Public_Macros */
|
||||
|
||||
/** @defgroup PARTITION_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
void pt_table_set_flash_operation(p_pt_table_flash_erase erase, p_pt_table_flash_write write, p_pt_table_flash_read read);
|
||||
pt_table_id_type pt_table_get_active_partition_need_lock(pt_table_stuff_config ptStuff[2]);
|
||||
pt_table_error_type pt_table_get_active_entries_by_id(pt_table_stuff_config *pt_stuff,
|
||||
pt_table_entry_type type,
|
||||
pt_table_entry_config *pt_entry);
|
||||
pt_table_error_type pt_table_get_active_entries_by_name(pt_table_stuff_config *pt_stuff,
|
||||
uint8_t *name,
|
||||
pt_table_entry_config *pt_entry);
|
||||
pt_table_error_type pt_table_update_entry(pt_table_id_type target_table_id,
|
||||
pt_table_stuff_config *pt_stuff,
|
||||
pt_table_entry_config *pt_entry);
|
||||
pt_table_error_type pt_table_create(pt_table_id_type pt_id);
|
||||
pt_table_error_type pt_table_dump(void);
|
||||
pt_table_error_type pt_table_get_iap_para(pt_table_iap_param_type *para);
|
||||
pt_table_error_type pt_table_set_iap_para(pt_table_iap_param_type *para);
|
||||
|
||||
/*@} end of group PARTITION_Public_Functions */
|
||||
|
||||
/*@} end of group PARTITION */
|
||||
|
||||
/*@} end of group BFLB_Common_Driver */
|
||||
|
||||
extern pt_table_iap_param_type p_iap_param;
|
||||
|
||||
#endif /* __PARTITION_H__ */
|
45
m0/include/softcrc.h
Normal file
45
m0/include/softcrc.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* *****************************************************************************
|
||||
* @file softcrc.h
|
||||
* @version 1.0
|
||||
* @date 2022-11-23
|
||||
* @brief
|
||||
* *****************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*/
|
||||
#ifndef __SOFTCRC_H__
|
||||
#define __SOFTCRC_H__
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
uint16_t BFLB_Soft_CRC16(void *dataIn, uint32_t len);
|
||||
uint32_t BFLB_Soft_CRC32_Ex(uint32_t initial, void *dataIn, uint32_t len);
|
||||
uint32_t BFLB_Soft_CRC32(void *dataIn, uint32_t len);
|
||||
|
||||
#endif
|
132
m0/include/usb_config.h
Normal file
132
m0/include/usb_config.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef CHERRYUSB_CONFIG_H
|
||||
#define CHERRYUSB_CONFIG_H
|
||||
|
||||
/* ================ USB common Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_PRINTF(...) printf(__VA_ARGS__)
|
||||
|
||||
#define usb_malloc(size) malloc(size)
|
||||
#define usb_free(ptr) free(ptr)
|
||||
|
||||
#ifndef CONFIG_USB_DBG_LEVEL
|
||||
#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
|
||||
#endif
|
||||
|
||||
/* Enable print with color */
|
||||
#define CONFIG_USB_PRINTF_COLOR_ENABLE
|
||||
|
||||
/* data align size when use dma */
|
||||
#ifndef CONFIG_USB_ALIGN_SIZE
|
||||
#define CONFIG_USB_ALIGN_SIZE 4
|
||||
#endif
|
||||
|
||||
/* attribute data into no cache ram */
|
||||
#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
|
||||
|
||||
/* ================= USB Device Stack Configuration ================ */
|
||||
|
||||
/* Ep0 max transfer buffer, specially for receiving data from ep0 out */
|
||||
#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 4096
|
||||
|
||||
/* Setup packet log for debug */
|
||||
//#define CONFIG_USBDEV_SETUP_LOG_PRINT
|
||||
|
||||
/* Check if the input descriptor is correct */
|
||||
#define CONFIG_USBDEV_DESC_CHECK
|
||||
|
||||
/* Enable test mode */
|
||||
// #define CONFIG_USBDEV_TEST_MODE
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE
|
||||
#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
|
||||
#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING
|
||||
#define CONFIG_USBDEV_MSC_PRODUCT_STRING ""
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_VERSION_STRING
|
||||
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
|
||||
#endif
|
||||
|
||||
// #define CONFIG_USBDEV_MSC_THREAD
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#ifndef CONFIG_USBDEV_MSC_STACKSIZE
|
||||
#define CONFIG_USBDEV_MSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRIO
|
||||
#define CONFIG_USBDEV_MSC_PRIO 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_AUDIO_VERSION
|
||||
#define CONFIG_USBDEV_AUDIO_VERSION 0x0100
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_AUDIO_MAX_CHANNEL
|
||||
#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 8
|
||||
#endif
|
||||
|
||||
/* ================ USB HOST Stack Configuration ================== */
|
||||
|
||||
#define CONFIG_USBHOST_MAX_RHPORTS 1
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 6
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_DEV_NAMELEN 16
|
||||
|
||||
#ifndef CONFIG_USBHOST_PSC_PRIO
|
||||
#define CONFIG_USBHOST_PSC_PRIO 4
|
||||
#endif
|
||||
#ifndef CONFIG_USBHOST_PSC_STACKSIZE
|
||||
#define CONFIG_USBHOST_PSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
//#define CONFIG_USBHOST_GET_STRING_DESC
|
||||
|
||||
/* Ep0 max transfer buffer */
|
||||
#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
|
||||
|
||||
#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
|
||||
#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_MSC_TIMEOUT
|
||||
#define CONFIG_USBHOST_MSC_TIMEOUT 5000
|
||||
#endif
|
||||
|
||||
/* ================ USB Device Port Configuration ================*/
|
||||
|
||||
//#define USBD_IRQHandler USBD_IRQHandler
|
||||
//#define USB_BASE (0x40080000UL)
|
||||
//#define USB_NUM_BIDIR_ENDPOINTS 4
|
||||
|
||||
/* ================ USB Host Port Configuration ==================*/
|
||||
|
||||
#define CONFIG_USBHOST_PIPE_NUM 10
|
||||
|
||||
/* ================ EHCI Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)
|
||||
#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
|
||||
#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
|
||||
// #define CONFIG_USB_EHCI_INFO_ENABLE
|
||||
#define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
|
||||
// #define CONFIG_USB_EHCI_CONFIGFLAG
|
||||
// #define CONFIG_USB_EHCI_PORT_POWER
|
||||
|
||||
#endif
|
137
m0/include/usb_dfu.h
Normal file
137
m0/include/usb_dfu.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USB_DFU_H
|
||||
#define USB_DFU_H
|
||||
|
||||
/**\addtogroup USB_MODULE_DFU USB DFU class
|
||||
* \brief This module contains USB Device Firmware Upgrade class definitions.
|
||||
* \details This module based on
|
||||
* + [USB Device Firmware Upgrade Specification, Revision 1.1]
|
||||
* (https://www.usb.org/sites/default/files/DFU_1.1.pdf)
|
||||
* @{ */
|
||||
|
||||
/** DFU Specification release */
|
||||
#define DFU_VERSION 0x0110
|
||||
|
||||
/** DFU Class Subclass */
|
||||
#define DFU_SUBCLASS_DFU 0x01
|
||||
|
||||
/** DFU Class runtime Protocol */
|
||||
#define DFU_PROTOCOL_RUNTIME 0x01
|
||||
|
||||
/** DFU Class DFU mode Protocol */
|
||||
#define DFU_PROTOCOL_MODE 0x02
|
||||
|
||||
/**
|
||||
* @brief DFU Class Specific Requests
|
||||
*/
|
||||
#define DFU_REQUEST_DETACH 0x00
|
||||
#define DFU_REQUEST_DNLOAD 0x01
|
||||
#define DFU_REQUEST_UPLOAD 0x02
|
||||
#define DFU_REQUEST_GETSTATUS 0x03
|
||||
#define DFU_REQUEST_CLRSTATUS 0x04
|
||||
#define DFU_REQUEST_GETSTATE 0x05
|
||||
#define DFU_REQUEST_ABORT 0x06
|
||||
|
||||
/** DFU FUNCTIONAL descriptor type */
|
||||
#define DFU_FUNC_DESC 0x21
|
||||
|
||||
/** DFU attributes DFU Functional Descriptor */
|
||||
#define DFU_ATTR_WILL_DETACH 0x08
|
||||
#define DFU_ATTR_MANIFESTATION_TOLERANT 0x04
|
||||
#define DFU_ATTR_CAN_UPLOAD 0x02
|
||||
#define DFU_ATTR_CAN_DNLOAD 0x01
|
||||
|
||||
/** bStatus values for the DFU_GETSTATUS response */
|
||||
#define DFU_STATUS_OK 0x00U
|
||||
#define DFU_STATUS_ERR_TARGET 0x01U
|
||||
#define DFU_STATUS_ERR_FILE 0x02U
|
||||
#define DFU_STATUS_ERR_WRITE 0x03U
|
||||
#define DFU_STATUS_ERR_ERASE 0x04U
|
||||
#define DFU_STATUS_ERR_CHECK_ERASED 0x05U
|
||||
#define DFU_STATUS_ERR_PROG 0x06U
|
||||
#define DFU_STATUS_ERR_VERIFY 0x07U
|
||||
#define DFU_STATUS_ERR_ADDRESS 0x08U
|
||||
#define DFU_STATUS_ERR_NOTDONE 0x09U
|
||||
#define DFU_STATUS_ERR_FIRMWARE 0x0AU
|
||||
#define DFU_STATUS_ERR_VENDOR 0x0BU
|
||||
#define DFU_STATUS_ERR_USB 0x0CU
|
||||
#define DFU_STATUS_ERR_POR 0x0DU
|
||||
#define DFU_STATUS_ERR_UNKNOWN 0x0EU
|
||||
#define DFU_STATUS_ERR_STALLEDPKT 0x0FU
|
||||
|
||||
/** bState values for the DFU_GETSTATUS response */
|
||||
#define DFU_STATE_APP_IDLE 0U
|
||||
#define DFU_STATE_APP_DETACH 1U
|
||||
#define DFU_STATE_DFU_IDLE 2U
|
||||
#define DFU_STATE_DFU_DNLOAD_SYNC 3U
|
||||
#define DFU_STATE_DFU_DNLOAD_BUSY 4U
|
||||
#define DFU_STATE_DFU_DNLOAD_IDLE 5U
|
||||
#define DFU_STATE_DFU_MANIFEST_SYNC 6U
|
||||
#define DFU_STATE_DFU_MANIFEST 7U
|
||||
#define DFU_STATE_DFU_MANIFEST_WAIT_RESET 8U
|
||||
#define DFU_STATE_DFU_UPLOAD_IDLE 9U
|
||||
#define DFU_STATE_DFU_ERROR 10U
|
||||
|
||||
/** DFU Manifestation State */
|
||||
#define DFU_MANIFEST_COMPLETE 0U
|
||||
#define DFU_MANIFEST_IN_PROGRESS 1U
|
||||
|
||||
/** Special Commands with Download Request */
|
||||
#define DFU_CMD_GETCOMMANDS 0U
|
||||
#define DFU_CMD_SETADDRESSPOINTER 0x21U
|
||||
#define DFU_CMD_ERASE 0x41U
|
||||
#define DFU_MEDIA_ERASE 0x00U
|
||||
#define DFU_MEDIA_PROGRAM 0x01U
|
||||
|
||||
/** Other defines */
|
||||
/* Bit Detach capable = bit 3 in bmAttributes field */
|
||||
#define DFU_DETACH_MASK (1U << 3)
|
||||
#define DFU_MANIFEST_MASK (1U << 2)
|
||||
|
||||
/** Run-Time Functional Descriptor */
|
||||
struct dfu_runtime_descriptor {
|
||||
uint8_t bLength; /**<\brief Descriptor length in bytes.*/
|
||||
uint8_t bDescriptorType; /**<\brief DFU functional descriptor type.*/
|
||||
uint8_t bmAttributes; /**<\brief USB DFU capabilities \ref USB_DFU_CAPAB*/
|
||||
uint16_t wDetachTimeout; /**<\brief USB DFU detach timeout in ms.*/
|
||||
uint16_t wTransferSize; /**<\brief USB DFU maximum transfer block size in bytes.*/
|
||||
uint16_t bcdDFUVersion; /**<\brief USB DFU version \ref VERSION_BCD utility macro.*/
|
||||
} __PACKED;
|
||||
|
||||
/**\brief Payload packet to response in DFU_GETSTATUS request */
|
||||
struct dfu_info {
|
||||
uint8_t bStatus; /**<\brief An indication of the status resulting from the
|
||||
* execution of the most recent request.*/
|
||||
uint8_t bPollTimeout; /**<\brief Minimum time (LSB) in ms, that the host should wait
|
||||
* before sending a subsequent DFU_GETSTATUS request.*/
|
||||
uint16_t wPollTimeout; /**<\brief Minimum time (MSB) in ms, that the host should wait
|
||||
* before sending a subsequent DFU_GETSTATUS request.*/
|
||||
uint8_t bState; /**<\brief An indication of the state that the device is going
|
||||
* to enter immediately following transmission of this response.*/
|
||||
uint8_t iString; /**<\brief Index of the status string descriptor.*/
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
#define DFU_DESCRIPTOR_INIT() \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
0x00, /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x00, /* bNumEndpoints Default Control Pipe only */ \
|
||||
USB_DEVICE_CLASS_APP_SPECIFIC, /* bInterfaceClass */ \
|
||||
0x01, /* bInterfaceSubClass Device Firmware Upgrade */ \
|
||||
0x02, /* bInterfaceProtocol DFU mode */ \
|
||||
0x04, /* iInterface */ /*!< Device Firmware Update Functional Descriptor */ \
|
||||
0x09, /* bLength */ \
|
||||
0x21, /* DFU Functional Descriptor */ \
|
||||
0x0B, /* bmAttributes */ \
|
||||
WBVAL(0x00ff), /* wDetachTimeOut */ \
|
||||
WBVAL(USBD_DFU_XFER_SIZE), /* wTransferSize */ \
|
||||
WBVAL(0x0110) /* bcdDFUVersion */
|
||||
// clang-format on
|
||||
|
||||
#endif /* USB_DFU_H */
|
9
m0/include/usb_uart.h
Normal file
9
m0/include/usb_uart.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef USBUART_H
|
||||
#define USBUART_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void vuart_write(uint8_t uart, char *buf, uint8_t len);
|
||||
void usbuart_read(uint8_t uart, char *data, uint32_t len);
|
||||
|
||||
#endif
|
28
m0/include/usbd_dfu.h
Normal file
28
m0/include/usbd_dfu.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USBD_DFU_H
|
||||
#define USBD_DFU_H
|
||||
|
||||
#include "usb_dfu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Init dfu interface driver */
|
||||
struct usbd_interface *usbd_dfu_init_intf(struct usbd_interface *intf);
|
||||
|
||||
/* Interface functions that need to be implemented by the user */
|
||||
uint8_t *dfu_read_flash(uint8_t *src, uint8_t *dest, uint32_t len);
|
||||
uint16_t dfu_write_flash(uint8_t *src, uint8_t *dest, uint32_t len);
|
||||
uint16_t dfu_erase_flash(uint32_t add);
|
||||
void dfu_leave(void);
|
||||
void dfu_reset(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBD_DFU_H */
|
15
m0/proj.conf
Normal file
15
m0/proj.conf
Normal file
|
@ -0,0 +1,15 @@
|
|||
set(CONFIG_CHERRYUSB 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_CDC 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_HID 0)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_MSC 0)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_AUDIO 0)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_VIDEO 0)
|
||||
set(CONFIG_PSRAM 1)
|
||||
set(CONFIG_SHELL 1)
|
||||
set(CONFIG_FREERTOS 1)
|
||||
set(CONFIG_BFLOG 1)
|
||||
set(CONFIG_VLIBC 1)
|
||||
set(CONFIG_DEBUG 1)
|
||||
set(CONFIG_ROMAPI 1)
|
||||
set(CONFIG_TLSF 1)
|
17
m0/src/cmd/cmd_memory.c
Normal file
17
m0/src/cmd/cmd_memory.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include <stdio.h>
|
||||
#include <shell.h>
|
||||
#ifdef CONFIG_TLSF
|
||||
#include "bflb_tlsf.h"
|
||||
|
||||
int meminfo(int argc, char **argv)
|
||||
{
|
||||
if (argc != 1) {
|
||||
printf("Usage: meminfo");
|
||||
return 0;
|
||||
}
|
||||
bflb_tlsf_size_container_t *tlsf_size = bflb_tlsf_stats();
|
||||
printf("Memory: Total: %dKb, Used: %dKb Free: %dKb\r\n", (tlsf_size->free + tlsf_size->used)/1024, tlsf_size->used/1024, tlsf_size->free/1024);
|
||||
return 0;
|
||||
}
|
||||
SHELL_CMD_EXPORT(meminfo, get free memory info)
|
||||
#endif
|
72
m0/src/cmd/cmd_sensors.c
Normal file
72
m0/src/cmd/cmd_sensors.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include <bflb_adc.h>
|
||||
#include <shell.h>
|
||||
|
||||
int temp(int argc, char **argv) {
|
||||
uint16_t i = 0;
|
||||
float average_filter = 0.0;
|
||||
|
||||
struct bflb_device_s *adc = bflb_device_get_by_name("adc");
|
||||
|
||||
/* adc clock = XCLK / 2 / 32 */
|
||||
struct bflb_adc_config_s cfg;
|
||||
cfg.clk_div = ADC_CLK_DIV_32;
|
||||
cfg.scan_conv_mode = false;
|
||||
cfg.continuous_conv_mode = false;
|
||||
cfg.differential_mode = false;
|
||||
cfg.resolution = ADC_RESOLUTION_16B;
|
||||
cfg.vref = ADC_VREF_2P0V;
|
||||
|
||||
struct bflb_adc_channel_s chan;
|
||||
|
||||
chan.pos_chan = ADC_CHANNEL_TSEN_P;
|
||||
chan.neg_chan = ADC_CHANNEL_GND;
|
||||
|
||||
bflb_adc_init(adc, &cfg);
|
||||
bflb_adc_channel_config(adc, &chan, 1);
|
||||
bflb_adc_tsen_init(adc, ADC_TSEN_MOD_INTERNAL_DIODE);
|
||||
|
||||
for (i = 0; i < 50; i++) {
|
||||
average_filter += bflb_adc_tsen_get_temp(adc);
|
||||
bflb_mtimer_delay_ms(10);
|
||||
}
|
||||
printf("temp = %d\r\n", (uint32_t)(average_filter / 50.0));
|
||||
return 0;
|
||||
}
|
||||
SHELL_CMD_EXPORT(temp, get CPU Temp)
|
||||
|
||||
int voltage(int argc, char **argv) {
|
||||
struct bflb_device_s *adc = bflb_device_get_by_name("adc");
|
||||
|
||||
/* adc clock = XCLK / 2 / 32 */
|
||||
struct bflb_adc_config_s cfg;
|
||||
cfg.clk_div = ADC_CLK_DIV_32;
|
||||
cfg.scan_conv_mode = false;
|
||||
cfg.continuous_conv_mode = false;
|
||||
cfg.differential_mode = false;
|
||||
cfg.resolution = ADC_RESOLUTION_16B;
|
||||
cfg.vref = ADC_VREF_3P2V;
|
||||
|
||||
struct bflb_adc_channel_s chan;
|
||||
|
||||
chan.pos_chan = ADC_CHANNEL_VABT_HALF;
|
||||
chan.neg_chan = ADC_CHANNEL_GND;
|
||||
|
||||
bflb_adc_init(adc, &cfg);
|
||||
bflb_adc_channel_config(adc, &chan, 1);
|
||||
bflb_adc_vbat_enable(adc);
|
||||
|
||||
struct bflb_adc_result_s result;
|
||||
|
||||
bflb_adc_start_conversion(adc);
|
||||
while (bflb_adc_get_count(adc) == 0) {
|
||||
bflb_mtimer_delay_ms(1);
|
||||
}
|
||||
uint32_t raw_data = bflb_adc_read_raw(adc);
|
||||
|
||||
bflb_adc_parse_result(adc, &raw_data, &result, 1);
|
||||
printf("vBat = %d mV\r\n", (uint32_t)(result.millivolt * 2));
|
||||
bflb_adc_stop_conversion(adc);
|
||||
bflb_adc_vbat_disable(adc);
|
||||
return 0;
|
||||
}
|
||||
SHELL_CMD_EXPORT(voltage, get Voltage)
|
60
m0/src/console.c
Normal file
60
m0/src/console.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
#include <bflb_core.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <semphr.h>
|
||||
#include <shell.h>
|
||||
#include <ring_buffer.h>
|
||||
#include "console.h"
|
||||
#include "usb_uart.h"
|
||||
|
||||
|
||||
static TaskHandle_t usbuart_handle;
|
||||
SemaphoreHandle_t usbuart_sem = NULL;
|
||||
Ring_Buffer_Type usbuart_rb;
|
||||
|
||||
|
||||
static void shell_task(void *pvParameters)
|
||||
{
|
||||
uint8_t data;
|
||||
uint32_t len;
|
||||
while (1) {
|
||||
if (xSemaphoreTake(usbuart_sem, portMAX_DELAY) == pdTRUE) {
|
||||
len = Ring_Buffer_Get_Length(&usbuart_rb);
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
Ring_Buffer_Read_Byte(&usbuart_rb, &data);
|
||||
shell_handler(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbuart_read(uint8_t uart, char *data, uint32_t len)
|
||||
{
|
||||
Ring_Buffer_Write(&usbuart_rb, (const uint8_t *)data, len);
|
||||
xSemaphoreGive(usbuart_sem);
|
||||
}
|
||||
|
||||
void usbuartprintf(char *fmt, ...) {
|
||||
char buf[256];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
vuart_write(0, buf, strlen(buf));
|
||||
}
|
||||
/* implemented in the Shell Component of BFBL_SDK */
|
||||
//extern void shell_init_with_task(struct bflb_device_s *shell);
|
||||
|
||||
extern int shell_set_print(void (*shell_printf)(char *fmt, ...));
|
||||
|
||||
void console_init() {
|
||||
/* start a UART Shell */
|
||||
struct bflb_device_s *uart0 = bflb_device_get_by_name("uart0");
|
||||
shell_set_prompt("0x64>");
|
||||
shell_init_with_task(uart0);
|
||||
//shell_init();
|
||||
//shell_set_print(usbuartprintf);
|
||||
//vSemaphoreCreateBinary(usbuart_sem);
|
||||
//xTaskCreate(shell_task, (char *)"usbuart_shell", SHELL_THREAD_STACK_SIZE, NULL, SHELL_THREAD_PRIO, &usbuart_handle);
|
||||
}
|
35
m0/src/flash.c
Normal file
35
m0/src/flash.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
#include "bflb_flash.h"
|
||||
#include "usbd_dfu.h"
|
||||
#include "log.h"
|
||||
|
||||
// uint8_t *dfu_read_flash(uint8_t *src, uint8_t *dest, uint32_t len)
|
||||
// {
|
||||
// LOG_I("DFU Read %lx %lx %ld\r\n", src, dest, len);
|
||||
// uint32_t i = 0;
|
||||
// uint8_t *psrc = src;
|
||||
|
||||
// for (i = 0; i < len; i++) {
|
||||
// dest[i] = *psrc++;
|
||||
// }
|
||||
// /* Return a valid address to avoid HardFault */
|
||||
// return (uint8_t *)(dest);
|
||||
// }
|
||||
|
||||
// uint16_t dfu_write_flash(uint8_t *src, uint8_t *dest, uint32_t len)
|
||||
// {
|
||||
// LOG_I("DFU Write %lx %lx %ld\r\n", src, dest, len);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// uint16_t dfu_erase_flash(uint32_t add)
|
||||
// {
|
||||
// LOG_I("DFU Erase %lx\r\n", add);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// void dfu_leave(void)
|
||||
// {
|
||||
// LOG_I("DFU Leave\r\n");
|
||||
// dfu_reset();
|
||||
// }
|
88
m0/src/main.c
Normal file
88
m0/src/main.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
|
||||
#include <bl808_glb.h>
|
||||
|
||||
#include <bflb_mtimer.h>
|
||||
#include <bflb_flash.h>
|
||||
#ifdef CONFIG_TLSF
|
||||
#include <bflb_tlsf.h>
|
||||
#endif
|
||||
#include <bflb_gpio.h>
|
||||
|
||||
#include <board.h>
|
||||
#include <log.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <semphr.h>
|
||||
#include <usbh_core.h>
|
||||
#include "console.h"
|
||||
|
||||
extern void cdc_acm_multi_init(void);
|
||||
|
||||
// static uint8_t freertos_heap[configTOTAL_HEAP_SIZE];
|
||||
|
||||
// static HeapRegion_t xHeapRegions[] = {
|
||||
// { (uint8_t *)freertos_heap, 0 },
|
||||
// { NULL, 0 }, /* Terminates the array. */
|
||||
// { NULL, 0 } /* Terminates the array. */
|
||||
// };
|
||||
|
||||
|
||||
extern uint32_t __start;
|
||||
int main(void)
|
||||
{
|
||||
board_init();
|
||||
struct bflb_device_s *gpio = bflb_device_get_by_name("gpio");
|
||||
bflb_gpio_init(gpio, GPIO_PIN_12, GPIO_ALTERNATE | GPIO_FUNC_JTAG_M0);
|
||||
bflb_gpio_init(gpio, GPIO_PIN_13, GPIO_ALTERNATE | GPIO_FUNC_JTAG_M0);
|
||||
bflb_gpio_init(gpio, GPIO_PIN_6, GPIO_ALTERNATE | GPIO_FUNC_JTAG_M0);
|
||||
bflb_gpio_init(gpio, GPIO_PIN_7, GPIO_ALTERNATE | GPIO_FUNC_JTAG_M0);
|
||||
#ifdef CONFIG_TLSF
|
||||
void *ptr = meminfo();
|
||||
#endif
|
||||
void *ptr2 = temp();
|
||||
|
||||
LOG_I("Starting 0x64_coproc on %d at 0x%08lx\r\n", GLB_Get_Core_Type(), __start);
|
||||
LOG_I("Flash Offset at 0x%08lx\r\n", bflb_flash_get_image_offset());
|
||||
cdc_acm_multi_init();
|
||||
LOG_I("USB Running\r\n");
|
||||
#ifdef CONFIG_TLSF
|
||||
bflb_tlsf_size_container_t *tlsf_size = bflb_tlsf_stats();
|
||||
printf("Memory: Total: %dKb, Used: %dKb Free: %dKb\r\n", (tlsf_size->free + tlsf_size->used)/1024, tlsf_size->used/1024, tlsf_size->free/1024);
|
||||
#endif
|
||||
LOG_I("FreeRTOS Scheduler Starting\r\n");
|
||||
console_init();
|
||||
LOG_I("Console Started\r\n");
|
||||
pt_table_set_flash_operation(bflb_flash_erase, bflb_flash_write, bflb_flash_read);
|
||||
pt_table_dump();
|
||||
vTaskStartScheduler();
|
||||
/* we should never get here */
|
||||
}
|
||||
|
||||
// void vApplicationMallocFailedHook( void )
|
||||
// {
|
||||
// /* Called if a call to pvPortMalloc() fails because there is insufficient
|
||||
// free memory available in the FreeRTOS heap. pvPortMalloc() is called
|
||||
// internally by FreeRTOS API functions that create tasks, queues, software
|
||||
// timers, and semaphores. The size of the FreeRTOS heap is set by the
|
||||
// configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
|
||||
// LOG_E("Malloc Failed\r\n");
|
||||
// bflb_mtimer_delay_ms(500);
|
||||
|
||||
// /* Force an assert. */
|
||||
// configASSERT( ( volatile void * ) NULL );
|
||||
// }
|
||||
// /*-----------------------------------------------------------*/
|
||||
|
||||
// void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
|
||||
// {
|
||||
// ( void ) pcTaskName;
|
||||
// ( void ) pxTask;
|
||||
|
||||
// /* Run time stack overflow checking is performed if
|
||||
// configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
|
||||
// function is called if a stack overflow is detected. */
|
||||
// LOG_E("Stack Overflow\r\n");
|
||||
// bflb_mtimer_delay_ms(500);
|
||||
|
||||
// /* Force an assert. */
|
||||
// configASSERT( ( volatile void * ) NULL );
|
||||
// }
|
542
m0/src/partition.c
Normal file
542
m0/src/partition.c
Normal file
|
@ -0,0 +1,542 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file partition.c
|
||||
* @version V1.0
|
||||
* @date
|
||||
* @brief This file is the standard driver c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2019 Bouffalo Lab</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#include "bflb_core.h"
|
||||
#include "partition.h"
|
||||
#include "softcrc.h"
|
||||
#include "log.h"
|
||||
|
||||
/** @addtogroup BFLB_Common_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PARTITION
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PARTITION_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group PARTITION_Private_Macros */
|
||||
|
||||
/** @defgroup PARTITION_Private_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group PARTITION_Private_Types */
|
||||
|
||||
/** @defgroup PARTITION_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
p_pt_table_flash_erase gp_pt_table_flash_erase = NULL;
|
||||
p_pt_table_flash_write gp_pt_table_flash_write = NULL;
|
||||
p_pt_table_flash_read gp_pt_table_flash_read = NULL;
|
||||
pt_table_iap_param_type p_iap_param;
|
||||
|
||||
/*@} end of group PARTITION_Private_Variables */
|
||||
|
||||
/** @defgroup PARTITION_Global_Variables
|
||||
* @{
|
||||
*/
|
||||
extern int main(void);
|
||||
|
||||
/*@} end of group PARTITION_Global_Variables */
|
||||
|
||||
/** @defgroup PARTITION_Private_Fun_Declaration
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group PARTITION_Private_Fun_Declaration */
|
||||
|
||||
/** @defgroup PARTITION_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Judge partition table valid
|
||||
*
|
||||
* @param ptStuff: Partition table stuff pointer
|
||||
*
|
||||
* @return 0 for invalid and 1 for valid
|
||||
*
|
||||
*******************************************************************************/
|
||||
static uint8_t pt_table_valid(pt_table_stuff_config *pt_stuff)
|
||||
{
|
||||
pt_table_config *pt_table = &pt_stuff->pt_table;
|
||||
pt_table_entry_config *pt_entries = pt_stuff->pt_entries;
|
||||
uint32_t *p_crc32;
|
||||
uint32_t entriesLen = sizeof(pt_table_entry_config) * pt_table->entryCnt;
|
||||
|
||||
if (pt_table->magicCode == BFLB_PT_MAGIC_CODE) {
|
||||
if (pt_table->entryCnt > PT_ENTRY_MAX) {
|
||||
LOG_F("PT Entry Count Error\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pt_table->crc32 !=
|
||||
BFLB_Soft_CRC32((uint8_t *)pt_table, sizeof(pt_table_config) - 4)) {
|
||||
LOG_F("PT CRC Error\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ToDo it is a trap here, when entryCnt > 8, crc32 will overflow, comment by zhangcheng */
|
||||
p_crc32 = (uint32_t *)((uintptr_t)pt_entries + entriesLen);
|
||||
|
||||
if (*p_crc32 != BFLB_Soft_CRC32((uint8_t *)pt_entries, entriesLen)) {
|
||||
LOG_F("PT Entry CRC Error\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
LOG_F("PT Invalid Partition Magic: %08lx\r\n", pt_table->magicCode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*@} end of group PARTITION_Private_Functions */
|
||||
|
||||
/** @defgroup PARTITION_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Register partition flash read write erase fucntion
|
||||
*
|
||||
* @param erase: Flash erase function
|
||||
* @param write: Flash write function
|
||||
* @param read: Flash read function
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void pt_table_set_flash_operation(p_pt_table_flash_erase erase, p_pt_table_flash_write write, p_pt_table_flash_read read)
|
||||
{
|
||||
gp_pt_table_flash_erase = erase;
|
||||
gp_pt_table_flash_write = write;
|
||||
gp_pt_table_flash_read = read;
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Get active partition table whole stuff
|
||||
*
|
||||
* @param ptStuff[2]: Partition table stuff pointer
|
||||
*
|
||||
* @return Active partition table ID
|
||||
*
|
||||
*******************************************************************************/
|
||||
pt_table_id_type pt_table_get_active_partition_need_lock(pt_table_stuff_config ptStuff[2])
|
||||
{
|
||||
uint32_t pt_valid[2] = { 0, 0 };
|
||||
pt_table_id_type activePtID;
|
||||
|
||||
if (ptStuff == NULL) {
|
||||
return PT_TABLE_ID_INVALID;
|
||||
}
|
||||
|
||||
activePtID = PT_TABLE_ID_INVALID;
|
||||
|
||||
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&ptStuff[0], sizeof(pt_table_stuff_config));
|
||||
pt_valid[0] = pt_table_valid(&ptStuff[0]);
|
||||
|
||||
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&ptStuff[1], sizeof(pt_table_stuff_config));
|
||||
pt_valid[1] = pt_table_valid(&ptStuff[1]);
|
||||
|
||||
if (pt_valid[0] == 1 && pt_valid[1] == 1) {
|
||||
if (ptStuff[0].pt_table.age >= ptStuff[1].pt_table.age) {
|
||||
activePtID = PT_TABLE_ID_0;
|
||||
} else {
|
||||
activePtID = PT_TABLE_ID_1;
|
||||
}
|
||||
} else if (pt_valid[0] == 1) {
|
||||
activePtID = PT_TABLE_ID_0;
|
||||
} else if (pt_valid[1] == 1) {
|
||||
activePtID = PT_TABLE_ID_1;
|
||||
}
|
||||
|
||||
return activePtID;
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Get partition entry according to entry ID
|
||||
*
|
||||
* @param ptStuff: Partition table stuff pointer
|
||||
* @param type: Type of partition entry
|
||||
* @param ptEntry: Partition entry pointer to store read data
|
||||
*
|
||||
* @return PT_ERROR_SUCCESS or PT_ERROR_ENTRY_NOT_FOUND or PT_ERROR_PARAMETER
|
||||
*
|
||||
*******************************************************************************/
|
||||
pt_table_error_type pt_table_get_active_entries_by_id(pt_table_stuff_config *pt_stuff,
|
||||
pt_table_entry_type type,
|
||||
pt_table_entry_config *pt_entry)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
if (pt_stuff == NULL || pt_entry == NULL) {
|
||||
return PT_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
for (i = 0; i < pt_stuff->pt_table.entryCnt; i++) {
|
||||
if (pt_stuff->pt_entries[i].type == type) {
|
||||
ARCH_MemCpy_Fast(pt_entry, &pt_stuff->pt_entries[i], sizeof(pt_table_entry_config));
|
||||
return PT_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return PT_ERROR_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Get partition entry according to entry name
|
||||
*
|
||||
* @param ptStuff: Partition table stuff pointer
|
||||
* @param name: Name of partition entry
|
||||
* @param ptEntry: Partition entry pointer to store read data
|
||||
*
|
||||
* @return PT_ERROR_SUCCESS or PT_ERROR_ENTRY_NOT_FOUND or PT_ERROR_PARAMETER
|
||||
*
|
||||
*******************************************************************************/
|
||||
pt_table_error_type pt_table_get_active_entries_by_name(pt_table_stuff_config *pt_stuff,
|
||||
uint8_t *name,
|
||||
pt_table_entry_config *pt_entry)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t len = strlen((char *)name);
|
||||
|
||||
if (pt_stuff == NULL || pt_entry == NULL) {
|
||||
return PT_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
for (i = 0; i < pt_stuff->pt_table.entryCnt; i++) {
|
||||
if (strlen((char *)pt_stuff->pt_entries[i].name) == len &&
|
||||
memcmp((char *)pt_stuff->pt_entries[i].name, (char *)name, len) == 0) {
|
||||
ARCH_MemCpy_Fast(pt_entry, &pt_stuff->pt_entries[i], sizeof(pt_table_entry_config));
|
||||
return PT_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return PT_ERROR_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Update partition entry
|
||||
*
|
||||
* @param targetTableID: Target partition table to update
|
||||
* @param ptStuff: Partition table stuff pointer
|
||||
* @param ptEntry: Partition entry pointer to update
|
||||
*
|
||||
* @return Partition update result
|
||||
*
|
||||
*******************************************************************************/
|
||||
pt_table_error_type pt_table_update_entry(pt_table_id_type target_table_id,
|
||||
pt_table_stuff_config *pt_stuff,
|
||||
pt_table_entry_config *pt_entry)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
BL_Err_Type ret;
|
||||
uint32_t write_addr;
|
||||
uint32_t entries_len;
|
||||
pt_table_config *pt_table;
|
||||
pt_table_entry_config *pt_entries;
|
||||
uint32_t *crc32;
|
||||
|
||||
if (pt_entry == NULL || pt_stuff == NULL) {
|
||||
return PT_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
pt_table = &pt_stuff->pt_table;
|
||||
pt_entries = pt_stuff->pt_entries;
|
||||
|
||||
if (target_table_id == PT_TABLE_ID_INVALID) {
|
||||
return PT_ERROR_TABLE_NOT_VALID;
|
||||
}
|
||||
|
||||
if (target_table_id == PT_TABLE_ID_0) {
|
||||
write_addr = BFLB_PT_TABLE0_ADDRESS;
|
||||
} else {
|
||||
write_addr = BFLB_PT_TABLE1_ADDRESS;
|
||||
}
|
||||
|
||||
for (i = 0; i < pt_table->entryCnt; i++) {
|
||||
if (pt_entries[i].type == pt_entry->type) {
|
||||
ARCH_MemCpy_Fast(&pt_entries[i], pt_entry, sizeof(pt_table_entry_config));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == pt_table->entryCnt) {
|
||||
/* Not found this entry ,add new one */
|
||||
if (pt_table->entryCnt < PT_ENTRY_MAX) {
|
||||
ARCH_MemCpy_Fast(&pt_entries[pt_table->entryCnt], pt_entry, sizeof(pt_table_entry_config));
|
||||
pt_table->entryCnt++;
|
||||
} else {
|
||||
return PT_ERROR_ENTRY_UPDATE_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare write back to flash */
|
||||
/* Update age */
|
||||
pt_table->age++;
|
||||
pt_table->crc32 = BFLB_Soft_CRC32((uint8_t *)pt_table, sizeof(pt_table_config) - 4);
|
||||
|
||||
/* Update entries CRC */
|
||||
entries_len = pt_table->entryCnt * sizeof(pt_table_entry_config);
|
||||
crc32 = (uint32_t *)((uintptr_t)pt_entries + entries_len);
|
||||
*crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_entries[0], entries_len);
|
||||
|
||||
/* Write back to flash */
|
||||
/* Erase flash first */
|
||||
//ret = gp_pt_table_flash_erase(write_addr, write_addr + sizeof(pt_table_config) + entries_len + 4 - 1);
|
||||
ret = gp_pt_table_flash_erase(write_addr, sizeof(pt_table_config) + entries_len + 4);
|
||||
|
||||
if (ret != SUCCESS) {
|
||||
//LOG_D_ERR("Flash Erase error\r\n");
|
||||
return PT_ERROR_FALSH_WRITE;
|
||||
}
|
||||
|
||||
/* Write flash */
|
||||
ret = gp_pt_table_flash_write(write_addr, (uint8_t *)pt_stuff, sizeof(pt_table_stuff_config));
|
||||
|
||||
if (ret != SUCCESS) {
|
||||
//LOG_D_ERR("Flash Write error\r\n");
|
||||
return PT_ERROR_FALSH_WRITE;
|
||||
}
|
||||
|
||||
return PT_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Create partition entry
|
||||
*
|
||||
* @param ptID: Partition table ID
|
||||
*
|
||||
* @return Partition create result
|
||||
*
|
||||
*******************************************************************************/
|
||||
pt_table_error_type pt_table_create(pt_table_id_type pt_id)
|
||||
{
|
||||
uint32_t write_addr;
|
||||
BL_Err_Type ret;
|
||||
pt_table_config pt_table;
|
||||
|
||||
if (pt_id == PT_TABLE_ID_INVALID) {
|
||||
return PT_ERROR_TABLE_NOT_VALID;
|
||||
}
|
||||
|
||||
if (pt_id == PT_TABLE_ID_0) {
|
||||
write_addr = BFLB_PT_TABLE0_ADDRESS;
|
||||
} else {
|
||||
write_addr = BFLB_PT_TABLE1_ADDRESS;
|
||||
}
|
||||
|
||||
/* Prepare write back to flash */
|
||||
pt_table.magicCode = BFLB_PT_MAGIC_CODE;
|
||||
pt_table.version = 0;
|
||||
pt_table.entryCnt = 0;
|
||||
pt_table.age = 0;
|
||||
pt_table.crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_table, sizeof(pt_table_config) - 4);
|
||||
/* Write back to flash */
|
||||
//ret = gp_pt_table_flash_erase(write_addr, write_addr + sizeof(pt_table_config) - 1);
|
||||
ret = gp_pt_table_flash_erase(write_addr, sizeof(pt_table_config));
|
||||
|
||||
if (ret != SUCCESS) {
|
||||
//LOG_D_ERR("Flash Erase error\r\n");
|
||||
return PT_ERROR_FALSH_ERASE;
|
||||
}
|
||||
|
||||
ret = gp_pt_table_flash_write(write_addr, (uint8_t *)&pt_table, sizeof(pt_table_config));
|
||||
|
||||
if (ret != SUCCESS) {
|
||||
//LOG_D_ERR("Flash Write error\r\n");
|
||||
return PT_ERROR_FALSH_WRITE;
|
||||
}
|
||||
|
||||
return PT_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
pt_table_error_type pt_table_dump(void)
|
||||
{
|
||||
uint32_t pt_valid[2] = { 0, 0 };
|
||||
pt_table_stuff_config pt_stuff[2];
|
||||
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff[0], sizeof(pt_table_stuff_config));
|
||||
pt_valid[0] = pt_table_valid(&pt_stuff[0]);
|
||||
|
||||
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff[1], sizeof(pt_table_stuff_config));
|
||||
pt_valid[1] = pt_table_valid(&pt_stuff[1]);
|
||||
|
||||
if (pt_valid[0]) {
|
||||
LOG_F("PT TABLE0 (%x) valid\r\n", BFLB_PT_TABLE0_ADDRESS);
|
||||
} else {
|
||||
LOG_F("PT TABLE0 (%x) invalid\r\n", BFLB_PT_TABLE0_ADDRESS);
|
||||
}
|
||||
|
||||
if (pt_valid[1]) {
|
||||
LOG_F("PT TABLE1 (%x) valid\r\n", BFLB_PT_TABLE1_ADDRESS);
|
||||
} else {
|
||||
LOG_F("PT TABLE1 (%x) invalid\r\n", BFLB_PT_TABLE1_ADDRESS);
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (pt_valid[i] == 1) {
|
||||
LOG_F("ptStuff[%d].pt_table.magicCode 0x%08x\r\n", i, pt_stuff[i].pt_table.magicCode);
|
||||
LOG_F("ptStuff[%d].pt_table.version 0x%08x\r\n", i, pt_stuff[i].pt_table.version);
|
||||
LOG_F("ptStuff[%d].pt_table.entryCnt 0x%08x\r\n", i, pt_stuff[i].pt_table.entryCnt);
|
||||
LOG_F("ptStuff[%d].pt_table.age 0x%08x\r\n", i, pt_stuff[i].pt_table.age);
|
||||
LOG_F("ptStuff[%d].pt_table.crc32 0x%08x\r\n", i, pt_stuff[i].pt_table.crc32);
|
||||
|
||||
for (int j = 0; j < pt_stuff[i].pt_table.entryCnt; j++) {
|
||||
LOG_F("ptStuff[%d].pt_entries[%d].type 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].type);
|
||||
LOG_F("ptStuff[%d].pt_entries[%d].name %s\r\n", i, j, pt_stuff[i].pt_entries[j].name);
|
||||
LOG_F("ptStuff[%d].pt_entries[%d].device 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].device);
|
||||
LOG_F("ptStuff[%d].pt_entries[%d].active_index 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].active_index);
|
||||
LOG_F("ptStuff[%d].pt_entries[%d].Address[0] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].start_address[0]);
|
||||
LOG_F("ptStuff[%d].pt_entries[%d].Address[1] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].start_address[1]);
|
||||
LOG_F("ptStuff[%d].pt_entries[%d].maxLen[0] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].max_len[0]);
|
||||
LOG_F("ptStuff[%d].pt_entries[%d].maxLen[1] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].max_len[1]);
|
||||
LOG_F("ptStuff[%d].pt_entries[%d].len 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].len);
|
||||
LOG_F("ptStuff[%d].pt_entries[%d].age 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].age);
|
||||
}
|
||||
}
|
||||
}
|
||||
return PT_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
pt_table_error_type pt_table_get_iap_para(pt_table_iap_param_type *para)
|
||||
{
|
||||
uint32_t pt_valid[2] = { 0, 0 };
|
||||
pt_table_stuff_config pt_stuff[2];
|
||||
uint8_t active_index;
|
||||
|
||||
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff[0], sizeof(pt_table_stuff_config));
|
||||
pt_valid[0] = pt_table_valid(&pt_stuff[0]);
|
||||
|
||||
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff[1], sizeof(pt_table_stuff_config));
|
||||
pt_valid[1] = pt_table_valid(&pt_stuff[1]);
|
||||
|
||||
if ((pt_valid[0] == 1) && (pt_valid[1] == 1)) {
|
||||
if (pt_stuff[0].pt_table.age >= pt_stuff[1].pt_table.age) {
|
||||
active_index = pt_stuff[0].pt_entries[0].active_index;
|
||||
para->iap_write_addr = para->iap_start_addr = pt_stuff[0].pt_entries[0].start_address[!(active_index & 0x01)];
|
||||
para->inactive_index = !(active_index & 0x01);
|
||||
para->inactive_table_index = 1;
|
||||
|
||||
} else {
|
||||
active_index = pt_stuff[1].pt_entries[0].active_index;
|
||||
para->iap_write_addr = para->iap_start_addr = pt_stuff[1].pt_entries[0].start_address[!(active_index & 0x01)];
|
||||
para->inactive_index = !(active_index & 0x01);
|
||||
para->inactive_table_index = 0;
|
||||
}
|
||||
|
||||
} else if (pt_valid[1] == 1) {
|
||||
active_index = pt_stuff[1].pt_entries[0].active_index;
|
||||
para->iap_write_addr = para->iap_start_addr = pt_stuff[1].pt_entries[0].start_address[!(active_index & 0x01)];
|
||||
para->inactive_index = !(active_index & 0x01);
|
||||
para->inactive_table_index = 0;
|
||||
} else if (pt_valid[0] == 1) {
|
||||
active_index = pt_stuff[0].pt_entries[0].active_index;
|
||||
para->iap_write_addr = para->iap_start_addr = pt_stuff[0].pt_entries[0].start_address[!(active_index & 0x01)];
|
||||
para->inactive_index = !(active_index & 0x01);
|
||||
para->inactive_table_index = 1;
|
||||
} else {
|
||||
return PT_ERROR_TABLE_NOT_VALID;
|
||||
}
|
||||
|
||||
LOG_F("inactive_table_index %d, inactive index %d , IAP start addr %08x \r\n", para->inactive_table_index, para->inactive_index, para->iap_start_addr);
|
||||
return PT_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
pt_table_error_type pt_table_set_iap_para(pt_table_iap_param_type *para)
|
||||
{
|
||||
pt_table_stuff_config pt_stuff, pt_stuff_write;
|
||||
int32_t ret;
|
||||
uint32_t *p_crc32;
|
||||
uint32_t entries_len;
|
||||
|
||||
if (para->inactive_table_index == 1) {
|
||||
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff, sizeof(pt_table_stuff_config));
|
||||
} else if (para->inactive_table_index == 0) {
|
||||
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff, sizeof(pt_table_stuff_config));
|
||||
}
|
||||
|
||||
ARCH_MemCpy_Fast((void *)&pt_stuff_write, (void *)&pt_stuff, sizeof(pt_table_stuff_config));
|
||||
pt_stuff_write.pt_table.age += 1;
|
||||
pt_stuff_write.pt_entries[0].active_index = !(pt_stuff_write.pt_entries[0].active_index & 0x01);
|
||||
pt_stuff_write.pt_table.crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_stuff_write, sizeof(pt_table_config) - 4);
|
||||
entries_len = sizeof(pt_table_entry_config) * pt_stuff_write.pt_table.entryCnt;
|
||||
//pt_stuff_write.crc32 = BFLB_Soft_CRC32((uint8_t*)pt_stuff_write.pt_entries,entries_len);
|
||||
p_crc32 = (uint32_t *)((uintptr_t)pt_stuff_write.pt_entries + entries_len);
|
||||
*p_crc32 = BFLB_Soft_CRC32((uint8_t *)pt_stuff_write.pt_entries, entries_len);
|
||||
|
||||
if (para->inactive_table_index == 1) {
|
||||
//ret = gp_pt_table_flash_erase(BFLB_PT_TABLE1_ADDRESS, BFLB_PT_TABLE1_ADDRESS + sizeof(pt_table_stuff_config) - 1);
|
||||
ret = gp_pt_table_flash_erase(BFLB_PT_TABLE1_ADDRESS, sizeof(pt_table_stuff_config));
|
||||
|
||||
if (ret != SUCCESS) {
|
||||
//LOG_D_ERR("Flash Erase error\r\n");
|
||||
return PT_ERROR_FALSH_ERASE;
|
||||
}
|
||||
|
||||
ret = gp_pt_table_flash_write(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff_write, sizeof(pt_table_stuff_config));
|
||||
|
||||
if (ret != SUCCESS) {
|
||||
//LOG_D_ERR("Flash Write error\r\n");
|
||||
return PT_ERROR_FALSH_WRITE;
|
||||
}
|
||||
} else if (para->inactive_table_index == 0) {
|
||||
//ret = gp_pt_table_flash_erase(BFLB_PT_TABLE0_ADDRESS, BFLB_PT_TABLE0_ADDRESS + sizeof(pt_table_stuff_config) - 1);
|
||||
ret = gp_pt_table_flash_erase(BFLB_PT_TABLE0_ADDRESS, sizeof(pt_table_stuff_config));
|
||||
|
||||
if (ret != SUCCESS) {
|
||||
//LOG_D_ERR("Flash Erase error\r\n");
|
||||
return PT_ERROR_FALSH_ERASE;
|
||||
}
|
||||
|
||||
ret = gp_pt_table_flash_write(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff_write, sizeof(pt_table_stuff_config));
|
||||
|
||||
if (ret != SUCCESS) {
|
||||
//LOG_D_ERR("Flash Write error\r\n");
|
||||
return PT_ERROR_FALSH_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_F("Update pt_table suss\r\n");
|
||||
return PT_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*@} end of group PARTITION_Public_Functions */
|
||||
|
||||
/*@} end of group PARTITION */
|
||||
|
||||
/*@} end of group BFLB_Common_Driver */
|
209
m0/src/softcrc.c
Normal file
209
m0/src/softcrc.c
Normal file
|
@ -0,0 +1,209 @@
|
|||
/**
|
||||
* *****************************************************************************
|
||||
* @file softcrc.c
|
||||
* @version 1.0
|
||||
* @date 2022-11-23
|
||||
* @brief
|
||||
* *****************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include "bflb_core.h"
|
||||
#include "softcrc.h"
|
||||
// ---------------- POPULAR POLYNOMIALS ----------------
|
||||
// CCITT: x^16 + x^12 + x^5 + x^0 (0x1021,init 0x0000)
|
||||
// CRC-16: x^16 + x^15 + x^2 + x^0 (0x8005,init 0xFFFF)
|
||||
// we use 0x8005 here and
|
||||
|
||||
const uint8_t chCRCHTalbe[] = {
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40
|
||||
};
|
||||
|
||||
const uint8_t chCRCLTalbe[] = {
|
||||
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
|
||||
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
|
||||
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
|
||||
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
|
||||
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
|
||||
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
|
||||
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
|
||||
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
|
||||
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
|
||||
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
|
||||
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
|
||||
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
|
||||
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
|
||||
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
|
||||
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
|
||||
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
|
||||
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
|
||||
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
|
||||
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
|
||||
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
|
||||
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
|
||||
0x41, 0x81, 0x80, 0x40
|
||||
};
|
||||
|
||||
uint16_t BFLB_Soft_CRC16(void *dataIn, uint32_t len)
|
||||
{
|
||||
uint8_t chCRCHi = 0xFF;
|
||||
uint8_t chCRCLo = 0xFF;
|
||||
uint16_t wIndex;
|
||||
uint8_t *data = (uint8_t *)dataIn;
|
||||
|
||||
while (len--) {
|
||||
wIndex = chCRCLo ^ *data++;
|
||||
chCRCLo = chCRCHi ^ chCRCHTalbe[wIndex];
|
||||
chCRCHi = chCRCLTalbe[wIndex];
|
||||
}
|
||||
|
||||
return ((chCRCHi << 8) | chCRCLo);
|
||||
}
|
||||
|
||||
/*
|
||||
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
|
||||
*/
|
||||
const uint32_t crc32Tab[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
uint32_t BFLB_Soft_CRC32_Table(void *dataIn, uint32_t len)
|
||||
{
|
||||
uint32_t crc = 0;
|
||||
uint8_t *data = (uint8_t *)dataIn;
|
||||
|
||||
crc = crc ^ 0xffffffff;
|
||||
|
||||
while (len--) {
|
||||
crc = crc32Tab[(crc ^ *data++) & 0xFF] ^ (crc >> 8);
|
||||
}
|
||||
|
||||
return crc ^ 0xffffffff;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Name: CRC-32 x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
|
||||
* Poly: 0x4C11DB7
|
||||
* Init: 0xFFFFFFF
|
||||
* Refin: True
|
||||
* Refout: True
|
||||
* Xorout: 0xFFFFFFF
|
||||
* Alias: CRC_32/ADCCP
|
||||
* Use: WinRAR,ect.
|
||||
*****************************************************************************/
|
||||
uint32_t ATTR_TCM_SECTION BFLB_Soft_CRC32_Ex(uint32_t initial, void *dataIn, uint32_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
uint32_t crc = ~initial; // Initial value
|
||||
uint8_t *data = (uint8_t *)dataIn;
|
||||
|
||||
while (len--) {
|
||||
crc ^= *data++; // crc ^= *data; data++;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
if (crc & 1) {
|
||||
crc = (crc >> 1) ^ 0xEDB88320; // 0xEDB88320= reverse 0x04C11DB7
|
||||
} else {
|
||||
crc = (crc >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
#ifndef BFLB_USE_ROM_DRIVER
|
||||
__WEAK
|
||||
uint32_t ATTR_TCM_SECTION BFLB_Soft_CRC32(void *dataIn, uint32_t len)
|
||||
{
|
||||
return BFLB_Soft_CRC32_Ex(0, dataIn, len);
|
||||
}
|
||||
#endif
|
397
m0/src/usb_descriptors.c
Normal file
397
m0/src/usb_descriptors.c
Normal file
|
@ -0,0 +1,397 @@
|
|||
#include <usbd_core.h>
|
||||
#include <usbd_cdc.h>
|
||||
#include <log.h>
|
||||
|
||||
#include "usbd_dfu.h"
|
||||
//#include "usb_uart.h"
|
||||
|
||||
/*!< endpoint address */
|
||||
/* v-uart1 */
|
||||
#define CDC_IN_EP1 0x81
|
||||
#define CDC_OUT_EP1 0x02
|
||||
#define CDC_INT_EP1 0x83
|
||||
|
||||
/* v-uart2 */
|
||||
#define CDC_IN_EP2 0x82
|
||||
#define CDC_OUT_EP2 0x03
|
||||
#define CDC_INT_EP2 0x84
|
||||
|
||||
#if 0
|
||||
/* v-uart 3*/
|
||||
#define CDC_IN_EP3 0x83
|
||||
#define CDC_OUT_EP3 0x04
|
||||
#define CDC_INT_EP3 0x86
|
||||
|
||||
/* v-uart 4 */
|
||||
#define CDC_IN_EP4 0x84
|
||||
#define CDC_OUT_EP4 0x04
|
||||
#define CDC_INT_EP4 0x88
|
||||
#endif
|
||||
|
||||
#define USBD_VID 0x000F
|
||||
#define USBD_PID 0xFFFF
|
||||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[3][256];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[3][256];
|
||||
|
||||
|
||||
typedef void (*vuart_readcb)(uint8_t uart, char *data, uint32_t len);
|
||||
|
||||
typedef struct cdc_endpoints {
|
||||
uint8_t uart;
|
||||
uint8_t inep;
|
||||
uint8_t outep;
|
||||
uint8_t intep;
|
||||
uint8_t *rdbuf;
|
||||
uint8_t *wrbuf;
|
||||
vuart_readcb readcb;
|
||||
bool tx_busy;
|
||||
} cdc_endpoints;
|
||||
|
||||
cdc_endpoints *get_vuart(uint8_t ep);
|
||||
|
||||
void vuart_write(uint8_t uart, char *buf, uint8_t len) {
|
||||
volatile cdc_endpoints *cdcep = get_vuart(uart);
|
||||
if (cdcep == NULL) {
|
||||
LOG_W("Invalid vUART %d\r\n", uart);
|
||||
return;
|
||||
}
|
||||
LOG_I("Sending (%d) %d\r\n", uart, len);
|
||||
memcpy(cdcep->wrbuf, buf, len);
|
||||
cdcep->tx_busy = true;
|
||||
usbd_ep_start_write(cdcep->inep, cdcep->wrbuf, len);
|
||||
}
|
||||
|
||||
|
||||
void vuart_read(uint8_t uart, char *data, uint32_t len) {
|
||||
char buf[256];
|
||||
strlcpy(buf, data, MIN(len+1, 256));
|
||||
LOG_I("Read (%d): %s - %d %d\r\n", uart, buf, MIN(len, 2047), len);
|
||||
}
|
||||
|
||||
|
||||
cdc_endpoints vuart[] = {
|
||||
{1, CDC_IN_EP1, CDC_OUT_EP1, CDC_INT_EP1, read_buffer[0], write_buffer[0], &vuart_read, false},
|
||||
{2, CDC_IN_EP2, CDC_OUT_EP2, CDC_INT_EP2, read_buffer[1], write_buffer[1], &vuart_read, false},
|
||||
// {3, CDC_IN_EP3, CDC_OUT_EP3, CDC_INT_EP3, read_buffer[2], write_buffer[2], &vuart_read, false},
|
||||
};
|
||||
|
||||
cdc_endpoints *get_vuart_outep(uint8_t ep) {
|
||||
for (uint8_t i = 0; i < (sizeof(vuart)/sizeof(vuart[0])); i++) {
|
||||
if (vuart[i].outep == ep)
|
||||
return &vuart[i];
|
||||
}
|
||||
return NULL;
|
||||
};
|
||||
|
||||
cdc_endpoints *get_vuart_inep(uint8_t ep) {
|
||||
for (uint8_t i = 0; i < (sizeof(vuart)/sizeof(vuart[0])); i++) {
|
||||
if (vuart[i].inep == ep)
|
||||
return &vuart[i];
|
||||
}
|
||||
return NULL;
|
||||
};
|
||||
|
||||
cdc_endpoints *get_vuart(uint8_t uart) {
|
||||
for (uint8_t i = 0; i < (sizeof(vuart)/sizeof(vuart[0])); i++) {
|
||||
if (vuart[i].uart == uart)
|
||||
return &vuart[i];
|
||||
}
|
||||
return NULL;
|
||||
};
|
||||
|
||||
|
||||
/*!< config descriptor size */
|
||||
/* 3 devices */
|
||||
#define USB_CONFIG_SIZE (9 + 9 + 9 + (CDC_ACM_DESCRIPTOR_LEN * 1))
|
||||
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, USB_DEVICE_CLASS_MISC, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT((0x09 + 0x12 + (CDC_ACM_DESCRIPTOR_LEN * 2)), 0x05, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
DFU_DESCRIPTOR_INIT(),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP1, CDC_OUT_EP1, CDC_IN_EP1, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x03, CDC_INT_EP2, CDC_OUT_EP2, CDC_IN_EP2, 0x02),
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
USB_LANGID_INIT(USBD_LANGID_STRING),
|
||||
///////////////////////////////////////
|
||||
/// string1 descriptor
|
||||
///////////////////////////////////////
|
||||
0x0E, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'P', 0x00, /* wcChar0 */
|
||||
'I', 0x00, /* wcChar1 */
|
||||
'N', 0x00, /* wcChar2 */
|
||||
'E', 0x00, /* wcChar3 */
|
||||
'6', 0x00, /* wcChar4 */
|
||||
'4', 0x00, /* wcChar5 */
|
||||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
0x0A, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'O', 0x00, /* wcChar0 */
|
||||
'x', 0x00, /* wcChar1 */
|
||||
'6', 0x00, /* wcChar2 */
|
||||
'4', 0x00, /* wcChar3 */
|
||||
///////////////////////////////////////
|
||||
/// string3 descriptor
|
||||
///////////////////////////////////////
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'1', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
///////////////////////////////////////
|
||||
/// string4 descriptor - 0x58 000 000
|
||||
///////////////////////////////////////
|
||||
0x56, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'@', 0x00, /* wcChar0 */
|
||||
'M', 0x00, /* wcChar1 */
|
||||
'0', 0x00, /* wcChar2 */
|
||||
' ', 0x00, /* wcChar3 */
|
||||
'F', 0x00, /* wcChar4 */
|
||||
'l', 0x00, /* wcChar5 */
|
||||
'a', 0x00, /* wcChar6 */
|
||||
's', 0x00, /* wcChar7 */
|
||||
'h', 0x00, /* wcChar8 */
|
||||
' ', 0x00, /* wcChar17 */
|
||||
' ', 0x00, /* wcChar17 */
|
||||
' ', 0x00, /* wcChar17 */
|
||||
' ', 0x00, /* wcChar17 */
|
||||
'/', 0x00, /* wcChar18 */
|
||||
'0', 0x00, /* wcChar19 */
|
||||
'x', 0x00, /* wcChar20 */
|
||||
'5', 0x00, /* wcChar21*/
|
||||
'8', 0x00, /* wcChar22 */
|
||||
'0', 0x00, /* wcChar23 */
|
||||
'0', 0x00, /* wcChar24 */
|
||||
'0', 0x00, /* wcChar25 */
|
||||
'0', 0x00, /* wcChar26 */
|
||||
'0', 0x00, /* wcChar27 */
|
||||
'0', 0x00, /* wcChar28 */
|
||||
'/', 0x00, /* wcChar29 */
|
||||
'9', 0x00, /* wcChar30 */
|
||||
'9', 0x00, /* wcChar31*/
|
||||
'*', 0x00, /* wcChar32 */
|
||||
'0', 0x00, /* wcChar33 */
|
||||
'0', 0x00, /* wcChar34 */
|
||||
'1', 0x00, /* wcChar35 */
|
||||
'K', 0x00, /* wcChar36 */
|
||||
'g', 0x00, /* wcChar37 */
|
||||
',', 0x00, /* wcChar38 */
|
||||
'1', 0x00, /* wcChar39 */
|
||||
'1', 0x00, /* wcChar40 */
|
||||
'2', 0x00, /* wcChar41*/
|
||||
'*', 0x00, /* wcChar42 */
|
||||
'0', 0x00, /* wcChar43 */
|
||||
'1', 0x00, /* wcChar44 */
|
||||
'K', 0x00, /* wcChar45 */
|
||||
'g', 0x00, /* wcChar46 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
// 0x0a,
|
||||
// USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
// 0x00,
|
||||
// 0x02,
|
||||
// 0x02,
|
||||
// 0x02,
|
||||
// 0x01,
|
||||
// 0x40,
|
||||
// 0x01,
|
||||
// 0x00,
|
||||
0x09, // len
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, // bDescriptorType
|
||||
0x00, // bcdUSB
|
||||
0xEF, // bDeviceClass
|
||||
0x02, // bDeviceSubClass
|
||||
0x01, // bDeviceProtocol
|
||||
0x40, // bMaxPacketSize0
|
||||
0x01, // bNumConfigurations
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
/* setup first out ep read transfer */
|
||||
for (uint8_t i = 0; i < (sizeof(vuart)/sizeof(vuart[0])); i++) {
|
||||
LOG_I("Configure CDCEP: UART:%d IN:%d OUT:%d INT:%d RDptr:%p Wptr:%p\r\n", vuart[i].uart, vuart[i].inep, vuart[i].outep, vuart[i].intep, vuart[i].rdbuf, vuart[i].wrbuf);
|
||||
usbd_ep_start_read(vuart[i].outep, vuart[i].rdbuf, 256);
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
volatile cdc_endpoints *cdcep = get_vuart_outep(ep);
|
||||
if (cdcep == NULL) {
|
||||
LOG_W("Invalid CDC Endpoint %d\r\n", ep);
|
||||
return;
|
||||
}
|
||||
LOG_I("actual out len:%d ep: %d\r\n", nbytes, ep);
|
||||
cdcep->readcb(cdcep->uart, (char *)cdcep->rdbuf, nbytes);
|
||||
|
||||
/* setup next out ep read transfer */
|
||||
usbd_ep_start_read(cdcep->outep, cdcep->rdbuf, 256);
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_in(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
volatile cdc_endpoints *cdcep = get_vuart_inep(ep);
|
||||
if (cdcep == NULL) {
|
||||
LOG_W("Invalid CDC Endpoint %d\r\n", ep);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_I("actual in len:%d ep:%d\r\n", nbytes, ep);
|
||||
|
||||
if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(cdcep->inep, NULL, 0);
|
||||
} else {
|
||||
cdcep->tx_busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*!< endpoint call back */
|
||||
struct usbd_endpoint cdc_out_ep1 = {
|
||||
.ep_addr = CDC_OUT_EP1,
|
||||
.ep_cb = usbd_cdc_acm_bulk_out
|
||||
};
|
||||
|
||||
struct usbd_endpoint cdc_in_ep1 = {
|
||||
.ep_addr = CDC_IN_EP1,
|
||||
.ep_cb = usbd_cdc_acm_bulk_in
|
||||
};
|
||||
|
||||
struct usbd_endpoint cdc_out_ep2 = {
|
||||
.ep_addr = CDC_OUT_EP2,
|
||||
.ep_cb = usbd_cdc_acm_bulk_out
|
||||
};
|
||||
|
||||
struct usbd_endpoint cdc_in_ep2 = {
|
||||
.ep_addr = CDC_IN_EP2,
|
||||
.ep_cb = usbd_cdc_acm_bulk_in
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
struct usbd_endpoint cdc_out_ep3 = {
|
||||
.ep_addr = CDC_OUT_EP3,
|
||||
.ep_cb = usbd_cdc_acm_bulk_out
|
||||
};
|
||||
|
||||
struct usbd_endpoint cdc_in_ep3 = {
|
||||
.ep_addr = CDC_IN_EP3,
|
||||
.ep_cb = usbd_cdc_acm_bulk_in
|
||||
};
|
||||
#endif
|
||||
|
||||
struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
struct usbd_interface intf2;
|
||||
struct usbd_interface intf3;
|
||||
struct usbd_interface intf4;
|
||||
#if 0
|
||||
struct usbd_interface intf5;
|
||||
#endif
|
||||
|
||||
/* function ------------------------------------------------------------------*/
|
||||
void cdc_acm_multi_init(void)
|
||||
{
|
||||
usbd_desc_register(cdc_descriptor);
|
||||
/* DFU First */
|
||||
usbd_add_interface(usbd_dfu_init_intf(&intf0));
|
||||
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf1));
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf2));
|
||||
usbd_add_endpoint(&cdc_out_ep1);
|
||||
usbd_add_endpoint(&cdc_in_ep1);
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf3));
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf4));
|
||||
usbd_add_endpoint(&cdc_out_ep2);
|
||||
usbd_add_endpoint(&cdc_in_ep2);
|
||||
#if 0
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf4));
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf5));
|
||||
usbd_add_endpoint(&cdc_out_ep3);
|
||||
usbd_add_endpoint(&cdc_in_ep3);
|
||||
#endif
|
||||
usbd_initialize();
|
||||
}
|
||||
|
||||
volatile uint8_t dtr_enable = 0;
|
||||
|
||||
void usbd_cdc_acm_set_dtr(uint8_t intf, bool dtr)
|
||||
{
|
||||
LOG_I("DTR Change %d %d\r\n", intf, dtr);
|
||||
if (dtr) {
|
||||
dtr_enable = 1;
|
||||
} else {
|
||||
dtr_enable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_set_rts(uint8_t intf, bool rts) {
|
||||
LOG_I("RTS Change %d %d\r\n", intf, rts);
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_set_line_coding(uint8_t intf, struct cdc_line_coding *line_coding) {
|
||||
LOG_I("Line Coding Change %d %d %d %d\r\n", intf, line_coding->dwDTERate, line_coding->bCharFormat, line_coding->bParityType, line_coding->bDataBits);
|
||||
}
|
||||
|
||||
|
||||
uint8_t *dfu_read_flash(uint8_t *src, uint8_t *dest, uint32_t len)
|
||||
{
|
||||
LOG_I("DFU Read %lx %lx %ld\r\n", src, dest, len);
|
||||
uint32_t i = 0;
|
||||
uint8_t *psrc = src;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
dest[i] = *psrc++;
|
||||
}
|
||||
/* Return a valid address to avoid HardFault */
|
||||
return (uint8_t *)(dest);
|
||||
}
|
||||
|
||||
uint16_t dfu_write_flash(uint8_t *src, uint8_t *dest, uint32_t len)
|
||||
{
|
||||
LOG_I("DFU Write %lx %lx %ld\r\n", src, dest, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t dfu_erase_flash(uint32_t add)
|
||||
{
|
||||
LOG_I("DFU Erase %lx\r\n", add);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dfu_leave(void)
|
||||
{
|
||||
LOG_I("DFU Leave\r\n");
|
||||
dfu_reset();
|
||||
}
|
508
m0/src/usbd_dfu.c
Normal file
508
m0/src/usbd_dfu.c
Normal file
|
@ -0,0 +1,508 @@
|
|||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_dfu.h"
|
||||
#include "log.h"
|
||||
|
||||
/** Modify the following three parameters according to different platforms */
|
||||
// #ifndef USBD_DFU_XFER_SIZE
|
||||
// #define USBD_DFU_XFER_SIZE 256
|
||||
// #endif
|
||||
|
||||
#ifndef USBD_DFU_APP_DEFAULT_ADD
|
||||
#define USBD_DFU_APP_DEFAULT_ADD 0x58000000
|
||||
#endif
|
||||
|
||||
#ifndef FLASH_PROGRAM_TIME
|
||||
#define FLASH_PROGRAM_TIME 50
|
||||
#endif
|
||||
|
||||
#ifndef FLASH_ERASE_TIME
|
||||
#define FLASH_ERASE_TIME 50
|
||||
#endif
|
||||
|
||||
struct dfu_cfg_priv {
|
||||
// struct dfu_info info;
|
||||
union {
|
||||
uint32_t d32[USBD_DFU_XFER_SIZE / 4U];
|
||||
uint8_t d8[USBD_DFU_XFER_SIZE];
|
||||
} buffer;
|
||||
|
||||
uint32_t wblock_num;
|
||||
uint32_t wlength;
|
||||
uint32_t data_ptr;
|
||||
uint32_t alt_setting;
|
||||
|
||||
uint8_t dev_status[6];
|
||||
uint8_t ReservedForAlign[2];
|
||||
uint8_t dev_state;
|
||||
uint8_t manif_state;
|
||||
uint8_t firmwar_flag;
|
||||
} usbd_dfu_cfg;
|
||||
|
||||
void dfu_reset(void)
|
||||
{
|
||||
memset(&usbd_dfu_cfg, 0, sizeof(usbd_dfu_cfg));
|
||||
|
||||
usbd_dfu_cfg.alt_setting = 0U;
|
||||
usbd_dfu_cfg.data_ptr = USBD_DFU_APP_DEFAULT_ADD;
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
|
||||
usbd_dfu_cfg.manif_state = DFU_MANIFEST_COMPLETE;
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[0] = DFU_STATUS_OK;
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = DFU_STATE_DFU_IDLE;
|
||||
usbd_dfu_cfg.dev_status[5] = 0U;
|
||||
}
|
||||
|
||||
static uint16_t dfu_getstatus(uint32_t add, uint8_t cmd, uint8_t *buffer)
|
||||
{
|
||||
switch (cmd) {
|
||||
case DFU_MEDIA_PROGRAM:
|
||||
buffer[1] = (uint8_t)FLASH_PROGRAM_TIME;
|
||||
buffer[2] = (uint8_t)(FLASH_PROGRAM_TIME << 8);
|
||||
buffer[3] = 0;
|
||||
break;
|
||||
|
||||
case DFU_MEDIA_ERASE:
|
||||
buffer[1] = (uint8_t)FLASH_ERASE_TIME;
|
||||
buffer[2] = (uint8_t)(FLASH_ERASE_TIME << 8);
|
||||
buffer[3] = 0;
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void dfu_request_detach(void)
|
||||
{
|
||||
if ((usbd_dfu_cfg.dev_state == DFU_STATE_DFU_IDLE) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_SYNC) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_MANIFEST_SYNC) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) {
|
||||
/* Update the state machine */
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
usbd_dfu_cfg.dev_status[0] = DFU_STATUS_OK;
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U; /*bwPollTimeout=0ms*/
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
usbd_dfu_cfg.dev_status[5] = 0U; /*iString*/
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
struct usb_setup_packet *req = setup;
|
||||
uint32_t addr;
|
||||
/* Data setup request */
|
||||
if (req->wLength > 0U) {
|
||||
if ((usbd_dfu_cfg.dev_state == DFU_STATE_DFU_IDLE) || (usbd_dfu_cfg.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) {
|
||||
/* Update the global length and block number */
|
||||
usbd_dfu_cfg.wblock_num = req->wValue;
|
||||
usbd_dfu_cfg.wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE);
|
||||
LOG_I("upload Size %d %d\r\n", usbd_dfu_cfg.wlength, req->wLength);
|
||||
/* DFU Get Command */
|
||||
if (usbd_dfu_cfg.wblock_num == 0U) {
|
||||
/* Update the state machine */
|
||||
usbd_dfu_cfg.dev_state = (usbd_dfu_cfg.wlength > 3U) ? DFU_STATE_DFU_IDLE : DFU_STATE_DFU_UPLOAD_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
|
||||
/* Store the values of all supported commands */
|
||||
usbd_dfu_cfg.buffer.d8[0] = DFU_CMD_GETCOMMANDS;
|
||||
usbd_dfu_cfg.buffer.d8[1] = DFU_CMD_SETADDRESSPOINTER;
|
||||
usbd_dfu_cfg.buffer.d8[2] = DFU_CMD_ERASE;
|
||||
|
||||
/* Send the status data over EP0 */
|
||||
*data = usbd_dfu_cfg.buffer.d8;
|
||||
*len = 3;
|
||||
} else if (usbd_dfu_cfg.wblock_num > 1U) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_UPLOAD_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
|
||||
addr = ((usbd_dfu_cfg.wblock_num - 2U) * USBD_DFU_XFER_SIZE) + usbd_dfu_cfg.data_ptr;
|
||||
|
||||
/* Return the physical address where data are stored */
|
||||
dfu_read_flash((uint8_t *)addr, usbd_dfu_cfg.buffer.d8, usbd_dfu_cfg.wlength);
|
||||
|
||||
/* Send the status data over EP0 */
|
||||
*data = usbd_dfu_cfg.buffer.d8;
|
||||
*len = usbd_dfu_cfg.wlength;
|
||||
} else /* unsupported usbd_dfu_cfg.wblock_num */
|
||||
{
|
||||
usbd_dfu_cfg.dev_state = DFU_STATUS_ERR_STALLEDPKT;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
|
||||
/* Call the error management function (command will be NAKed */
|
||||
LOG_E("Dfu_request_upload unsupported usbd_dfu_cfg.wblock_num\r\n");
|
||||
}
|
||||
}
|
||||
/* Unsupported state */
|
||||
else {
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
|
||||
/* Call the error management function (command will be NAKed */
|
||||
LOG_E("Dfu_request_upload unsupported state\r\n");
|
||||
}
|
||||
}
|
||||
/* No Data setup request */
|
||||
else {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
}
|
||||
}
|
||||
|
||||
static void dfu_request_dnload(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
/* Data setup request */
|
||||
struct usb_setup_packet *req = setup;
|
||||
if (req->wLength > 0U) {
|
||||
LOG_I("State %d\r\n", usbd_dfu_cfg.dev_state);
|
||||
if ((usbd_dfu_cfg.dev_state == DFU_STATE_DFU_IDLE) || (usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_IDLE)) {
|
||||
/* Update the global length and block number */
|
||||
usbd_dfu_cfg.wblock_num = req->wValue;
|
||||
usbd_dfu_cfg.wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE);
|
||||
LOG_I("download Size %d %d\r\n", usbd_dfu_cfg.wlength, req->wLength);
|
||||
/* Update the state machine */
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_DNLOAD_SYNC;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
|
||||
/*!< Data has received complete */
|
||||
memcpy((uint8_t *)usbd_dfu_cfg.buffer.d8, (uint8_t *)*data, usbd_dfu_cfg.wlength);
|
||||
/*!< Set flag = 1 Write the firmware to the flash in the next dfu_request_getstatus */
|
||||
usbd_dfu_cfg.firmwar_flag = 1;
|
||||
}
|
||||
/* Unsupported state */
|
||||
else {
|
||||
LOG_E("Dfu_request_dnload unsupported state\r\n");
|
||||
}
|
||||
}
|
||||
/* 0 Data DNLOAD request */
|
||||
else {
|
||||
/* End of DNLOAD operation*/
|
||||
if ((usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) || (usbd_dfu_cfg.dev_state == DFU_STATE_DFU_IDLE)) {
|
||||
usbd_dfu_cfg.manif_state = DFU_MANIFEST_IN_PROGRESS;
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_MANIFEST_SYNC;
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
} else {
|
||||
/* Call the error management function (command will be NAKed */
|
||||
LOG_E("Dfu_request_dnload End of DNLOAD operation but dev_state %02x \r\n", usbd_dfu_cfg.dev_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int8_t dfu_getstatus_special_handler(void)
|
||||
{
|
||||
uint32_t addr;
|
||||
if (usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_BUSY) {
|
||||
/* Decode the Special Command */
|
||||
if (usbd_dfu_cfg.wblock_num == 0U) {
|
||||
if (usbd_dfu_cfg.wlength == 1U) {
|
||||
if (usbd_dfu_cfg.buffer.d8[0] == DFU_CMD_GETCOMMANDS) {
|
||||
/* Nothing to do */
|
||||
}
|
||||
} else if (usbd_dfu_cfg.wlength == 5U) {
|
||||
if (usbd_dfu_cfg.buffer.d8[0] == DFU_CMD_SETADDRESSPOINTER) {
|
||||
usbd_dfu_cfg.data_ptr = usbd_dfu_cfg.buffer.d8[1];
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[2] << 8;
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[3] << 16;
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[4] << 24;
|
||||
} else if (usbd_dfu_cfg.buffer.d8[0] == DFU_CMD_ERASE) {
|
||||
usbd_dfu_cfg.data_ptr = usbd_dfu_cfg.buffer.d8[1];
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[2] << 8;
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[3] << 16;
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[4] << 24;
|
||||
|
||||
LOG_I("Erase start add %08x \r\n", usbd_dfu_cfg.data_ptr);
|
||||
/*!< Erase */
|
||||
dfu_erase_flash(usbd_dfu_cfg.data_ptr);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* Reset the global length and block number */
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
/* Call the error management function (command will be NAKed) */
|
||||
LOG_E("Reset the global length and block number\r\n");
|
||||
}
|
||||
}
|
||||
/* Regular Download Command */
|
||||
else {
|
||||
if (usbd_dfu_cfg.wblock_num > 1U) {
|
||||
/* Decode the required address */
|
||||
addr = ((usbd_dfu_cfg.wblock_num - 2U) * USBD_DFU_XFER_SIZE) + usbd_dfu_cfg.data_ptr;
|
||||
|
||||
/* Perform the write operation */
|
||||
/* Write flash */
|
||||
LOG_I("Write start add %08x length %d\r\n", addr, usbd_dfu_cfg.wlength);
|
||||
dfu_write_flash(usbd_dfu_cfg.buffer.d8, (uint8_t *)addr, usbd_dfu_cfg.wlength);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the global length and block number */
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
|
||||
/* Update the state machine */
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_DNLOAD_SYNC;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dfu_request_getstatus(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
/*!< Determine whether to leave DFU mode */
|
||||
if (usbd_dfu_cfg.manif_state == DFU_MANIFEST_IN_PROGRESS &&
|
||||
usbd_dfu_cfg.dev_state == DFU_STATE_DFU_MANIFEST_SYNC &&
|
||||
usbd_dfu_cfg.dev_status[1] == 0U &&
|
||||
usbd_dfu_cfg.dev_status[2] == 0U &&
|
||||
usbd_dfu_cfg.dev_status[3] == 0U &&
|
||||
usbd_dfu_cfg.dev_status[4] == usbd_dfu_cfg.dev_state) {
|
||||
usbd_dfu_cfg.manif_state = DFU_MANIFEST_COMPLETE;
|
||||
|
||||
if ((0x0B & DFU_MANIFEST_MASK) != 0U) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_MANIFEST_SYNC;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
return;
|
||||
} else {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_MANIFEST_WAIT_RESET;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
/* Generate system reset to allow jumping to the user code */
|
||||
dfu_leave();
|
||||
}
|
||||
}
|
||||
|
||||
switch (usbd_dfu_cfg.dev_state) {
|
||||
case DFU_STATE_DFU_DNLOAD_SYNC:
|
||||
if (usbd_dfu_cfg.wlength != 0U) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_DNLOAD_BUSY;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
|
||||
if ((usbd_dfu_cfg.wblock_num == 0U) && (usbd_dfu_cfg.buffer.d8[0] == DFU_CMD_ERASE)) {
|
||||
dfu_getstatus(usbd_dfu_cfg.data_ptr, DFU_MEDIA_ERASE, usbd_dfu_cfg.dev_status);
|
||||
} else {
|
||||
dfu_getstatus(usbd_dfu_cfg.data_ptr, DFU_MEDIA_PROGRAM, usbd_dfu_cfg.dev_status);
|
||||
}
|
||||
} else /* (usbd_dfu_cfg.wlength==0)*/
|
||||
{
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_DNLOAD_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
}
|
||||
break;
|
||||
|
||||
case DFU_STATE_DFU_MANIFEST_SYNC:
|
||||
if (usbd_dfu_cfg.manif_state == DFU_MANIFEST_IN_PROGRESS) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_MANIFEST;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 1U; /*bwPollTimeout = 1ms*/
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
} else {
|
||||
if ((usbd_dfu_cfg.manif_state == DFU_MANIFEST_COMPLETE) &&
|
||||
((0x0B & DFU_MANIFEST_MASK) != 0U)) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Send the status data over EP0 */
|
||||
uint8_t temp_data[6];
|
||||
memcpy(temp_data, usbd_dfu_cfg.dev_status, 6);
|
||||
*data = temp_data;
|
||||
*len = 6;
|
||||
|
||||
if (usbd_dfu_cfg.firmwar_flag == 1) {
|
||||
if (dfu_getstatus_special_handler() != 0) {
|
||||
LOG_E("dfu_getstatus_special_handler error \r\n");
|
||||
}
|
||||
usbd_dfu_cfg.firmwar_flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void dfu_request_clrstatus(void)
|
||||
{
|
||||
if (usbd_dfu_cfg.dev_state == DFU_STATE_DFU_ERROR) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
usbd_dfu_cfg.dev_status[0] = DFU_STATUS_OK; /* bStatus */
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U; /* bwPollTimeout=0ms */
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state; /* bState */
|
||||
usbd_dfu_cfg.dev_status[5] = 0U; /* iString */
|
||||
} else {
|
||||
/* State Error */
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_ERROR;
|
||||
usbd_dfu_cfg.dev_status[0] = DFU_STATUS_ERR_UNKNOWN; /* bStatus */
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U; /* bwPollTimeout=0ms */
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state; /* bState */
|
||||
usbd_dfu_cfg.dev_status[5] = 0U; /* iString */
|
||||
}
|
||||
}
|
||||
|
||||
static void dfu_request_getstate(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
/* Return the current state of the DFU interface */
|
||||
*data = &usbd_dfu_cfg.dev_state;
|
||||
*len = 1;
|
||||
}
|
||||
|
||||
void dfu_request_abort(void)
|
||||
{
|
||||
if ((usbd_dfu_cfg.dev_state == DFU_STATE_DFU_IDLE) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_SYNC) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_MANIFEST_SYNC) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
usbd_dfu_cfg.dev_status[0] = DFU_STATUS_OK;
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U; /* bwPollTimeout=0ms */
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
usbd_dfu_cfg.dev_status[5] = 0U; /* iString */
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
static int dfu_class_interface_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
LOG_I("DFU Class request: "
|
||||
"bRequest 0x%02x len %d\r\n",
|
||||
setup->bRequest, len);
|
||||
|
||||
switch (setup->bRequest) {
|
||||
case DFU_REQUEST_DETACH:
|
||||
dfu_request_detach();
|
||||
break;
|
||||
case DFU_REQUEST_DNLOAD:
|
||||
dfu_request_dnload(setup, data, len);
|
||||
break;
|
||||
case DFU_REQUEST_UPLOAD:
|
||||
dfu_request_upload(setup, data, len);
|
||||
break;
|
||||
case DFU_REQUEST_GETSTATUS:
|
||||
dfu_request_getstatus(setup, data, len);
|
||||
break;
|
||||
case DFU_REQUEST_CLRSTATUS:
|
||||
dfu_request_clrstatus();
|
||||
break;
|
||||
case DFU_REQUEST_GETSTATE:
|
||||
dfu_request_getstate(setup, data, len);
|
||||
break;
|
||||
case DFU_REQUEST_ABORT:
|
||||
dfu_request_abort();
|
||||
break;
|
||||
default:
|
||||
LOG_E("Unhandled DFU Class bRequest 0x%02x\r\n", setup->bRequest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dfu_notify_handler(uint8_t event, void *arg)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
dfu_reset();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct usbd_interface *usbd_dfu_init_intf(struct usbd_interface *intf)
|
||||
{
|
||||
intf->class_interface_handler = dfu_class_interface_request_handler;
|
||||
intf->class_endpoint_handler = NULL;
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = dfu_notify_handler;
|
||||
|
||||
return intf;
|
||||
}
|
||||
|
||||
__WEAK uint8_t *dfu_read_flash(uint8_t *src, uint8_t *dest, uint32_t len)
|
||||
{
|
||||
return dest;
|
||||
}
|
||||
|
||||
__WEAK uint16_t dfu_write_flash(uint8_t *src, uint8_t *dest, uint32_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK uint16_t dfu_erase_flash(uint32_t add)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void dfu_leave(void)
|
||||
{
|
||||
}
|
Loading…
Add table
Reference in a new issue