From: yuhzheng Date: Fri, 10 Jan 2020 07:53:14 +0000 (+0000) Subject: Introduce a port for T-HEAD CK802. A simple demo for T-HEAD CB2201 is also included. X-Git-Tag: V10.3.0~21 X-Git-Url: https://git.sur5r.net/?p=freertos;a=commitdiff_plain;h=eb22b4ef7e59311b4e0439de0b3cf7356915a4d7 Introduce a port for T-HEAD CK802. A simple demo for T-HEAD CB2201 is also included. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2802 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/FreeRTOSConfig.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/FreeRTOSConfig.h new file mode 100644 index 000000000..ace104cd2 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/FreeRTOSConfig.h @@ -0,0 +1,101 @@ +/* + * 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 +#include "stdio.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. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned long ) 24000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) (256) ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) 16384 ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_CO_ROUTINES 0 +#define configUSE_MUTEXES 1 +#define configCHECK_FOR_STACK_OVERFLOW 1 +#define configUSE_RECURSIVE_MUTEXES 0 +#define configQUEUE_REGISTRY_SIZE 10 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY 1 +#define configTIMER_QUEUE_LENGTH 36 +#define configTIMER_TASK_STACK_DEPTH 1024 +#define configUSE_TIME_SLICING 1 +#define configUSE_COUNTING_SEMAPHORES 1 + +#define portCRITICAL_NESTING_IN_TCB 0 + + + + +/*#define configGENERATE_RUN_TIME_STATS 1*/ + +#define configMAX_PRIORITIES ( 200 ) +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* 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 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +#define configASSERT( a ) do {if ((a)==0){printf("Assert : %s %d\r\n", __FILE__, __LINE__);while(1);}}while(0) + +#define configKERNEL_INTERRUPT_PRIORITY ( ( unsigned char ) 7 << ( unsigned char ) 5 ) /* Priority 7, or 255 as only the top three bits are implemented. This is the lowest priority. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( ( unsigned char ) 5 << ( unsigned char ) 5 ) /* Priority 5, or 160 as only the top three bits are implemented. */ + +extern volatile unsigned long ulHighFrequencyTimerTicks; +/* There is already a high frequency timer running - just reset its count back +to zero. */ +/* +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ( ulHighFrequencyTimerTicks = 0UL ) +#define portGET_RUN_TIME_COUNTER_VALUE() ulHighFrequencyTimerTicks +*/ +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/RTOSDemo_CDK.cdkws.cxx b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/RTOSDemo_CDK.cdkws.cxx new file mode 100644 index 000000000..26bca8d93 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/RTOSDemo_CDK.cdkws.cxx @@ -0,0 +1,6 @@ + + + + + + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/RTOSDemo_CDK.session b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/RTOSDemo_CDK.session new file mode 100644 index 000000000..06446e7cf --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/RTOSDemo_CDK.session @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/RTOSDemo_CDK.tags b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/RTOSDemo_CDK.tags new file mode 100644 index 000000000..cbc38e0cc Binary files /dev/null and b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/RTOSDemo_CDK.tags differ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/compilation.db b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/compilation.db new file mode 100644 index 000000000..ffe8a393d Binary files /dev/null and b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/compilation.db differ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/refactoring.db b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/refactoring.db new file mode 100644 index 000000000..bda411557 Binary files /dev/null and b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/.cdk/refactoring.db differ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/Makefile b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/Makefile new file mode 100644 index 000000000..01560dbca --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/Makefile @@ -0,0 +1,9 @@ +.PHONY: clean All + +All: + @echo "----------Building project:[ RTOSDemo - BuildSet ]----------" + @ + @cd "RTOSDemo" && make -f "RTOSDemo.mk" MakeIntermediateDirs && make -f "RTOSDemo.mk" -j 8 +clean: + @echo "----------Cleaning project:[ RTOSDemo - BuildSet ]----------" + @cd "RTOSDemo" && make -f "RTOSDemo.mk" clean diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/RTOSDemo.session b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/RTOSDemo.session new file mode 100644 index 000000000..06a8eb6e9 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/RTOSDemo.session @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/RTOSDemo.tags b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/RTOSDemo.tags new file mode 100644 index 000000000..48f59420d Binary files /dev/null and b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/RTOSDemo.tags differ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/compilation.db b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/compilation.db new file mode 100644 index 000000000..ffe8a393d Binary files /dev/null and b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/compilation.db differ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/refactoring.db b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/refactoring.db new file mode 100644 index 000000000..bc6fc0342 Binary files /dev/null and b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/.cdk/refactoring.db differ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/Makefile b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/Makefile new file mode 100644 index 000000000..307c9dcc4 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/Makefile @@ -0,0 +1,9 @@ +.PHONY: clean All + +All: + @echo "----------Building project:[ RTOSDemo - BuildSet ]----------" + @ + @make -f "RTOSDemo.mk" MakeIntermediateDirs && make -f "RTOSDemo.mk" -j 8 +clean: + @echo "----------Cleaning project:[ RTOSDemo - BuildSet ]----------" + @make -f "RTOSDemo.mk" clean diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/RTOSDemo.cdkproj b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/RTOSDemo.cdkproj new file mode 100644 index 000000000..2b45bdf88 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/RTOSDemo.cdkproj @@ -0,0 +1,381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 37 + 47 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + uxDeletedTasksWaitingCleanUp:0 + 0xe000e100;;; + ;;MHZ + + 0 + 0 + + 100:8;100:8;100:8;100:8; + + + + + + + yes + 0x60000000 + 0x4000 + + + no + + + + + no + + + + + no + + + + + no + + + + + + + no + 0x20000000 + 0x80000 + yes + + + no + 0x50000000 + 0x800000 + yes + + + yes + 0x60004000 + 0xc000 + yes + + + no + + + yes + + + no + + + yes + + + ck802 + yes + little + no + yes + no + no + + + $(ProjectName) + Executable + no + no + no + yes + no + yes + + + + no + + + + no + + + + no + + + + + + + Optimize size (-Os) + Default (-g) + $(ProjectPath);$(ProjectPath)/../../driver;$(ProjectPath)/../../csi/csi_driver/include;$(ProjectPath)/../../csi/csi_driver/csky/hobbit1_2/include;$(ProjectPath)/../../csi/csi_driver/csky/common/usart;$(ProjectPath)/../../csi/csi_core/include;$(ProjectPath)/../../csi/csi_core/include/csi-gcc;$(ProjectPath)/../../csi/csi_core/ck802;$(ProjectPath)/../../;$(ProjectPath)/../../../../Source/include;$(ProjectPath)/../../../../Source/portable/ThirdParty/CDK/T-HEAD_CK802;$(ProjectPath)/../../../../Demo/Common/include + -ffunction-sections -fdata-sections -mistack + no + no + no + no + no + no + yes + no + no + no + + + + + $(ProjectPath);$(CDKPath)/CSKY/csi/csi_core/include/;$(CDKPath)/CSKY/csi/csi_core/csi_cdk/;$(CDKPath)/CSKY/csi/csi_driver/include/ + + gdwarf2 + + + yes + $(ProjectPath)/ckcpu.ld + + + + no + + + yes + ICE + yes + main + $(ProjectPath)/gdb.init + yes + Soft Reset + 60000000 + no + no + $(ProjectPath)/$(ProjectName).cdkcore + + localhost + 1025 + 12000 + 10 + 50 + yes + no + no + Normal + soft + 0 + None + no + yes + + Local + + + + + + yes + no + no + + + + $(ProjectPath)/flash.init + Erase Sectors + hobbit1_2_OTP_CDK.elf + no + no + no + Soft Reset + + no + + + + + + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/RTOSDemo.cdkws b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/RTOSDemo.cdkws new file mode 100644 index 000000000..6c03663fe --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/RTOSDemo.cdkws @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/chip_name.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/chip_name.c new file mode 100644 index 000000000..2ce840697 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/chip_name.c @@ -0,0 +1,50 @@ +/*============================================================================ + * Name : chip_name.c + * Author : $(UserName) + * Copyright : Your copyright notice + * Description : System Initialization before main + * 1 CPU initialization + * 2 memory & IO base address initialization + * 3 flash size & address initialization + * 4 interrupt resource initialization for the soc + *============================================================================ + */ +#include "chip_name.h" +/** + * @brief initial CPU based on user config in chip_name.h + */ +static void CPUInit(void) +{ + /** + * Config CPU's Unit such as MGU, Cache... + */ + + return; +} + +/** + * @brief entry of whole chip initialization + * @Note anyone should not use any global variable in this function since this function is called + * at before data section's initialization. + * Since here SystemInit is a weak symbol, any vendor can override this symbol on its own wishes. + */ + + #define CONFIG_SYSTICK_HZ 100 + #define CONFIG_SYSTEM_FREQ 24000000 + +__attribute__((weak)) void SystemInit(void) +{ + /** + * initial CPU based on the config in chip_name.h + */ + CPUInit(); + + /** + * TODO: initial IO, memory, flash... + */ + + drv_coret_config(CONFIG_SYSTEM_FREQ / CONFIG_SYSTICK_HZ, CORET_IRQn); //10ms + csi_vic_enable_sirq(CORET_IRQn); + + return; +} \ No newline at end of file diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/chip_name.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/chip_name.h new file mode 100644 index 000000000..4f9dc236b --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/chip_name.h @@ -0,0 +1,45 @@ +/* + * Description : chip_name.h - Define the system configuration such as: + * 1 CPU base config + * 2 memory & IO base address + * 3 flash size & address + * 4 interrupt resource for the soc. + * + * Copyright (C) : Hangzhou C-SKY Microsystems Co.,LTD. + * Date: 2016-08-22 + */ + +#ifndef __INCLUDE_CHIP_NAME_H__ +#define __INCLUDE_CHIP_NAME_H__ + +typedef enum IRQn +{ +/* ---------------------- CK801CM0 Specific Interrupt Numbers --------------------- */ + CORET_IRQn = 0, +} IRQn_Type; + +/* Configuration of the CK80# Processor and Core Peripherals */ +/* ToDo: set the defines according your Device */ +/* ToDo: define the correct core revision + __CK801_REV if your device is a CK801 device + __CK802_REV if your device is a CK802 device + __CK803S_REV if your device is a CK803S device */ +#define __NVIC_PRIO_BITS 2 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __MGU_PRESENT 0 /*!< MGU present or not */ + +/* Soft reset address */ +#define __RESET_CONST 0xabcd1234 + +/********************************************** + * Config CPU + * Define the attribute for your CPU + *********************************************/ +//#include "CSICORE_CK802.H" + +/******************************* + * Config IO base address + ******************************/ + + +#endif /* __INCLUDE_CHIP_NAME_H__ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/ckcpu.ld b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/ckcpu.ld new file mode 100644 index 000000000..68893e677 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/ckcpu.ld @@ -0,0 +1,150 @@ +/************************************************************* +// <<< Use Configuration Wizard in Context Menu >>> +*************************************************************/ + +/************************************************************* +// Entry Point <2> +// config start function for this application +*************************************************************/ +MEMORY +{ + ROM : ORIGIN = 0x0 , LENGTH = 0x2000 /* ROM 8KB*/ + EFLASH : ORIGIN = 0x60000000 , LENGTH = 0x4000 /* E-FLASH 252KB*/ + SRAM : ORIGIN = 0x60004000 , LENGTH = 0xC000 /* on-chip SRAM 80KB*/ +} + +__min_heap_size = 0x200; +PROVIDE (__ram_end = 0x60014000); +PROVIDE (__heap_end = __ram_end); + +REGION_ALIAS("REGION_TEXT", EFLASH); +REGION_ALIAS("REGION_RODATA", EFLASH); +REGION_ALIAS("REGION_DATA", SRAM); +REGION_ALIAS("REGION_BSS", SRAM); + +ENTRY(Reset_Handler) +SECTIONS +{ + .text : { + . = ALIGN(0x4) ; + *startup.o(*.text) + __stext = . ; + *(.text) + *(.text*) + *(.text.*) + *(.gnu.warning) + *(.stub) + *(.gnu.linkonce.t*) + *(.glue_7t) + *(.glue_7) + *(.jcr) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN (4) ; + PROVIDE(__ctbp = .); + *(.call_table_data) + *(.call_table_text) + . = ALIGN(0x10) ; + __etext = . ; + } > REGION_TEXT + .eh_frame_hdr : { + *(.eh_frame_hdr) + } > REGION_TEXT + .eh_frame : ONLY_IF_RO { + KEEP (*(.eh_frame)) + } > REGION_TEXT + .gcc_except_table : ONLY_IF_RO { + *(.gcc_except_table .gcc_except_table.*) + } > REGION_TEXT + .rodata : { + . = ALIGN(0x4) ; + __srodata = .; + *(.rdata) + *(.rdata*) + *(.rdata1) + *(.rdata.*) + *(.rodata) + *(.rodata1) + *(.rodata*) + *(.rodata.*) + *(.rodata.str1.4) + . = ALIGN(0x4) ; + __ctor_start__ = .; + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __ctor_end__ = .; + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __dtor_end__ = .; + . = ALIGN(0x4) ; + __erodata = .; + __rodata_end__ = .; + } > REGION_RODATA + .data : { + . = ALIGN(0x4) ; + __sdata = . ; + __data_start__ = . ; + data_start = . ; + KEEP(*startup.o(.vectors)) + *(.got.plt) + *(.got) + *(.gnu.linkonce.r*) + *(.data) + *(.data*) + *(.data1) + *(.data.*) + *(.gnu.linkonce.d*) + *(.data1) + *(.gcc_except_table) + *(.gcc_except_table*) + __start_init_call = .; + *(.initcall.init) + __stop_init_call = .; + __start_cmd = .; + *(.bootloaddata.cmd) + . = ALIGN(4) ; + __stop_cmd = .; + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(__libc_atexit) + *(__libc_subinit) + *(__libc_subfreeres) + *(.note.ABI-tag) + __edata = .; + __data_end__ = .; + . = ALIGN(0x4) ; + } > REGION_DATA AT > REGION_RODATA + .eh_frame : ONLY_IF_RW { + KEEP (*(.eh_frame)) + } > REGION_DATA AT > REGION_RODATA + .gcc_except_table : ONLY_IF_RW { + *(.gcc_except_table .gcc_except_table.*) + __edata = .; + __data_end__ = .; + } > REGION_DATA AT > REGION_RODATA + .bss : { + . = ALIGN(0x4) ; + __sbss = ALIGN(0x4) ; + __bss_start__ = . ; + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.scommon) + *(.dynbss) + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(0x4) ; + __ebss = . ; + __bss_end__ = .; + __end = . ; + end = . ; + } > REGION_BSS AT > REGION_BSS + ._user_heap : { + . = ALIGN(0x4) ; + __heap_start = .; + . += __min_heap_size; + . = ALIGN(0x4) ; + } > REGION_BSS AT > REGION_BSS +} \ No newline at end of file diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/crt0.S b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/crt0.S new file mode 100644 index 000000000..a72543a71 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/crt0.S @@ -0,0 +1,195 @@ +/* + * crt0.S + * 1 define and initial the stack pointer + * 2 exception handler table + * 3 call SystemInit + * 4 go to __main in entry.o + * + * Copyright (C) 2016~2017 Hangzhou C-SKY Microsystems Co., Ltd + * Modify by Jiang Long on 2016-09-14 + */ +// <<< Use Configuration Wizard in Context Menu >>> + +/* + * For importing variable or functions from other c or assemble files. + */ +.import main + +/* + * default service routine + */ +.global Reset_Handler +.global Misaligned_Access_Handler +.global Access_Error_Handler +.global Divided_By_Zero_Handler +.global Illegal_Handler +.global Privlege_Violation_Handler +.global Trace_Exection_Handler +.global Breakpoint_Exception_Handler +.global Unrecoverable_Error_Handler +.global Idly4_Error_Handler +.global Auto_INT_Handler +.global Auto_FINT_Handler +.global Reserved_HAI_Handler +.global Reserved_FP_Handler +.global TLB_Ins_Empty_Handler +.global TLB_Data_Empty_Handler +.global Default_handler + +.weak Reset_Handler +.weak Misaligned_Access_Handler +.weak Access_Error_Handler +.weak Divided_By_Zero_Handler +.weak Illegal_Handler +.weak Privlege_Violation_Handler +.weak Trace_Exection_Handler +.weak Breakpoint_Exception_Handler +.weak Unrecoverable_Error_Handler +.weak Idly4_Error_Handler +.weak Auto_INT_Handler +.weak Auto_FINT_Handler +.weak Reserved_HAI_Handler +.weak Reserved_FP_Handler +.weak TLB_Ins_Empty_Handler +.weak TLB_Data_Empty_Handler +.weak Default_handler + + +.export ckcpu_vsr_table /* Vector table base address. */ +.section .exp_table,"ax",@progbits +/* Vector table space. */ +$d: +.align 10 +ckcpu_vsr_table: + .long Reset_Handler + .long Misaligned_Access_Handler + .long Access_Error_Handler + .long Divided_By_Zero_Handler + .long Illegal_Handler + .long Privlege_Violation_Handler + .long Trace_Exection_Handler + .long Breakpoint_Exception_Handler + .long Unrecoverable_Error_Handler + .long Idly4_Error_Handler + .long Auto_INT_Handler + .long Auto_FINT_Handler + .long Reserved_HAI_Handler + .long Reserved_FP_Handler + .long TLB_Ins_Empty_Handler + .long TLB_Data_Empty_Handler + +.rept 32 + .long NOVIC_IRQ_Default_Handler +.endr +$t: +/* The ckcpu startup codes. */ +.text +.align 2 + /* + * This is the codes first entry point. This is where it all begins... + */ +Reset_Handler: + /* + * Init psr value, enable exception, disable interrupt and fast interrupt. + * psr = 0x80000100 + */ + bgeni r7, 31 + bseti r7, 30 + bseti r7, 29 + bseti r7, 8 + mtcr r7, psr + + /* + * Setup initial vector base table for interrupts and exceptions + */ + lrw a3, ckcpu_vsr_table + mtcr a3, vbr + + /* Initialize the normal stack pointer from the linker definition. */ + lrw r0, g_top_irqstack + mov sp, r0 + +/* + * The ranges of copy from/to are specified by following symbols + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to + * __data_end__: VMA of end of the section to copy to + * + * All addresses must be aligned to 4 bytes boundary. + */ + lrw r1, __erodata + lrw r2, __data_start__ + lrw r3, __data_end__ + + subu r3, r2 + cmpnei r3, 0 + bf .L_loop0_done + +.L_loop0: + ldw r0, (r1, 0) + stw r0, (r2, 0) + addi r1, 4 + addi r2, 4 + subi r3, 4 + cmpnei r3, 0 + bt .L_loop0 + +.L_loop0_done: + +/* + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * Both addresses must be aligned to 4 bytes boundary. + */ + lrw r1, __bss_start__ + lrw r2, __bss_end__ + + movi r0, 0 + + subu r2, r1 + cmpnei r2, 0 + bf .L_loop1_done + +.L_loop1: + stw r0, (r1, 0) + addi r1, 4 + subi r2, 4 + cmpnei r2, 0 + bt .L_loop1 +.L_loop1_done: + + jbsr main + /* Should never get here. */ +1: + br 1b +Misaligned_Access_Handler: +Access_Error_Handler: +Divided_By_Zero_Handler: +Illegal_Handler: +Privlege_Violation_Handler: +Trace_Exection_Handler: +Breakpoint_Exception_Handler: +Unrecoverable_Error_Handler: +Idly4_Error_Handler: +Auto_INT_Handler: +Auto_FINT_Handler: +Reserved_HAI_Handler: +Reserved_FP_Handler: +TLB_Ins_Empty_Handler: +TLB_Data_Empty_Handler: +Default_handler: + br Default_handler + rte + +.section .bss + + .align 2 + .global g_intstackalloc + .global g_intstackbase + .global g_top_irqstack +g_intstackalloc: +g_intstackbase: + .space 4096 +g_top_irqstack: \ No newline at end of file diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/flash.init b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/flash.init new file mode 100644 index 000000000..6120b37d0 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/flash.init @@ -0,0 +1,4 @@ + + + + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/gdb.init b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/gdb.init new file mode 100644 index 000000000..8bc3f58ca --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/gdb.init @@ -0,0 +1,6 @@ +set *0x4000202c=0xc0206 +set *0x40002004=0x8 + +set $pc=0x60000000 +set $psr=0xe0000000 + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/main.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/main.c new file mode 100644 index 000000000..45c172810 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo/main.c @@ -0,0 +1,123 @@ +/*============================================================================ + * Name : main.c + * Author : $(username) + * Version : 0.0.0 + * Copyright : Your copyright notice + * Description : Simple function in C, Ansi-style + *============================================================================ + */ + + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +extern void SystemInit(void); + +#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) + +#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) + + +/* The number of items the queue can hold. This is 1 as the receive task + +will remove items as they are added, meaning the send task should always find + +the queue empty. */ + +#define mainQUEUE_LENGTH ( 1 ) + +static QueueHandle_t xQueue = NULL; + +static void prvQueueSendTask( void *pvParameters ) +{ + TickType_t xNextWakeTime; + const unsigned long ulValueToSend = 100UL; + + + /* Initialise xNextWakeTime - this only needs to be done once. */ + + xNextWakeTime = xTaskGetTickCount(); + + for( ;; ) + + { + + /* Place this task in the blocked state until it is time to run again. + + The block time is specified in ticks, the constant used converts ticks + + to ms. While in the Blocked state this task will not consume any CPU + + time. */ + + vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); + + + /* Send to the queue - causing the queue receive task to unblock and + + toggle an LED. 0 is used as the block time so the sending operation + + will not block - it shouldn't need to block as the queue should always + + be empty at this point in the code. */ + + xQueueSend( xQueue, &ulValueToSend, 0 ); + + } + +} + +static void prvQueueReceiveTask( void *pvParameters ) +{ + unsigned int ulReceivedValue; + + for( ;; ) + { + + /* Wait until something arrives in the queue - this task will block + + indefinitely provided INCLUDE_vTaskSuspend is set to 1 in + + FreeRTOSConfig.h. */ + + xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); + + + + /* To get here something must have been received from the queue, but + + is it the expected value? If it is, toggle the green LED. */ + + if( ulReceivedValue == 100UL ) + { + printf("Recieve expected value : %d\n", ulReceivedValue); + } + else + { + printf("Recieve unexpected value : %d\n", ulReceivedValue); + } + + } + +} + +int main() +{ + SystemInit(); + + xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); + if (xQueue != NULL) + { + xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); + + xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); + + vTaskStartScheduler(); + } + + + return 0; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo_CDK.cdkws b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo_CDK.cdkws new file mode 100644 index 000000000..382f7dd85 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/RTOSDemo_CDK.cdkws @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/hobbit1_2_OTP_CDK.elf b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/hobbit1_2_OTP_CDK.elf new file mode 100644 index 000000000..5cee76925 Binary files /dev/null and b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/RTOSDemo_CDK/hobbit1_2_OTP_CDK.elf differ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/Readme.txt b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/Readme.txt new file mode 100644 index 000000000..2a4e1bcd7 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/Readme.txt @@ -0,0 +1,19 @@ +# T-HEAD CB2201 Demo Project + +The demo shows inter-task communication using a queue. +The sender periodically sends a constant value to the queue. The receiver blocks until +the next value is received and validates it. Receiver prints evaluation result to output. + + +## References +CB2201 development board: https://occ.t-head.cn/#/vendor_product_detail?id=635878225301471232&vendorId=3706716635429273600&module=4 +The latest version of CDK: https://occ.t-head.cn/community/download_detail?spm=a2oza.cdk.0.0.413b180fZ5hVxQ&id=575997419775328256 + + +## Getting started +1. Download the latest version of CDK and follow CDK installation wizard to intall. +2. Open RTOSDemo.cdkproj under ./RTOSDemo_CDK/RTOSDemo/ +3. Build project. +4. Connect to T-HEAD Cb2201 board. (Make sure serial cable is connected correctly.) +5. Run. +6. Check messages in serial window. \ No newline at end of file diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/VERSION b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/VERSION new file mode 100644 index 000000000..88acfb504 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/VERSION @@ -0,0 +1 @@ +CSI-CORE v1.0 diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/ck802/core_ck802.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/ck802/core_ck802.c new file mode 100644 index 000000000..4c68b5a96 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/ck802/core_ck802.c @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file core_ck802.c + * @brief CSI CK802 Core Peripheral Access Layer File + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#include +#include +#include + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core VIC Functions + - Core CORET Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CSI_Core_FunctionInterface Functions and Instructions Reference +*/ + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under CSKYv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +static uint32_t s_nvic_prio_bits = __NVIC_PRIO_BITS; + +/** + \brief initialize the NVIC interrupt controller + \param [in] prio_bits the priority bits of NVIC interrupt controller. + */ +void drv_nvic_init(uint32_t prio_bits) +{ + if (s_nvic_prio_bits >= 8U) { + return; + } + + s_nvic_prio_bits = prio_bits; +} + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +void drv_nvic_enable_irq(int32_t IRQn) +{ + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISSR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +void drv_nvic_disable_irq(int32_t IRQn) +{ + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + +/** + \brief Enable External Secure Interrupt + \details Enables a secure device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +void drv_nvic_enable_sirq(int32_t IRQn) +{ + NVIC->ISSR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +uint32_t drv_nvic_get_pending_irq(int32_t IRQn) +{ + return ((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +void drv_nvic_set_pending_irq(int32_t IRQn) +{ + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +void drv_nvic_clear_pending_irq(int32_t IRQn) +{ + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + +/** + \brief Get Wake up Interrupt + \details Reads the wake up register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt is not set as wake up interrupt. + \return 1 Interrupt is set as wake up interrupt. + */ +uint32_t drv_nvic_get_wakeup_irq(int32_t IRQn) +{ + return ((uint32_t)(((NVIC->IWER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + +/** + \brief Set Wake up Interrupt + \details Sets the wake up bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +void drv_nvic_set_wakeup_irq(int32_t IRQn) +{ + NVIC->IWER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + +/** + \brief Clear Wake up Interrupt + \details Clears the wake up bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +void drv_nvic_clear_wakeup_irq(int32_t IRQn) +{ + NVIC->IWDR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +uint32_t drv_nvic_get_active(int32_t IRQn) +{ + return ((uint32_t)(((NVIC->IABR[0] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + +/** + \brief Set Threshold register + \details set the threshold register in the NVIC. + \param [in] VectThreshold specific vecter threshold. + \param [in] PrioThreshold specific priority threshold. + */ +void drv_nvic_set_threshold(uint32_t VectThreshold, uint32_t PrioThreshold) +{ + NVIC->IPTR = 0x80000000 | (((VectThreshold + 32) & 0xFF) << 8) | ((PrioThreshold & 0x3) << 6); +} + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +void drv_nvic_set_prio(int32_t IRQn, uint32_t priority) +{ + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - s_nvic_prio_bits)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); +} + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +uint32_t drv_nvic_get_prio(int32_t IRQn) +{ + return ((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & (uint32_t)0xFFUL) >> (8U - s_nvic_prio_bits))); +} + + +/*@} end of CSI_Core_NVICFunctions */ + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + + +/** + \brief CORE timer Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \param [in] IRQn core timer Interrupt number. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +uint32_t drv_coret_config(uint32_t ticks, int32_t IRQn) +{ + if ((ticks - 1UL) > CORET_LOAD_RELOAD_Msk) { + return (1UL); /* Reload value impossible */ + } + + CORET->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + //drv_nvic_set_prio(IRQn, (1UL << s_nvic_prio_bits) - 1UL); fix me /* set Priority for Systick Interrupt */ + CORET->VAL = 0UL; /* Load the CORET Counter Value */ + CORET->CTRL = CORET_CTRL_CLKSOURCE_Msk | + CORET_CTRL_TICKINT_Msk | + CORET_CTRL_ENABLE_Msk; /* Enable CORET IRQ and CORET Timer */ + return (0UL); /* Function successful */ +} + +/** + \brief get CORE timer reload value + \return CORE timer counter value. + */ +uint32_t drv_coret_get_load(void) +{ + return CORET->LOAD; +} + +/** + \brief get CORE timer counter value + \return CORE timer counter value. + */ +uint32_t drv_coret_get_value(void) +{ + return CORET->VAL; +} + +/*@} end of CSI_Core_SysTickFunctions */ + +#if 0 +/* ##################################### DCC function ########################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_core_DebugFunctions HAD Functions + \brief Functions that access the HAD debug interface. + @{ + */ + +/** + \brief HAD Send Character + \details Transmits a character via the HAD channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +uint32_t HAD_SendChar(uint32_t ch) +{ + DCC->DERJR = (uint8_t)ch; + + return (ch); +} + + +/** + \brief HAD Receive Character + \details Inputs a character via the external variable \ref HAD_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +int32_t HAD_ReceiveChar(void) +{ + int32_t ch = -1; /* no character available */ + + if (_FLD2VAL(DCC_EHSR_JW, DCC->EHSR)) { + ch = DCC->DERJW; + } + + return (ch); +} + + +/** + \brief HAD Check Character + \details Checks whether a character is pending for reading in the variable \ref HAD_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +int32_t HAD_CheckChar(void) +{ + return _FLD2VAL(DCC_EHSR_JW, DCC->EHSR); /* no character available */ +} + +#endif + +/*@} end of CSI_core_DebugFunctions */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/ck802/core_ck802.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/ck802/core_ck802.h new file mode 100644 index 000000000..2b365d761 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/ck802/core_ck802.h @@ -0,0 +1,546 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file core_ck802.h + * @brief CSI CK802 Core Peripheral Access Layer Header File + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef __CORE_CK802_H_GENERIC +#define __CORE_CK802_H_GENERIC + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * CSI definitions + ******************************************************************************/ +/** + \ingroup Ck802 + @{ + */ + +/* CSI CK802 definitions */ +#define __CK802_CSI_VERSION_MAIN (0x04U) /*!< [31:16] CSI HAL main version */ +#define __CK802_CSI_VERSION_SUB (0x1EU) /*!< [15:0] CSI HAL sub version */ +#define __CK802_CSI_VERSION ((__CK802_CSI_VERSION_MAIN << 16U) | \ + __CK802_CSI_VERSION_SUB ) /*!< CSI HAL version number */ +#ifndef __CK80X +#define __CK80X (0x02U) /*!< CK80X Core */ +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __GNUC__ ) +#if defined (__VFP_FP__) && !defined(__SOFTFP__) +#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif +#endif + +#include "csi_gcc.h" + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CK802_H_GENERIC */ + +#ifndef __CSI_GENERIC + +#ifndef __CORE_CK802_H_DEPENDANT +#define __CORE_CK802_H_DEPENDANT + +#ifdef __cplusplus +extern "C" { +#endif + +/* check device defines and use defaults */ +//#if defined __CHECK_DEVICE_DEFINES +#ifndef __CK802_REV +#define __CK802_REV 0x0000U +//#warning "__CK802_REV not defined in device header file; using default!" +#endif + +#ifndef __NVIC_PRIO_BITS +#define __NVIC_PRIO_BITS 2U +//#warning "__NVIC_PRIO_BITS not defined in device header file; using default!" +#endif + +#ifndef __Vendor_SysTickConfig +#define __Vendor_SysTickConfig 0U +//#warning "__Vendor_SysTickConfig not defined in device header file; using default!" +#endif + +#ifndef __GSR_GCR_PRESENT +#define __GSR_GCR_PRESENT 0U +//#warning "__GSR_GCR_PRESENT not defined in device header file; using default!" +#endif + +#ifndef __MGU_PRESENT +#define __MGU_PRESENT 0U +//#warning "__MGU_PRESENT not defined in device header file; using default!" +#endif +//#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CSI_glob_defs CSI Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus +#define __I volatile /*!< Defines 'read only' permissions */ +#else +#define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + + /* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + + /*@} end of group CK802 */ + + /******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ + /** + \defgroup CSI_core_register Defines and Type Definitions + \brief Type definitions and defines for CK80X processor based devices. + */ + + /** + \ingroup CSI_core_register + \defgroup CSI_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + + /** + \brief 访问处理器状态寄存器(PSR)的联合体定义. + */ + typedef union { + struct { + uint32_t C: 1; /*!< bit: 0 条件码/进位位 */ + uint32_t _reserved0: 5; /*!< bit: 2.. 5 保留 */ + uint32_t IE: 1; /*!< bit: 6 中断有效控制位 */ + uint32_t IC: 1; /*!< bit: 7 中断控制位 */ + uint32_t EE: 1; /*!< bit: 8 异常有效控制位 */ + uint32_t MM: 1; /*!< bit: 9 不对齐异常掩盖位 */ + uint32_t _reserved1: 6; /*!< bit: 10..15 保留 */ + uint32_t VEC: 8; /*!< bit: 16..23 异常事件向量值 */ + uint32_t _reserved2: 7; /*!< bit: 24..30 保留 */ + uint32_t S: 1; /*!< bit: 31 超级用户模式设置位 */ + } b; /*!< Structure 用来按位访问 */ + uint32_t w; /*!< Type 整个寄存器访问 */ + } PSR_Type; + + /* PSR Register Definitions */ +#define PSR_S_Pos 31U /*!< PSR: S Position */ +#define PSR_S_Msk (1UL << PSR_S_Pos) /*!< PSR: S Mask */ + +#define PSR_VEC_Pos 16U /*!< PSR: VEC Position */ +#define PSR_VEC_Msk (0x7FUL << PSR_VEC_Pos) /*!< PSR: VEC Mask */ + +#define PSR_MM_Pos 9U /*!< PSR: MM Position */ +#define PSR_MM_Msk (1UL << PSR_MM_Pos) /*!< PSR: MM Mask */ + +#define PSR_EE_Pos 8U /*!< PSR: EE Position */ +#define PSR_EE_Msk (1UL << PSR_EE_Pos) /*!< PSR: EE Mask */ + +#define PSR_IC_Pos 7U /*!< PSR: IC Position */ +#define PSR_IC_Msk (1UL << PSR_IC_Pos) /*!< PSR: IC Mask */ + +#define PSR_IE_Pos 6U /*!< PSR: IE Position */ +#define PSR_IE_Msk (1UL << PSR_IE_Pos) /*!< PSR: IE Mask */ + +#define PSR_C_Pos 0U /*!< PSR: C Position */ +#define PSR_C_Msk (1UL << PSR_C_Pos) /*!< PSR: C Mask */ + + /** + \brief 访问高速缓存配置寄存器(CCR, CR<18, 0>)的联合体定义. + */ + typedef union { + struct { + uint32_t MP: 1; /*!< bit: 0 内存保护设置位 */ + uint32_t _reserved0: 6; /*!< bit: 1.. 6 保留 */ + uint32_t BE: 1; /*!< bit: 7 Endian模式 */ + uint32_t SCK: 3; /*!< bit: 8..10 系统和处理器的时钟比 */ + uint32_t _reserved1: 2; /*!< bit: 11..12 保留 */ + uint32_t BE_V2: 1; /*!< bit: 13 V2版本大小端 */ + uint32_t _reserved2: 18; /*!< bit: 14..31 保留 */ + } b; /*!< Structure 用来按位访问 */ + uint32_t w; /*!< Type 整个寄存器访问 */ + } CCR_Type; + + /* CCR Register Definitions */ +#define CCR_BE_V2_Pos 13U /*!< CCR: BE_V2 Position */ +#define CCR_BE_V2_Msk (0x1UL << CCR_ISR_Pos) /*!< CCR: BE_V2 Mask */ + +#define CCR_SCK_Pos 8U /*!< CCR: SCK Position */ +#define CCR_SCK_Msk (0x3UL << CCR_SCK_Pos) /*!< CCR: SCK Mask */ + +#define CCR_BE_Pos 7U /*!< CCR: BE Position */ +#define CCR_BE_Msk (0x1UL << CCR_BE_Pos) /*!< CCR: BE Mask */ + +#define CCR_MP_Pos 0U /*!< CCR: MP Position */ +#define CCR_MP_Msk (0x1UL << CCR_MP_Pos) /*!< CCR: MP Mask */ + + /** + \brief 访问可高缓和访问权限配置寄存器(CAPR, CR<19,0>)的联合体定义.. + */ + typedef union { + struct { + uint32_t X0: 1; /*!< bit: 0 不可执行属性设置位 */ + uint32_t X1: 1; /*!< bit: 1 不可执行属性设置位 */ + uint32_t X2: 1; /*!< bit: 2 不可执行属性设置位 */ + uint32_t X3: 1; /*!< bit: 3 不可执行属性设置位 */ + uint32_t X4: 1; /*!< bit: 4 不可执行属性设置位 */ + uint32_t X5: 1; /*!< bit: 5 不可执行属性设置位 */ + uint32_t X6: 1; /*!< bit: 6 不可执行属性设置位 */ + uint32_t X7: 1; /*!< bit: 7 不可执行属性设置位 */ + uint32_t AP0: 2; /*!< bit: 8.. 9 访问权限设置位 */ + uint32_t AP1: 2; /*!< bit: 10..11 访问权限设置位 */ + uint32_t AP2: 2; /*!< bit: 12..13 访问权限设置位 */ + uint32_t AP3: 2; /*!< bit: 14..15 访问权限设置位 */ + uint32_t AP4: 2; /*!< bit: 16..17 访问权限设置位 */ + uint32_t AP5: 2; /*!< bit: 18..19 访问权限设置位 */ + uint32_t AP6: 2; /*!< bit: 20..21 访问权限设置位 */ + uint32_t AP7: 2; /*!< bit: 22..23 访问权限设置位 */ + uint32_t S0: 1; /*!< bit: 24 安全属性设置位 */ + uint32_t S1: 1; /*!< bit: 25 安全属性设置位 */ + uint32_t S2: 1; /*!< bit: 26 安全属性设置位 */ + uint32_t S3: 1; /*!< bit: 27 安全属性设置位 */ + uint32_t S4: 1; /*!< bit: 28 安全属性设置位 */ + uint32_t S5: 1; /*!< bit: 29 安全属性设置位 */ + uint32_t S6: 1; /*!< bit: 30 安全属性设置位 */ + uint32_t S7: 1; /*!< bit: 31 安全属性设置位 */ + } b; /*!< Structure 用来按位访问 */ + uint32_t w; /*!< Type 整个寄存器访问 */ + } CAPR_Type; + + /* CAPR Register Definitions */ +#define CAPR_S7_Pos 31U /*!< CAPR: S7 Position */ +#define CAPR_S7_Msk (1UL << CAPR_S7_Pos) /*!< CAPR: S7 Mask */ + +#define CAPR_S6_Pos 30U /*!< CAPR: S6 Position */ +#define CAPR_S6_Msk (1UL << CAPR_S6_Pos) /*!< CAPR: S6 Mask */ + +#define CAPR_S5_Pos 29U /*!< CAPR: S5 Position */ +#define CAPR_S5_Msk (1UL << CAPR_S5_Pos) /*!< CAPR: S5 Mask */ + +#define CAPR_S4_Pos 28U /*!< CAPR: S4 Position */ +#define CAPR_S4_Msk (1UL << CAPR_S4_Pos) /*!< CAPR: S4 Mask */ + +#define CAPR_S3_Pos 27U /*!< CAPR: S3 Position */ +#define CAPR_S3_Msk (1UL << CAPR_S3_Pos) /*!< CAPR: S3 Mask */ + +#define CAPR_S2_Pos 26U /*!< CAPR: S2 Position */ +#define CAPR_S2_Msk (1UL << CAPR_S2_Pos) /*!< CAPR: S2 Mask */ + +#define CAPR_S1_Pos 25U /*!< CAPR: S1 Position */ +#define CAPR_S1_Msk (1UL << CAPR_S1_Pos) /*!< CAPR: S1 Mask */ + +#define CAPR_S0_Pos 24U /*!< CAPR: S0 Position */ +#define CAPR_S0_Msk (1UL << CAPR_S0_Pos) /*!< CAPR: S0 Mask */ + +#define CAPR_AP7_Pos 22U /*!< CAPR: AP7 Position */ +#define CAPR_AP7_Msk (0x3UL << CAPR_AP7_Pos) /*!< CAPR: AP7 Mask */ + +#define CAPR_AP6_Pos 20U /*!< CAPR: AP6 Position */ +#define CAPR_AP6_Msk (0x3UL << CAPR_AP6_Pos) /*!< CAPR: AP6 Mask */ + +#define CAPR_AP5_Pos 18U /*!< CAPR: AP5 Position */ +#define CAPR_AP5_Msk (0x3UL << CAPR_AP5_Pos) /*!< CAPR: AP5 Mask */ + +#define CAPR_AP4_Pos 16U /*!< CAPR: AP4 Position */ +#define CAPR_AP4_Msk (0x3UL << CAPR_AP4_Pos) /*!< CAPR: AP4 Mask */ + +#define CAPR_AP3_Pos 14U /*!< CAPR: AP3 Position */ +#define CAPR_AP3_Msk (0x3UL << CAPR_AP3_Pos) /*!< CAPR: AP3 Mask */ + +#define CAPR_AP2_Pos 12U /*!< CAPR: AP2 Position */ +#define CAPR_AP2_Msk (0x3UL << CAPR_AP2_Pos) /*!< CAPR: AP2 Mask */ + +#define CAPR_AP1_Pos 10U /*!< CAPR: AP1 Position */ +#define CAPR_AP1_Msk (0x3UL << CAPR_AP1_Pos) /*!< CAPR: AP1 Mask */ + +#define CAPR_AP0_Pos 8U /*!< CAPR: AP0 Position */ +#define CAPR_AP0_Msk (0x3UL << CAPR_AP0_Pos) /*!< CAPR: AP0 Mask */ + +#define CAPR_X7_Pos 7U /*!< CAPR: X7 Position */ +#define CAPR_X7_Msk (0x1UL << CAPR_X7_Pos) /*!< CAPR: X7 Mask */ + +#define CAPR_X6_Pos 6U /*!< CAPR: X6 Position */ +#define CAPR_X6_Msk (0x1UL << CAPR_X6_Pos) /*!< CAPR: X6 Mask */ + +#define CAPR_X5_Pos 5U /*!< CAPR: X5 Position */ +#define CAPR_X5_Msk (0x1UL << CAPR_X5_Pos) /*!< CAPR: X5 Mask */ + +#define CAPR_X4_Pos 4U /*!< CAPR: X4 Position */ +#define CAPR_X4_Msk (0x1UL << CAPR_X4_Pos) /*!< CAPR: X4 Mask */ + +#define CAPR_X3_Pos 3U /*!< CAPR: X3 Position */ +#define CAPR_X3_Msk (0x1UL << CAPR_X3_Pos) /*!< CAPR: X3 Mask */ + +#define CAPR_X2_Pos 2U /*!< CAPR: X2 Position */ +#define CAPR_X2_Msk (0x1UL << CAPR_X2_Pos) /*!< CAPR: X2 Mask */ + +#define CAPR_X1_Pos 1U /*!< CAPR: X1 Position */ +#define CAPR_X1_Msk (0x1UL << CAPR_X1_Pos) /*!< CAPR: X1 Mask */ + +#define CAPR_X0_Pos 0U /*!< CAPR: X0 Position */ +#define CAPR_X0_Msk (0x1UL << CAPR_X0_Pos) /*!< CAPR: X0 Mask */ + + /** + \brief 访问保护区控制寄存器(PACR, CR<20,0>)的联合体定义. + */ + typedef union { + struct { + uint32_t E: 1; /*!< bit: 0 保护区有效设置 */ + uint32_t Size: 5; /*!< bit: 1.. 5 保护区大小 */ + uint32_t _reserved0: 4; /*!< bit: 6.. 9 保留 */ + uint32_t base_addr: 22; /*!< bit: 10..31 保护区地址的高位 */ + } b; /*!< Structure 用来按位访问 */ + uint32_t w; /*!< Type 整个寄存器访问 */ + } PACR_Type; + + /* PACR Register Definitions */ +#define PACR_BASE_ADDR_Pos 10U /*!< PACR: base_addr Position */ +#define PACK_BASE_ADDR_Msk (0x3FFFFFUL << PACR_BASE_ADDR_Pos) /*!< PACR: base_addr Mask */ + +#define PACR_SIZE_Pos 1U /*!< PACR: Size Position */ +#define PACK_SIZE_Msk (0x1FUL << PACR_SIZE_Pos) /*!< PACR: Size Mask */ + +#define PACR_E_Pos 0U /*!< PACR: E Position */ +#define PACK_E_Msk (0x1UL << PACR_E_Pos) /*!< PACR: E Mask */ + + /** + \brief 访问保护区选择寄存器(PRSR,CR<21,0>)的联合体定义. + */ + typedef union { + struct { + uint32_t RID: 3; /*!< bit: 0.. 2 保护区索引值 */ + uint32_t _reserved0: 30; /*!< bit: 3..31 保留 */ + } b; /*!< Structure 用来按位访问 */ + uint32_t w; /*!< Type 整个寄存器访问 */ + } PRSR_Type; + + /* PRSR Register Definitions */ +#define PRSR_RID_Pos 0U /*!< PRSR: RID Position */ +#define PRSR_RID_Msk (0x7UL << PRSR_RID_Pos) /*!< PRSR: RID Mask */ + + /*@} end of group CSI_CORE */ + + + /** + \ingroup CSI_core_register + \defgroup CSI_NVIC Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + + /** + \brief 访问矢量中断控制器的结构体. + */ + typedef struct { + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) 中断使能设置寄存器 */ + uint32_t RESERVED0[15U]; + __IOM uint32_t IWER[1U]; /*!< Offset: 0x040 (R/W) 中断低功耗唤醒设置寄存器 */ + uint32_t RESERVED1[15U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) 中断使能清除寄存器 */ + uint32_t RESERVED2[15U]; + __IOM uint32_t IWDR[1U]; /*!< Offset: 0x0c0 (R/W) 中断低功耗唤醒清除寄存器 */ + uint32_t RESERVED3[15U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) 中断等待设置寄存器 */ + uint32_t RESERVED4[15U]; + __IOM uint32_t ISSR[1U]; /*!< Offset: 0x140 (R/W) 安全中断使能设置寄存器 */ + uint32_t RESERVED5[15U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) 中断等待清除寄存器 */ + uint32_t RESERVED6[31U]; + __IOM uint32_t IABR[1U]; /*!< Offset: 0x200 (R/W) 中断响应状态寄存器 */ + uint32_t RESERVED7[63U]; + __IOM uint32_t IPR[8U]; /*!< Offset: 0x300 (R/W) 中断优先级设置寄存器 */ + uint32_t RESERVED8[504U]; + __IM uint32_t ISR; /*!< Offset: 0xB00 (R/ ) 中断状态寄存器 */ + __IOM uint32_t IPTR; /*!< Offset: 0xB04 (R/W) 中断优先级阈值寄存器 */ + } NVIC_Type; + + /*@} end of group CSI_NVIC */ + + /** + \ingroup CSI_core_register + \defgroup CSI_SysTick System Tick Timer (CORET) + \brief Type definitions for the System Timer Registers. + @{ + */ + + /** + \brief 访问系统计时器的数据结构. + */ + typedef struct { + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) 控制状态寄存器 */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) 回填值寄存器 */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) 当前值寄存器 */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) 校准寄存器 */ + } CORET_Type; + + /* CORET Control / Status Register Definitions */ +#define CORET_CTRL_COUNTFLAG_Pos 16U /*!< CORET CTRL: COUNTFLAG Position */ +#define CORET_CTRL_COUNTFLAG_Msk (1UL << CORET_CTRL_COUNTFLAG_Pos) /*!< CORET CTRL: COUNTFLAG Mask */ + +#define CORET_CTRL_CLKSOURCE_Pos 2U /*!< CORET CTRL: CLKSOURCE Position */ +#define CORET_CTRL_CLKSOURCE_Msk (1UL << CORET_CTRL_CLKSOURCE_Pos) /*!< CORET CTRL: CLKSOURCE Mask */ + +#define CORET_CTRL_TICKINT_Pos 1U /*!< CORET CTRL: TICKINT Position */ +#define CORET_CTRL_TICKINT_Msk (1UL << CORET_CTRL_TICKINT_Pos) /*!< CORET CTRL: TICKINT Mask */ + +#define CORET_CTRL_ENABLE_Pos 0U /*!< CORET CTRL: ENABLE Position */ +#define CORET_CTRL_ENABLE_Msk (1UL /*<< CORET_CTRL_ENABLE_Pos*/) /*!< CORET CTRL: ENABLE Mask */ + + /* CORET Reload Register Definitions */ +#define CORET_LOAD_RELOAD_Pos 0U /*!< CORET LOAD: RELOAD Position */ +#define CORET_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< CORET_LOAD_RELOAD_Pos*/) /*!< CORET LOAD: RELOAD Mask */ + + /* CORET Current Register Definitions */ +#define CORET_VAL_CURRENT_Pos 0U /*!< CORET VAL: CURRENT Position */ +#define CORET_VAL_CURRENT_Msk (0xFFFFFFUL /*<< CORET_VAL_CURRENT_Pos*/) /*!< CORET VAL: CURRENT Mask */ + + /* CORET Calibration Register Definitions */ +#define CORET_CALIB_NOREF_Pos 31U /*!< CORET CALIB: NOREF Position */ +#define CORET_CALIB_NOREF_Msk (1UL << CORET_CALIB_NOREF_Pos) /*!< CORET CALIB: NOREF Mask */ + +#define CORET_CALIB_SKEW_Pos 30U /*!< CORET CALIB: SKEW Position */ +#define CORET_CALIB_SKEW_Msk (1UL << CORET_CALIB_SKEW_Pos) /*!< CORET CALIB: SKEW Mask */ + +#define CORET_CALIB_TENMS_Pos 0U /*!< CORET CALIB: TENMS Position */ +#define CORET_CALIB_TENMS_Msk (0xFFFFFFUL /*<< CORET_CALIB_TENMS_Pos*/) /*!< CORET CALIB: TENMS Mask */ + + /*@} end of group CSI_SysTick */ + + /** + \ingroup CSI_core_register + \defgroup CSI_DCC + \brief Type definitions for the DCC. + @{ + */ + + /** + \brief 访问DCC的数据结构. + */ + typedef struct { + uint32_t RESERVED0[13U]; + __IOM uint32_t HCR; /*!< Offset: 0x034 (R/W) */ + __IM uint32_t EHSR; /*!< Offset: 0x03C (R/ ) */ + uint32_t RESERVED1[6U]; + union { + __IM uint32_t DERJW; /*!< Offset: 0x058 (R/ ) 数据交换寄存器 CPU读*/ + __OM uint32_t DERJR; /*!< Offset: 0x058 ( /W) 数据交换寄存器 CPU写*/ + }; + + } DCC_Type; + +#define DCC_HCR_JW_Pos 18U /*!< DCC HCR: jw_int_en Position */ +#define DCC_HCR_JW_Msk (1UL << DCC_HCR_JW_Pos) /*!< DCC HCR: jw_int_en Mask */ + +#define DCC_HCR_JR_Pos 19U /*!< DCC HCR: jr_int_en Position */ +#define DCC_HCR_JR_Msk (1UL << DCC_HCR_JR_Pos) /*!< DCC HCR: jr_int_en Mask */ + +#define DCC_EHSR_JW_Pos 1U /*!< DCC EHSR: jw_vld Position */ +#define DCC_EHSR_JW_Msk (1UL << DCC_EHSR_JW_Pos) /*!< DCC EHSR: jw_vld Mask */ + +#define DCC_EHSR_JR_Pos 2U /*!< DCC EHSR: jr_vld Position */ +#define DCC_EHSR_JR_Msk (1UL << DCC_EHSR_JR_Pos) /*!< DCC EHSR: jr_vld Mask */ + + /*@} end of group CSI_DCC */ + + + /** + \ingroup CSI_core_register + \defgroup CSI_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + + /** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. + */ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + + /** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. + */ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + + /*@} end of group CSI_core_bitfield */ + + /** + \ingroup CSI_core_register + \defgroup CSI_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + + /* Memory mapping of CK802 Hardware */ +#define TCIP_BASE (0xE000E000UL) /*!< Titly Coupled IP Base Address */ +#define CORET_BASE (TCIP_BASE + 0x0010UL) /*!< CORET Base Address */ +#define NVIC_BASE (TCIP_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define DCC_BASE (0xE0011000UL) /*!< DCC Base Address */ + +#define CORET ((CORET_Type *) CORET_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define DCC ((DCC_Type *) DCC_BASE ) /*!< DCC configuration struct */ + + /*@} */ + +/** + \brief Set Wake up Interrupt + \details Sets the wake up bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +void drv_nvic_set_wakeup_irq(int32_t IRQn); +void drv_nvic_clear_wakeup_irq(int32_t IRQn); + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CK802_H_DEPENDANT */ + +#endif /* __CSI_GENERIC */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/csi.mk b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/csi.mk new file mode 100644 index 000000000..824cbc631 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/csi.mk @@ -0,0 +1,7 @@ +TEE_INC += \ + -I$(CSI_DIR)/csi_core/include \ + -I$(CSI_DIR)/csi_core/ck802 \ + -I$(CSI_DIR)/csi_core/include/csi-gcc + +TEE_SRC += \ + $(CSI_DIR)/csi_core/ck802/core_ck802.c \ No newline at end of file diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/csi_core_dummy.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/csi_core_dummy.c new file mode 100644 index 000000000..a08fac9bf --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/csi_core_dummy.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file csi_core_dummy.c + * @brief CSI Core Layer Source File + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#include "csi_core.h" + +#define _WEAK_ __attribute__((weak)) + +/* ################################## NVIC function ############################################ */ + + +_WEAK_ void drv_nvic_init(uint32_t prio_bits) +{ + return; +} +_WEAK_ void drv_nvic_enable_irq(int32_t irq_num) +{ + return; +} +_WEAK_ void drv_nvic_disable_irq(int32_t irq_num) +{ + return; +} + +_WEAK_ uint32_t drv_nvic_get_pending_irq(int32_t irq_num) +{ + return 0; +} +_WEAK_ void drv_nvic_set_pending_irq(int32_t irq_num) +{ + return; +} +_WEAK_ void drv_nvic_clear_pending_irq(int32_t irq_num) +{ + return; +} +_WEAK_ uint32_t drv_nvic_get_active(int32_t irq_num) +{ + return 0; +} + +_WEAK_ void drv_nvic_set_prio(int32_t irq_num, uint32_t priority) +{ + return; +} +_WEAK_ uint32_t drv_nvic_get_prio(int32_t irq_num) +{ + return 0; +} +/* ########################## Cache functions #################################### */ + +_WEAK_ void drv_icache_enable(void) +{ + return; +} +_WEAK_ void drv_icache_disable(void) +{ + return; +} +_WEAK_ void drv_icache_invalid(void) +{ + return; +} +_WEAK_ void drv_dcache_enable(void) +{ + return; +} +_WEAK_ void drv_dcache_disable(void) +{ + return; +} +_WEAK_ void drv_dcache_invalid(void) +{ + return; +} +_WEAK_ void drv_dcache_clean(void) +{ + return; +} +_WEAK_ void drv_dcache_clean_invalid(void) +{ + return; +} +_WEAK_ void drv_dcache_invalid_range(uint32_t *addr, int32_t dsize) +{ + return; +} +_WEAK_ void drv_dcache_clean_range(uint32_t *addr, int32_t dsize) +{ + return; +} +_WEAK_ void drv_dcache_clean_invalid_range(uint32_t *addr, int32_t dsize) +{ + return; +} +_WEAK_ void drv_cache_set_range(uint32_t index, uint32_t baseAddr, uint32_t size, uint32_t enable) +{ + return; +} +_WEAK_ void drv_cache_enable_profile(void) +{ + return; +} +_WEAK_ void drv_cache_disable_profile(void) +{ + return; +} +_WEAK_ void drv_cache_reset_profile(void) +{ + return; +} +_WEAK_ uint32_t drv_cache_get_access_time(void) +{ + return 0; +} +_WEAK_ uint32_t drv_cache_get_miss_time(void) +{ + return 0; +} +/* ################################## SysTick function ############################################ */ + +_WEAK_ uint32_t drv_coret_config(uint32_t ticks, int32_t irq_num) +{ + return 0; +} + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_gcc.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_gcc.h new file mode 100644 index 000000000..51d9bf694 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_gcc.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file csi_gcc.h + * @brief CSI Header File for GCC. + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_GCC_H_ +#define _CSI_GCC_H_ + +#define __ASM __asm /*!< asm keyword for GNU Compiler */ +#define __INLINE inline /*!< inline keyword for GNU Compiler */ +#define __ALWAYS_INLINE __attribute__((always_inline)) static inline + +#include +#include "csi_reg.h" +#include "csi_instr.h" +#include "csi_simd.h" + +#endif /* _CSI_GCC_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_instr.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_instr.h new file mode 100644 index 000000000..f765c2910 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_instr.h @@ -0,0 +1,436 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file csi_instr.h + * @brief CSI Header File for instruct. + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_INSTR_H_ +#define _CSI_INSTR_H_ + + +#define __CSI_GCC_OUT_REG(r) "=r" (r) +#define __CSI_GCC_USE_REG(r) "r" (r) + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__ALWAYS_INLINE void __NOP(void) +{ + __ASM volatile("nop"); +} + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +__ALWAYS_INLINE void __WFI(void) +{ + __ASM volatile("wait"); +} + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_INLINE void __WAIT(void) +{ + __ASM volatile("wait"); +} + +/** + \brief Doze For Interrupt + \details Doze For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_INLINE void __DOZE(void) +{ + __ASM volatile("doze"); +} + +/** + \brief Stop For Interrupt + \details Stop For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_INLINE void __STOP(void) +{ + __ASM volatile("stop"); +} + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__ALWAYS_INLINE void __ISB(void) +{ + __ASM volatile("sync"::: "memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__ALWAYS_INLINE void __DSB(void) +{ + __ASM volatile("sync"::: "memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__ALWAYS_INLINE void __DMB(void) +{ + __ASM volatile("sync"::: "memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_INLINE uint32_t __REV(uint32_t value) +{ + return __builtin_bswap32(value); +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; +#if (__CK80X >= 2) + __ASM volatile("revh %0, %1" : __CSI_GCC_OUT_REG(result) : __CSI_GCC_USE_REG(value)); +#else + result = ((value & 0xFF000000) >> 8) | ((value & 0x00FF0000) << 8) | + ((value & 0x0000FF00) >> 8) | ((value & 0x000000FF) << 8); +#endif + return (result); +} + + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_INLINE int32_t __REVSH(int32_t value) +{ + return (short)(((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8)); +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__ALWAYS_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + */ +__ALWAYS_INLINE void __BKPT() +{ + __ASM volatile("bkpt"); +} + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if (__CK80X >= 0x03U) + __ASM volatile("brev %0, %1" : "=r"(result) : "r"(value)); +#else + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + + for (value >>= 1U; value; value >>= 1U) { + result <<= 1U; + result |= value & 1U; + s--; + } + + result <<= s; /* shift when v's highest bits are zero */ +#endif + return (result); +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz +/** + \details This function saturates a signed value. + \param [in] x Value to be saturated + \param [in] y Bit position to saturate to [1..32] + \return Saturated value. + */ +__ALWAYS_INLINE int32_t __SSAT(int32_t x, uint32_t y) +{ + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + + for (i = 0; i < (y - 1); i++) { + posMax = posMax * 2; + } + + if (x > 0) { + posMax = (posMax - 1); + + if (x > posMax) { + x = posMax; + } + +// x &= (posMax * 2 + 1); + } else { + negMin = -posMax; + + if (x < negMin) { + x = negMin; + } + +// x &= (posMax * 2 - 1); + } + + return (x); +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__ALWAYS_INLINE uint32_t __USAT(uint32_t value, uint32_t sat) +{ + uint32_t result; + + if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + result = 0xFFFFFFFF >> (32 - sat); + } else { + result = value; + } + + return (result); +} + +/** + \brief Unsigned Saturate for internal use + \details Saturates an unsigned value, should not call directly. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__ALWAYS_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat) +{ + uint32_t result; + + if (value & 0x80000000) { /* only overflow set bit-31 */ + result = 0; + } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + result = 0xFFFFFFFF >> (32 - sat); + } else { + result = value; + } + + return (result); +} + +/** + \brief Rotate Right with Extend + \details This function moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \note carry input will always 0. + \param [in] op1 Value to rotate + \return Rotated value + */ +__ALWAYS_INLINE uint32_t __RRX(uint32_t op1) +{ +#if (__CK80X >= 2) + uint32_t res = 0; + __ASM volatile("bgeni t0, 31\n\t" + "lsri %0, 1\n\t" + "movt %1, t0\n\t" + "or %1, %1, %0\n\t" + : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "t0"); + return res; +#else + uint32_t res = 0; + __ASM volatile("movi r7, 0\n\t" + "bseti r7, 31\n\t" + "lsri %0, 1\n\t" + "bf 1f\n\t" + "mov %1, r7\n\t" + "1:\n\t" + "or %1, %1, %0\n\t" + : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "r7"); + return res; +#endif +} + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] addr Pointer to location + \return value of type uint8_t at (*ptr) + */ +__ALWAYS_INLINE uint8_t __LDRBT(volatile uint8_t *addr) +{ + uint32_t result; +//#warning "__LDRBT" + __ASM volatile("ldb %0, (%1, 0)" : "=r"(result) : "r"(addr)); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] addr Pointer to location + \return value of type uint16_t at (*ptr) + */ +__ALWAYS_INLINE uint16_t __LDRHT(volatile uint16_t *addr) +{ + uint32_t result; + +//#warning "__LDRHT" + __ASM volatile("ldh %0, (%1, 0)" : "=r"(result) : "r"(addr)); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] addr Pointer to location + \return value of type uint32_t at (*ptr) + */ +__ALWAYS_INLINE uint32_t __LDRT(volatile uint32_t *addr) +{ + uint32_t result; + +//#warning "__LDRT" + __ASM volatile("ldw %0, (%1, 0)" : "=r"(result) : "r"(addr)); + return (result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) +{ +//#warning "__STRBT" + __ASM volatile("stb %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory"); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) +{ +//#warning "__STRHT" + __ASM volatile("sth %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory"); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) +{ +//#warning "__STRT" + __ASM volatile("stw %1, (%0, 0)" :: "r"(addr), "r"(value) : "memory"); +} + +/*@}*/ /* end of group CSI_Core_InstructionInterface */ + + +/* ########################## FPU functions #################################### */ + +/** + \brief get FPU type + \details returns the FPU type, always 0. + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__ALWAYS_INLINE uint32_t __get_FPUType(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr13" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<13, 0>" : "=r"(result)); +#endif + return 0; +} + + +#endif /* _CSI_INSTR_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_reg.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_reg.h new file mode 100644 index 000000000..458a0f652 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_reg.h @@ -0,0 +1,418 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file csi_reg.h + * @brief CSI Header File for reg. + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_REG_H_ +#define _CSI_REG_H_ + +#include + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by setting the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_INLINE void __enable_irq(void) +{ + __ASM volatile("psrset ie"); +} + + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by clearing the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_INLINE void __disable_irq(void) +{ + __ASM volatile("psrclr ie"); +} + +/** + \brief Get PSR + \details Returns the content of the PSR Register. + \return PSR Register value + */ +__ALWAYS_INLINE uint32_t __get_PSR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, psr" : "=r"(result)); + return (result); +} + +/** + \brief Set PSR + \details Writes the given value to the PSR Register. + \param [in] psr PSR Register value to set + */ +__ALWAYS_INLINE void __set_PSR(uint32_t psr) +{ + __ASM volatile("mtcr %0, psr" : : "r"(psr)); +} + +/** + \brief Get SP + \details Returns the content of the SP Register. + \return SP Register value + */ +__ALWAYS_INLINE uint32_t __get_SP(void) +{ + uint32_t result; + + __ASM volatile("mov %0, sp" : "=r"(result)); + return (result); +} + +/** + \brief Set SP + \details Writes the given value to the SP Register. + \param [in] sp SP Register value to set + */ +__ALWAYS_INLINE void __set_SP(uint32_t sp) +{ + __ASM volatile("mov sp, %0" : : "r"(sp): "sp"); +} + + +/** + \brief Get VBR Register + \details Returns the content of the VBR Register. + \return VBR Register value + */ +__ALWAYS_INLINE uint32_t __get_VBR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, vbr" : "=r"(result)); + return (result); +} + +/** + \brief Set VBR + \details Writes the given value to the VBR Register. + \param [in] vbr VBR Register value to set + */ +__ALWAYS_INLINE void __set_VBR(uint32_t vbr) +{ + __ASM volatile("mtcr %0, vbr" : : "r"(vbr)); +} + +/** + \brief Get EPC Register + \details Returns the content of the EPC Register. + \return EPC Register value + */ +__ALWAYS_INLINE uint32_t __get_EPC(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, epc" : "=r"(result)); + return (result); +} + +/** + \brief Set EPC + \details Writes the given value to the EPC Register. + \param [in] epc EPC Register value to set + */ +__ALWAYS_INLINE void __set_EPC(uint32_t epc) +{ + __ASM volatile("mtcr %0, epc" : : "r"(epc)); +} + +/** + \brief Get EPSR + \details Returns the content of the EPSR Register. + \return EPSR Register value + */ +__ALWAYS_INLINE uint32_t __get_EPSR(void) +{ + uint32_t result; + + __ASM volatile("mfcr %0, epsr" : "=r"(result)); + return (result); +} + +/** + \brief Set EPSR + \details Writes the given value to the EPSR Register. + \param [in] epsr EPSR Register value to set + */ +__ALWAYS_INLINE void __set_EPSR(uint32_t epsr) +{ + __ASM volatile("mtcr %0, epsr" : : "r"(epsr)); +} + +/** + \brief Get CPUID Register + \details Returns the content of the CPUID Register. + \return CPUID Register value + */ +__ALWAYS_INLINE uint32_t __get_CPUID(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr13" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<13, 0>" : "=r"(result)); +#endif + return (result); +} + +#if (__SOFTRESET_PRESENT == 1U) +/** + \brief Set SRCR + \details Assigns the given value to the SRCR. + \param [in] srcr SRCR value to set + */ +__ALWAYS_INLINE void __set_SRCR(uint32_t srcr) +{ + __ASM volatile("mtcr %0, cr<31, 0>\n" : : "r"(srcr)); +} +#endif /* __SOFTRESET_PRESENT == 1U */ + +#if (__MGU_PRESENT == 1U) +/** + \brief Get CCR + \details Returns the current value of the CCR. + \return CCR Register value + */ +__ALWAYS_INLINE uint32_t __get_CCR(void) +{ + register uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr18\n" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<18, 0>\n" : "=r"(result)); +#endif + return (result); +} + + +/** + \brief Set CCR + \details Assigns the given value to the CCR. + \param [in] ccr CCR value to set + */ +__ALWAYS_INLINE void __set_CCR(uint32_t ccr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr18\n" : : "r"(ccr)); +#else + __ASM volatile("mtcr %0, cr<18, 0>\n" : : "r"(ccr)); +#endif +} + + +/** + \brief Get CAPR + \details Returns the current value of the CAPR. + \return CAPR Register value + */ +__ALWAYS_INLINE uint32_t __get_CAPR(void) +{ + register uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr19\n" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<19, 0>\n" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set CAPR + \details Assigns the given value to the CAPR. + \param [in] capr CAPR value to set + */ +__ALWAYS_INLINE void __set_CAPR(uint32_t capr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr19\n" : : "r"(capr)); +#else + __ASM volatile("mtcr %0, cr<19, 0>\n" : : "r"(capr)); +#endif +} + + +/** + \brief Set PACR + \details Assigns the given value to the PACR. + + \param [in] pacr PACR value to set + */ +__ALWAYS_INLINE void __set_PACR(uint32_t pacr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr20\n" : : "r"(pacr)); +#else + __ASM volatile("mtcr %0, cr<20, 0>\n" : : "r"(pacr)); +#endif +} + + +/** + \brief Get PACR + \details Returns the current value of PACR. + \return PACR value + */ +__ALWAYS_INLINE uint32_t __get_PACR(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr20" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<20, 0>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set PRSR + \details Assigns the given value to the PRSR. + + \param [in] prsr PRSR value to set + */ +__ALWAYS_INLINE void __set_PRSR(uint32_t prsr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr21\n" : : "r"(prsr)); +#else + __ASM volatile("mtcr %0, cr<21, 0>\n" : : "r"(prsr)); +#endif +} + +/** + \brief Get PRSR + \details Returns the current value of PRSR. + \return PRSR value + */ +__ALWAYS_INLINE uint32_t __get_PRSR(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr21" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<21, 0>" : "=r"(result)); +#endif + return (result); +} +#endif /* __MGU_PRESENT == 1U */ + +/** + \brief Get user sp + \details Returns the current value of user r14. + \return UR14 value + */ +__ALWAYS_INLINE uint32_t __get_UR14(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mov %0, sp" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<14, 1>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Enable interrupts and exceptions + \details Enables interrupts and exceptions by setting the IE-bit and EE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_INLINE void __enable_excp_irq(void) +{ + __ASM volatile("psrset ee, ie"); +} + + +/** + \brief Disable interrupts and exceptions + \details Disables interrupts and exceptions by clearing the IE-bit and EE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_INLINE void __disable_excp_irq(void) +{ + __ASM volatile("psrclr ee, ie"); +} + +#if (__GSR_GCR_PRESENT == 1U) +/** + \brief Get GSR + \details Returns the content of the GSR Register. + \return GSR Register value + */ +__ALWAYS_INLINE uint32_t __get_GSR(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr12" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<12, 0>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Get GCR + \details Returns the content of the GCR Register. + \return GCR Register value + */ +__ALWAYS_INLINE uint32_t __get_GCR(void) +{ + uint32_t result; + +#ifdef __CK610 + __ASM volatile("mfcr %0, cr11" : "=r"(result)); +#else + __ASM volatile("mfcr %0, cr<11, 0>" : "=r"(result)); +#endif + return (result); +} + +/** + \brief Set GCR + \details Writes the given value to the GCR Register. + \param [in] gcr GCR Register value to set + */ +__ALWAYS_INLINE void __set_GCR(uint32_t gcr) +{ +#ifdef __CK610 + __ASM volatile("mtcr %0, cr11" : : "r"(gcr)); +#else + __ASM volatile("mtcr %0, cr<11, 0>" : : "r"(gcr)); +#endif +} + +#endif /* (__GSR_GCR_PRESENT == 1U) */ + + +#endif /* _CSI_REG_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_simd.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_simd.h new file mode 100644 index 000000000..f9dc5b205 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi-gcc/csi_simd.h @@ -0,0 +1,1472 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file csi_simd.h + * @brief CSI Single Instruction Multiple Data (SIMD) Header File for GCC. + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_SIMD_H_ +#define _CSI_SIMD_H_ + + +/** + \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16] + of val2 levitated with the val3. + \details Combine a halfword from one register with a halfword from another register. + The second argument can be left-shifted before extraction of the halfword. + \param [in] val1 first 16-bit operands + \param [in] val2 second 16-bit operands + \param [in] val3 value for left-shifting val2. Value range [0..31]. + \return the combination of halfwords. + \remark + res[15:0] = val1[15:0] \n + res[31:16] = val2[31:16] << val3 + */ +__ALWAYS_INLINE uint32_t __PKHBT(uint32_t val1, uint32_t val2, uint32_t val3) +{ + return ((((int32_t)(val1) << 0) & (int32_t)0x0000FFFF) | (((int32_t)(val2) << val3) & (int32_t)0xFFFF0000)); +} + +/** + \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0] + of val2 right-shifted with the val3. + \details Combine a halfword from one register with a halfword from another register. + The second argument can be right-shifted before extraction of the halfword. + \param [in] val1 first 16-bit operands + \param [in] val2 second 16-bit operands + \param [in] val3 value for right-shifting val2. Value range [1..32]. + \return the combination of halfwords. + \remark + res[15:0] = val2[15:0] >> val3 \n + res[31:16] = val1[31:16] + */ +__ALWAYS_INLINE uint32_t __PKHTB(uint32_t val1, uint32_t val2, uint32_t val3) +{ + return ((((int32_t)(val1) << 0) & (int32_t)0xFFFF0000) | (((int32_t)(val2) >> val3) & (int32_t)0x0000FFFF)); +} + +/** + \brief Dual 16-bit signed saturate. + \details This function saturates a signed value. + \param [in] x two signed 16-bit values to be saturated. + \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16. + \return the sum of the absolute differences of the following bytes, added to the accumulation value:\n + the signed saturation of the low halfword in val1, saturated to the bit position specified in + val2 and returned in the low halfword of the return value.\n + the signed saturation of the high halfword in val1, saturated to the bit position specified in + val2 and returned in the high halfword of the return value. + */ +__ALWAYS_INLINE uint32_t __SSAT16(int32_t x, const uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __SSAT((((int32_t)x << 16) >> 16), y) & (int32_t)0x0000FFFF; + s = __SSAT((((int32_t)x) >> 16), y) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturate. + \details This function enables you to saturate two signed 16-bit values to a selected unsigned range. + \param [in] x two signed 16-bit values to be saturated. + \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16. + \return the saturation of the two signed 16-bit values, as non-negative values: + the saturation of the low halfword in val1, saturated to the bit position specified in + val2 and returned in the low halfword of the return value.\n + the saturation of the high halfword in val1, saturated to the bit position specified in + val2 and returned in the high halfword of the return value. + */ +__ALWAYS_INLINE uint32_t __USAT16(uint32_t x, const uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __IUSAT(((x << 16) >> 16), y) & 0x0000FFFF; + s = __IUSAT(((x) >> 16), y) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit saturating addition. + \details This function enables you to perform four 8-bit integer additions, + saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the saturated addition of the first byte of each operand in the first byte of the return value.\n + the saturated addition of the second byte of each operand in the second byte of the return value.\n + the saturated addition of the third byte of each operand in the third byte of the return value.\n + the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_INLINE uint32_t __QADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __SSAT(((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((int32_t)x) >> 24) + (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned saturating addition. + \details This function enables you to perform four unsigned 8-bit integer additions, + saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the saturated addition of the first byte of each operand in the first byte of the return value.\n + the saturated addition of the second byte of each operand in the second byte of the return value.\n + the saturated addition of the third byte of each operand in the third byte of the return value.\n + the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range 0 <= x <= 2^8 - 1. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_INLINE uint32_t __UQADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __IUSAT((((x << 24) >> 24) + ((y << 24) >> 24)), 8) & 0x000000FF; + s = __IUSAT((((x << 16) >> 24) + ((y << 16) >> 24)), 8) & 0x000000FF; + t = __IUSAT((((x << 8) >> 24) + ((y << 8) >> 24)), 8) & 0x000000FF; + u = __IUSAT((((x) >> 24) + ((y) >> 24)), 8) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit signed addition. + \details This function performs four 8-bit signed integer additions. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the addition of the first bytes from each operand, in the first byte of the return value.\n + the addition of the second bytes of each operand, in the second byte of the return value.\n + the addition of the third bytes of each operand, in the third byte of the return value.\n + the addition of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_INLINE uint32_t __SADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF; + s = ((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF; + t = ((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF; + u = ((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned addition. + \details This function performs four unsigned 8-bit integer additions. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the addition of the first bytes from each operand, in the first byte of the return value.\n + the addition of the second bytes of each operand, in the second byte of the return value.\n + the addition of the third bytes of each operand, in the third byte of the return value.\n + the addition of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_INLINE uint32_t __UADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) + ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) + ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) + ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) + ((y) >> 24)) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit saturating subtract. + \details This function enables you to perform four 8-bit integer subtractions, + saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the subtraction of the first byte of each operand in the first byte of the return value.\n + the subtraction of the second byte of each operand in the second byte of the return value.\n + the subtraction of the third byte of each operand in the third byte of the return value.\n + the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_INLINE uint32_t __QSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __SSAT(((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((int32_t)x) >> 24) - (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned saturating subtraction. + \details This function enables you to perform four unsigned 8-bit integer subtractions, + saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the subtraction of the first byte of each operand in the first byte of the return value.\n + the subtraction of the second byte of each operand in the second byte of the return value.\n + the subtraction of the third byte of each operand in the third byte of the return value.\n + the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit unsigned integer range 0 <= x <= 2^8 - 1. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_INLINE uint32_t __UQSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __IUSAT((((x << 24) >> 24) - ((y << 24) >> 24)), 8) & 0x000000FF; + s = __IUSAT((((x << 16) >> 24) - ((y << 16) >> 24)), 8) & 0x000000FF; + t = __IUSAT((((x << 8) >> 24) - ((y << 8) >> 24)), 8) & 0x000000FF; + u = __IUSAT((((x) >> 24) - ((y) >> 24)), 8) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit signed subtraction. + \details This function enables you to perform four 8-bit signed integer subtractions. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_INLINE uint32_t __SSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF; + s = ((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF; + t = ((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF; + u = ((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned subtract. + \details This function enables you to perform four 8-bit unsigned integer subtractions. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_INLINE uint32_t __USUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Unsigned sum of quad 8-bit unsigned absolute difference. + \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values + of the differences together, returning the result as a single unsigned integer. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.\n + The sum is returned as a single unsigned integer. + \remark + absdiff1 = val1[7:0] - val2[7:0] \n + absdiff2 = val1[15:8] - val2[15:8] \n + absdiff3 = val1[23:16] - val2[23:16] \n + absdiff4 = val1[31:24] - val2[31:24] \n + res[31:0] = absdiff1 + absdiff2 + absdiff3 + absdiff4 + */ +__ALWAYS_INLINE uint32_t __USAD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF; + + return (u + t + s + r); +} + +/** + \brief Unsigned sum of quad 8-bit unsigned absolute difference with 32-bit accumulate. + \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values + of the differences to a 32-bit accumulate operand. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \param [in] sum accumulation value. + \return the sum of the absolute differences of the following bytes, added to the accumulation value: + the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + absdiff1 = val1[7:0] - val2[7:0] \n + absdiff2 = val1[15:8] - val2[15:8] \n + absdiff3 = val1[23:16] - val2[23:16] \n + absdiff4 = val1[31:24] - val2[31:24] \n + sum = absdiff1 + absdiff2 + absdiff3 + absdiff4 \n + res[31:0] = sum[31:0] + val3[31:0] + */ +__ALWAYS_INLINE uint32_t __USADA8(uint32_t x, uint32_t y, uint32_t sum) +{ + int32_t r, s, t, u; + + r = (abs(((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF; + s = (abs(((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF; + t = (abs(((x << 8) >> 24) - ((y << 8) >> 24))) & 0x000000FF; + u = (abs(((x) >> 24) - ((y) >> 24))) & 0x000000FF; + + return (u + t + s + r + sum); +} + +/** + \brief Dual 16-bit saturating addition. + \details This function enables you to perform two 16-bit integer arithmetic additions in parallel, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated addition of the low halfwords, in the low halfword of the return value.\n + the saturated addition of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_INLINE uint32_t __QADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating addition. + \details This function enables you to perform two unsigned 16-bit integer additions, saturating + the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated addition of the low halfwords, in the low halfword of the return value.\n + the saturated addition of the high halfwords, in the high halfword of the return value.\n + The results are saturated to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_INLINE uint32_t __UQADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __IUSAT((((x << 16) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed addition. + \details This function enables you to perform two 16-bit signed integer additions. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the addition of the low halfwords in the low halfword of the return value.\n + the addition of the high halfwords in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_INLINE uint32_t __SADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = ((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition + \details This function enables you to perform two 16-bit unsigned integer additions. + \param [in] x first two 16-bit summands for each addition. + \param [in] y second two 16-bit summands for each addition. + \return the addition of the low halfwords in the low halfword of the return value.\n + the addition of the high halfwords in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_INLINE uint32_t __UADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = (((x << 16) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) + ((y) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + + +/** + \brief Dual 16-bit signed addition with halved results. + \details This function enables you to perform two signed 16-bit integer additions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved addition of the low halfwords, in the low halfword of the return value.\n + the halved addition of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] + val2[31:16]) >> 1 + */ +__ALWAYS_INLINE uint32_t __SHADD16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition with halved results. + \details This function enables you to perform two unsigned 16-bit integer additions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved addition of the low halfwords, in the low halfword of the return value.\n + the halved addition of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] + val2[31:16]) >> 1 + */ +__ALWAYS_INLINE uint32_t __UHADD16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit signed addition with halved results. + \details This function enables you to perform four signed 8-bit integer additions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n + the halved addition of the second bytes from each operand, in the second byte of the return value.\n + the halved addition of the third bytes from each operand, in the third byte of the return value.\n + the halved addition of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] + val2[31:24]) >> 1 + */ +__ALWAYS_INLINE uint32_t __SHADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF; + s = (((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF; + t = (((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF; + u = (((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned addition with halved results. + \details This function enables you to perform four unsigned 8-bit integer additions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n + the halved addition of the second bytes from each operand, in the second byte of the return value.\n + the halved addition of the third bytes from each operand, in the third byte of the return value.\n + the halved addition of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] + val2[31:24]) >> 1 + */ +__ALWAYS_INLINE uint32_t __UHADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((x << 24) >> 24) + ((y << 24) >> 24)) >> 1) & 0x000000FF; + s = ((((x << 16) >> 24) + ((y << 16) >> 24)) >> 1) & 0x000000FF; + t = ((((x << 8) >> 24) + ((y << 8) >> 24)) >> 1) & 0x000000FF; + u = ((((x) >> 24) + ((y) >> 24)) >> 1) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Dual 16-bit saturating subtract. + \details This function enables you to perform two 16-bit integer subtractions in parallel, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n + the saturated subtraction of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_INLINE uint32_t __QSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating subtraction. + \details This function enables you to perform two unsigned 16-bit integer subtractions, + saturating the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \param [in] x first two 16-bit operands for each subtraction. + \param [in] y second two 16-bit operands for each subtraction. + \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n + the saturated subtraction of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_INLINE uint32_t __UQSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction. + \details This function enables you to perform two 16-bit signed integer subtractions. + \param [in] x first two 16-bit operands of each subtraction. + \param [in] y second two 16-bit operands of each subtraction. + \return the subtraction of the low halfword in the second operand from the low + halfword in the first operand, in the low halfword of the return value. \n + the subtraction of the high halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_INLINE uint32_t __SSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtract. + \details This function enables you to perform two 16-bit unsigned integer subtractions. + \param [in] x first two 16-bit operands of each subtraction. + \param [in] y second two 16-bit operands of each subtraction. + \return the subtraction of the low halfword in the second operand from the low + halfword in the first operand, in the low halfword of the return value. \n + the subtraction of the high halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_INLINE uint32_t __USUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) - ((y) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction with halved results. + \details This function enables you to perform two signed 16-bit integer subtractions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n + the halved subtraction of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] - val2[31:16]) >> 1 + */ +__ALWAYS_INLINE uint32_t __SHSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtraction with halved results. + \details This function enables you to perform two unsigned 16-bit integer subtractions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n + the halved subtraction of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] - val2[31:16]) >> 1 + */ +__ALWAYS_INLINE uint32_t __UHSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit signed addition with halved results. + \details This function enables you to perform four signed 8-bit integer subtractions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n + the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n + the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n + the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] - val2[31:24]) >> 1 + */ +__ALWAYS_INLINE uint32_t __SHSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF; + s = (((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF; + t = (((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF; + u = (((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned subtraction with halved results. + \details This function enables you to perform four unsigned 8-bit integer subtractions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n + the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n + the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n + the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] - val2[31:24]) >> 1 + */ +__ALWAYS_INLINE uint32_t __UHSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((x << 24) >> 24) - ((y << 24) >> 24)) >> 1) & 0x000000FF; + s = ((((x << 16) >> 24) - ((y << 16) >> 24)) >> 1) & 0x000000FF; + t = ((((x << 8) >> 24) - ((y << 8) >> 24)) >> 1) & 0x000000FF; + u = ((((x) >> 24) - ((y) >> 24)) >> 1) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Dual 16-bit add and subtract with exchange. + \details This function enables you to exchange the halfwords of the one operand, + then add the high halfwords and subtract the low halfwords, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the saturated subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the saturated addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_INLINE uint32_t __QASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating addition and subtraction with exchange. + \details This function enables you to exchange the halfwords of the second operand and + perform one unsigned 16-bit integer addition and one unsigned 16-bit subtraction, + saturating the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the saturated subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the saturated addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_INLINE uint32_t __UQASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit addition and subtraction with exchange. + \details It enables you to exchange the halfwords of the second operand, add the high halfwords + and subtract the low halfwords. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_INLINE uint32_t __SASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition and subtraction with exchange. + \details This function enables you to exchange the two halfwords of the second operand, + add the high halfwords and subtract the low halfwords. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_INLINE uint32_t __UASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) - ((y) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed addition and subtraction with halved results. + \details This function enables you to exchange the two halfwords of one operand, perform one + signed 16-bit integer addition and one signed 16-bit subtraction, and halve the results. + \param [in] x first 16-bit operands. + \param [in] y second 16-bit operands. + \return the halved subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the halved addition of the low halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] + val2[15:0]) >> 1 + */ +__ALWAYS_INLINE uint32_t __SHASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition and subtraction with halved results and exchange. + \details This function enables you to exchange the halfwords of the second operand, + add the high halfwords and subtract the low halfwords, halving the results. + \param [in] x first operand for the subtraction in the low halfword, and + the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, and + the second operand for the addition in the low halfword. + \return the halved subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the halved addition of the low halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] + val2[15:0]) >> 1 + */ +__ALWAYS_INLINE uint32_t __UHASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit subtract and add with exchange. + \details This function enables you to exchange the halfwords of one operand, + then subtract the high halfwords and add the low halfwords, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the saturated addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the saturated subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_INLINE uint32_t __QSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating subtraction and addition with exchange. + \details This function enables you to exchange the halfwords of the second operand and perform + one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, saturating + the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the saturated addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the saturated subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_INLINE uint32_t __UQSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit unsigned subtract and add with exchange. + \details This function enables you to exchange the halfwords of the second operand, + subtract the high halfwords and add the low halfwords. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_INLINE uint32_t __USAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) + ((y) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction and addition with exchange. + \details This function enables you to exchange the two halfwords of one operand and perform one + 16-bit integer subtraction and one 16-bit addition. + \param [in] x first operand for the addition in the low halfword, and the first operand + for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, and the second + operand for the subtraction in the low halfword. + \return the addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_INLINE uint32_t __SSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + + +/** + \brief Dual 16-bit signed subtraction and addition with halved results. + \details This function enables you to exchange the two halfwords of one operand, perform one signed + 16-bit integer subtraction and one signed 16-bit addition, and halve the results. + \param [in] x first 16-bit operands. + \param [in] y second 16-bit operands. + \return the halved addition of the low halfword in the first operand and the + high halfword in the second operand, in the low halfword of the return value.\n + the halved subtraction of the low halfword in the second operand from the + high halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] - val2[15:0]) >> 1 + */ +__ALWAYS_INLINE uint32_t __SHSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtraction and addition with halved results and exchange. + \details This function enables you to exchange the halfwords of the second operand, + subtract the high halfwords and add the low halfwords, halving the results. + \param [in] x first operand for the addition in the low halfword, and + the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, and + the second operand for the subtraction in the low halfword. + \return the halved addition of the low halfword in the first operand and the + high halfword in the second operand, in the low halfword of the return value.\n + the halved subtraction of the low halfword in the second operand from the + high halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] - val2[15:0]) >> 1 + */ +__ALWAYS_INLINE uint32_t __UHSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed multiply with exchange returning difference. + \details This function enables you to perform two 16-bit signed multiplications, subtracting + one of the products from the other. The halfwords of the second operand are exchanged + before performing the arithmetic. This produces top * bottom and bottom * top multiplication. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the difference of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 - p2 + */ +__ALWAYS_INLINE uint32_t __SMUSDX(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)))); +} + +/** + \brief Sum of dual 16-bit signed multiply with exchange. + \details This function enables you to perform two 16-bit signed multiplications with exchanged + halfwords of the second operand, adding the products together. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the sum of the products of the two 16-bit signed multiplications with exchanged halfwords of the second operand. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 + p2 + */ +__ALWAYS_INLINE uint32_t __SMUADX(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)))); +} + + +/** + \brief Saturating add. + \details This function enables you to obtain the saturating add of two integers. + \param [in] x first summand of the saturating add operation. + \param [in] y second summand of the saturating add operation. + \return the saturating addition of val1 and val2. + \remark + res[31:0] = SAT(val1 + SAT(val2)) + */ +__ALWAYS_INLINE int32_t __QADD(int32_t x, int32_t y) +{ + int32_t result; + + if (y >= 0) { + if (x + y >= x) { + result = x + y; + } else { + result = 0x7FFFFFFF; + } + } else { + if (x + y < x) { + result = x + y; + } else { + result = 0x80000000; + } + } + + return result; +} + +/** + \brief Saturating subtract. + \details This function enables you to obtain the saturating add of two integers. + \param [in] x first summand of the saturating add operation. + \param [in] y second summand of the saturating add operation. + \return the saturating addition of val1 and val2. + \remark + res[31:0] = SAT(val1 + SAT(val2)) + */ +__ALWAYS_INLINE int32_t __QSUB(int32_t x, int32_t y) +{ + int64_t tmp; + int32_t result; + + tmp = (int64_t)x - (int64_t)y; + + if (tmp > 0x7fffffff) { + tmp = 0x7fffffff; + } else if (tmp < (-2147483647 - 1)) { + tmp = -2147483647 - 1; + } + + result = tmp; + return result; +} + +/** + \brief Dual 16-bit signed multiply with single 32-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications, + adding both results to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value, as a 32-bit integer. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 + p2 + val3[31:0] + */ +__ALWAYS_INLINE uint32_t __SMLAD(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Pre-exchanged dual 16-bit signed multiply with single 32-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications with exchanged + halfwords of the second operand, adding both results to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication with exchanged halfwords of the second + operand added to the accumulate value, as a 32-bit integer. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 + p2 + val3[31:0] + */ +__ALWAYS_INLINE uint32_t __SMLADX(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. + \details This function enables you to perform two 16-bit signed multiplications, take the + difference of the products, subtracting the high halfword product from the low + halfword product, and add the difference to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 - p2 + val3[31:0] + */ +__ALWAYS_INLINE uint32_t __SMLSD(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. + \details This function enables you to exchange the halfwords in the second operand, then perform two 16-bit + signed multiplications. The difference of the products is added to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 - p2 + val3[31:0] + */ +__ALWAYS_INLINE uint32_t __SMLSDX(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with single 64-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications, adding both results + to a 64-bit accumulate operand. Overflow is only possible as a result of the 64-bit addition. + This overflow is not detected if it occurs. Instead, the result wraps around modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + sum = p1 + p2 + val3[63:32][31:0] \n + res[63:32] = sum[63:32] \n + res[31:0] = sum[31:0] + */ +__ALWAYS_INLINE uint64_t __SMLALD(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange with single 64-bit accumulator. + \details This function enables you to exchange the halfwords of the second operand, and perform two + signed 16-bit multiplications, adding both results to a 64-bit accumulate operand. Overflow + is only possible as a result of the 64-bit addition. This overflow is not detected if it occurs. + Instead, the result wraps around modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + sum = p1 + p2 + val3[63:32][31:0] \n + res[63:32] = sum[63:32] \n + res[31:0] = sum[31:0] + */ +__ALWAYS_INLINE uint64_t __SMLALDX(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief dual 16-bit signed multiply subtract with 64-bit accumulate. + \details This function It enables you to perform two 16-bit signed multiplications, take the difference + of the products, subtracting the high halfword product from the low halfword product, and add the + difference to a 64-bit accumulate operand. Overflow cannot occur during the multiplications or the + subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow is not + detected. Instead, the result wraps round to modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[63:0] = p1 - p2 + val3[63:0] + */ +__ALWAYS_INLINE uint64_t __SMLSLD(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 64-bit accumulate. + \details This function enables you to exchange the halfwords of the second operand, perform two 16-bit multiplications, + adding the difference of the products to a 64-bit accumulate operand. Overflow cannot occur during the + multiplications or the subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow + is not detected. Instead, the result wraps round to modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[63:0] = p1 - p2 + val3[63:0] + */ +__ALWAYS_INLINE uint64_t __SMLSLDX(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief 32-bit signed multiply with 32-bit truncated accumulator. + \details This function enables you to perform a signed 32-bit multiplications, adding the most + significant 32 bits of the 64-bit result to a 32-bit accumulate operand. + \param [in] x first operand for multiplication. + \param [in] y second operand for multiplication. + \param [in] sum accumulate value. + \return the product of multiplication (most significant 32 bits) is added to the accumulate value, as a 32-bit integer. + \remark + p = val1 * val2 \n + res[31:0] = p[61:32] + val3[31:0] + */ +__ALWAYS_INLINE uint32_t __SMMLA(int32_t x, int32_t y, int32_t sum) +{ + return (uint32_t)((int32_t)((int64_t)((int64_t)x * (int64_t)y) >> 32) + sum); +} + +/** + \brief Sum of dual 16-bit signed multiply. + \details This function enables you to perform two 16-bit signed multiplications, adding the products together. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the sum of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 + p2 + */ +__ALWAYS_INLINE uint32_t __SMUAD(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)))); +} + +/** + \brief Dual 16-bit signed multiply returning difference. + \details This function enables you to perform two 16-bit signed multiplications, taking the difference + of the products by subtracting the high halfword product from the low halfword product. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the difference of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 - p2 + */ +__ALWAYS_INLINE uint32_t __SMUSD(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)))); +} + +/** + \brief Dual extracted 8-bit to 16-bit signed addition. + \details This function enables you to extract two 8-bit values from the second operand (at bit positions + [7:0] and [23:16]), sign-extend them to 16-bits each, and add the results to the first operand. + \param [in] x values added to the sign-extended to 16-bit values. + \param [in] y two 8-bit values to be extracted and sign-extended. + \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and + val2[23:16] have been extracted and sign-extended prior to the addition. + \remark + res[15:0] = val1[15:0] + SignExtended(val2[7:0]) \n + res[31:16] = val1[31:16] + SignExtended(val2[23:16]) + */ +__ALWAYS_INLINE uint32_t __SXTAB16(uint32_t x, uint32_t y) +{ + return ((uint32_t)((((((int32_t)y << 24) >> 24) + (((int32_t)x << 16) >> 16)) & (int32_t)0x0000FFFF) | + (((((int32_t)y << 8) >> 8) + (((int32_t)x >> 16) << 16)) & (int32_t)0xFFFF0000))); +} + +/** + \brief Extracted 16-bit to 32-bit unsigned addition. + \details This function enables you to extract two 8-bit values from one operand, zero-extend + them to 16 bits each, and add the results to two 16-bit values from another operand. + \param [in] x values added to the zero-extended to 16-bit values. + \param [in] y two 8-bit values to be extracted and zero-extended. + \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and + val2[23:16] have been extracted and zero-extended prior to the addition. + \remark + res[15:0] = ZeroExt(val2[7:0] to 16 bits) + val1[15:0] \n + res[31:16] = ZeroExt(val2[31:16] to 16 bits) + val1[31:16] + */ +__ALWAYS_INLINE uint32_t __UXTAB16(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((y << 24) >> 24) + ((x << 16) >> 16)) & 0x0000FFFF) | + ((((y << 8) >> 8) + ((x >> 16) << 16)) & 0xFFFF0000))); +} + +/** + \brief Dual extract 8-bits and sign extend each to 16-bits. + \details This function enables you to extract two 8-bit values from an operand and sign-extend them to 16 bits each. + \param [in] x two 8-bit values in val[7:0] and val[23:16] to be sign-extended. + \return the 8-bit values sign-extended to 16-bit values.\n + sign-extended value of val[7:0] in the low halfword of the return value.\n + sign-extended value of val[23:16] in the high halfword of the return value. + \remark + res[15:0] = SignExtended(val[7:0]) \n + res[31:16] = SignExtended(val[23:16]) + */ +__ALWAYS_INLINE uint32_t __SXTB16(uint32_t x) +{ + return ((uint32_t)(((((int32_t)x << 24) >> 24) & (int32_t)0x0000FFFF) | + ((((int32_t)x << 8) >> 8) & (int32_t)0xFFFF0000))); +} + +/** + \brief Dual extract 8-bits and zero-extend to 16-bits. + \details This function enables you to extract two 8-bit values from an operand and zero-extend them to 16 bits each. + \param [in] x two 8-bit values in val[7:0] and val[23:16] to be zero-extended. + \return the 8-bit values sign-extended to 16-bit values.\n + sign-extended value of val[7:0] in the low halfword of the return value.\n + sign-extended value of val[23:16] in the high halfword of the return value. + \remark + res[15:0] = SignExtended(val[7:0]) \n + res[31:16] = SignExtended(val[23:16]) + */ +__ALWAYS_INLINE uint32_t __UXTB16(uint32_t x) +{ + return ((uint32_t)((((x << 24) >> 24) & 0x0000FFFF) | + (((x << 8) >> 8) & 0xFFFF0000))); +} + +#endif /* _CSI_SIMD_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi_core.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi_core.h new file mode 100644 index 000000000..bf84ab166 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_core/include/csi_core.h @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file csi_core.h + * @brief CSI Core Layer Header File + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CORE_H_ +#define _CORE_H_ + +#include +#include "csi_gcc.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ################################## NVIC function ############################################ */ + +/** + \brief initialize the NVIC interrupt controller + \param [in] prio_bits the priority bits of NVIC interrupt controller. + */ +void drv_nvic_init(uint32_t prio_bits); + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] irq_num External interrupt number. Value cannot be negative. + */ +void drv_nvic_enable_irq(int32_t irq_num); +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] irq_num External interrupt number. Value cannot be negative. + */ +void drv_nvic_disable_irq(int32_t irq_num); + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] irq_num Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +uint32_t drv_nvic_get_pending_irq(int32_t irq_num); + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] irq_num Interrupt number. Value cannot be negative. + */ +void drv_nvic_set_pending_irq(int32_t irq_num); + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] irq_num External interrupt number. Value cannot be negative. + */ +void drv_nvic_clear_pending_irq(int32_t irq_num); + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] irq_num Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note irq_num must not be negative. + */ +uint32_t drv_nvic_get_active(int32_t irq_num); + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] irq_num Interrupt number. + \param [in] priority Priority to set. +*/ +void drv_nvic_set_prio(int32_t irq_num, uint32_t priority); +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] irq_num Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +uint32_t drv_nvic_get_prio(int32_t irq_num); + +/*@} end of CSI_Core_NVICFunctions */ + + +/* ########################## Cache functions #################################### */ + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +void drv_icache_enable(void); + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +void drv_icache_disable(void); + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +void drv_icache_invalid(void); + +/** + \brief Enable D-Cache + \details Turns on D-Cache + \note I-Cache also turns on. + */ +void drv_dcache_enable(void); + +/** + \brief Disable D-Cache + \details Turns off D-Cache + \note I-Cache also turns off. + */ +void drv_dcache_disable(void); + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + \note I-Cache also invalid + */ +void drv_dcache_invalid(void); + +/** + \brief Clean D-Cache + \details Cleans D-Cache + \note I-Cache also cleans + */ +void drv_dcache_clean(void); + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + \note I-Cache also flush. + */ +void drv_dcache_clean_invalid(void); + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address + \param[in] addr address (aligned to 16-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +void drv_dcache_invalid_range(uint32_t *addr, int32_t dsize); + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + \param[in] addr address (aligned to 16-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +void drv_dcache_clean_range(uint32_t *addr, int32_t dsize); + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + \param[in] addr address (aligned to 16-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +void drv_dcache_clean_invalid_range(uint32_t *addr, int32_t dsize); + +/** + \brief setup cacheable range Cache + \details setup Cache range + */ +void drv_cache_set_range(uint32_t index, uint32_t baseAddr, uint32_t size, uint32_t enable); + +/** + \brief Enable cache profile + \details Turns on Cache profile + */ +void drv_cache_enable_profile(void); + +/** + \brief Disable cache profile + \details Turns off Cache profile + */ +void drv_cache_disable_profile(void); +/** + \brief Reset cache profile + \details Reset Cache profile + */ +void drv_cache_reset_profile(void); + +/** + \brief cache access times + \details Cache access times + \note every 256 access add 1. + */ +uint32_t drv_cache_get_access_time(void); + +/** + \brief cache miss times + \details Cache miss times + \note every 256 miss add 1. + */ +uint32_t drv_cache_get_miss_time(void); + +/* ################################## SysTick function ############################################ */ + +/** + \brief CORE timer Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \param [in] irq_num core timer Interrupt number. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +uint32_t drv_coret_config(uint32_t ticks, int32_t irq_num); + +/** + \brief get CORE timer reload value + \return CORE timer counter value. + */ +uint32_t drv_coret_get_load(void); + +/** + \brief get CORE timer counter value + \return CORE timer counter value. + */ +uint32_t drv_coret_get_value(void); + +/** + \brief Save the Irq context + \details save the psr result before disable irq. + \param [in] irq_num External interrupt number. Value cannot be negative. + */ +__ALWAYS_INLINE uint32_t drv_irq_save(void) +{ + uint32_t result; + result = __get_PSR(); + __disable_irq(); + return(result); +} + +/** + \brief Restore the Irq context + \details restore saved primask state. + \param [in] irq_state psr irq state. + */ +__ALWAYS_INLINE void drv_irq_restore(uint32_t irq_state) +{ + __set_PSR(irq_state); +} + + +#ifdef __cplusplus +} +#endif + +#endif /* _CORE_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/Kconfig b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/Kconfig new file mode 100644 index 000000000..04cf34f08 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/Kconfig @@ -0,0 +1,7 @@ +if CONFIG_CSKY +source "../../csi/csi_driver/csky/Kconfig" +endif + +if CONFIG_SANECHIPS +source "../../csi/csi_driver/sanechips/Kconfig" +endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csi.mk b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csi.mk new file mode 100644 index 000000000..3c8243ac1 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csi.mk @@ -0,0 +1,9 @@ +TEE_INC += -I$(CSI_DIR)/csi_driver/include + +ifeq ($(CONFIG_CSKY), y) +include $(CSI_DIR)/csi_driver/csky/csi.mk +endif + +ifeq ($(CONFIG_SANECHIPS), y) +include $(CSI_DIR)/csi_driver/sanechips/csi.mk +endif \ No newline at end of file diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/Kconfig b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/Kconfig new file mode 100644 index 000000000..69f84e602 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/Kconfig @@ -0,0 +1,9 @@ +source "../../csi/csi_driver/csky/common/Kconfig" + +if CONFIG_PLATFORM_PHOBOS +source "../../csi/csi_driver/csky/phobos/Kconfig" +endif + +if CONFIG_PLATFORM_HOBBIT1_2 +source "../../csi/csi_driver/csky/hobbit1_2/Kconfig" +endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/Kconfig b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/Kconfig new file mode 100644 index 000000000..e69de29bb diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/VERSION b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/VERSION new file mode 100644 index 000000000..6b3126cee --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/VERSION @@ -0,0 +1 @@ +v1.0 diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/aes/ck_aes.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/aes/ck_aes.c new file mode 100644 index 000000000..f1e88973c --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/aes/ck_aes.c @@ -0,0 +1,525 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file ck_aes.c + * @brief CSI Source File for aes driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include "csi_core.h" +#include "drv_aes.h" +#include "ck_aes.h" + +#define ERR_AES(errno) (CSI_DRV_ERRNO_AES_BASE | errno) +#define AES_NULL_PARA_CHK(para) \ + do { \ + if (para == NULL) { \ + return ERR_AES(EDRV_PARAMETER); \ + } \ + } while (0) +static ck_aes_reg_t *aes_reg = NULL; +volatile static uint8_t block_cal_done = 0; + +typedef struct { + uint32_t base; + uint32_t irq; + void *iv; + uint8_t *result_out; + uint32_t len; + aes_event_cb_t cb; + aes_mode_e mode; + aes_key_len_bits_e keylen; + aes_endian_mode_e endian; + aes_crypto_mode_e enc; + aes_status_t status; +} ck_aes_priv_t; + +extern int32_t target_get_aes_count(void); +extern int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq); + +static ck_aes_priv_t aes_handle[CONFIG_AES_NUM]; + +/* Driver Capabilities */ +static const aes_capabilities_t driver_capabilities = { + .ecb_mode = 1, /* ECB mode */ + .cbc_mode = 1, /* CBC mode */ + .cfb_mode = 0, /* CFB mode */ + .ofb_mode = 0, /* OFB mode */ + .ctr_mode = 0, /* CTR mode */ + .bits_128 = 1, /* 128bits key length mode */ + .bits_192 = 1, /* 192bits key lenght mode */ + .bits_256 = 1 /* 256bits key length mode */ +}; + +extern int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq); +extern int32_t target_get_aes_count(void); +// +// Functions +// + +static inline void aes_set_opcode(aes_crypto_mode_e opcode) +{ + aes_reg->ctrl &= ~(3 << AES_OPCODE_OFFSET); //clear bit[7:6] + aes_reg->ctrl |= (opcode << AES_OPCODE_OFFSET); //set opcode +} + +static inline void aes_set_endian(aes_endian_mode_e endian) +{ + if (endian == AES_ENDIAN_LITTLE) { + aes_reg->ctrl &= ~AES_LITTLE_ENDIAN; + } else { + aes_reg->ctrl |= AES_LITTLE_ENDIAN; + } +} + +static inline uint32_t aes_set_keylen(aes_key_len_bits_e keylength) +{ + aes_reg->ctrl &= ~(3 << AES_KEY_LEN_OFFSET); //clear bit[5:4] + aes_reg->ctrl |= (keylength << AES_KEY_LEN_OFFSET);// Set key length + + return 0; +} + +static inline void aes_set_mode(aes_mode_e mode) +{ + aes_reg->ctrl &= ~(1 << AES_MODE_OFFSET); //clear bit 3 + aes_reg->ctrl |= (mode << AES_MODE_OFFSET); //set mode +} + +static inline void aes_enable(void) +{ + aes_reg->ctrl |= (1 << AES_WORK_ENABLE_OFFSET); +} + +static inline void aes_disable(void) +{ + aes_reg->ctrl &= ~(1 << AES_WORK_ENABLE_OFFSET); +} + +static inline void aes_enable_interrupt(void) +{ + aes_reg->ctrl |= (1 << AES_INT_ENABLE_OFFSET); +} + +static inline void aes_disable_interrupt(void) +{ + aes_reg->ctrl &= ~(1 << AES_INT_ENABLE_OFFSET); +} + +static inline void aes_clear_interrupt(void) +{ + aes_reg->state = 0x0; +} + +static inline uint32_t aes_get_intstatus(uint32_t AES_IT) +{ + return (aes_reg->state & AES_IT) ? 1 : 0; +} + +static void aes_set_key(void *context, uint8_t *key, aes_key_len_bits_e keylen, uint32_t enc, uint32_t endian) +{ + uint8_t keynum = 0; + + if (keylen == AES_KEY_LEN_BITS_128) { + keynum = 4; + } else if (keylen == AES_KEY_LEN_BITS_192) { + keynum = 6; + } else if (keylen == AES_KEY_LEN_BITS_256) { + keynum = 8; + } + + uint32_t i; + uint32_t temp = 0; + /* set key according to the endian mode */ + if (endian == AES_ENDIAN_LITTLE) { + for (i = 0; i < keynum; i++) { + temp = key[3] << 24 | key[2] << 16 | key[1] << 8 | key[0]; + aes_reg->key[keynum - 1 - i] = temp; + key += 4; + } + } else if (endian == AES_ENDIAN_BIG) { + for (i = 0; i < keynum; i++) { + temp = key[3] << 24 | key[2] << 16 | key[1] << 8 | key[0]; + aes_reg->key[i] = temp; + key += 4; + } + } + + if (enc == AES_CRYPTO_MODE_DECRYPT) { + aes_set_opcode(AES_CRYPTO_KEYEXP); /* if the mode is decrypt before decrypt you have to keyexpand */ + aes_enable(); +// while(block_cal_done == 0); +// block_cal_done = 0; + + while (aes_get_intstatus(AES_IT_KEYINT)); + + aes_set_opcode(AES_CRYPTO_MODE_DECRYPT); + } else if (enc == AES_CRYPTO_MODE_ENCRYPT) { + aes_set_opcode(AES_CRYPTO_MODE_ENCRYPT); + } + + aes_disable(); +} + +static void aes_set_iv(uint32_t mode, uint32_t endian, uint8_t *iv) +{ + uint32_t temp; + uint32_t i; + /* set iv if the mode is CBC */ + if (mode == AES_MODE_CBC) { + if (endian == AES_ENDIAN_BIG) { + for (i = 0; i < 4; i++) { + temp = iv[3] << 24 | iv[2] << 16 | iv[1] << 8 | iv[0]; + aes_reg->iv[i] = temp; + iv += 4; + } + } else if (endian == AES_ENDIAN_LITTLE) { + for (i = 0; i < 4; i++) { + temp = iv[3] << 24 | iv[2] << 16 | iv[1] << 8 | iv[0]; + aes_reg->iv[3 - i] = temp; + iv += 4; + } + } + } +} + +static int aes_crypto(void *context, uint8_t *in, uint8_t *out, + uint32_t len, uint8_t *iv, uint32_t mode, uint32_t endian, uint32_t enc) +{ + + uint32_t temp[4]; + aes_set_iv(mode, endian, iv); + + uint32_t i = 0; + uint32_t j = 0; + /* set the text before aes calculating */ + for (i = 0; i < len; i = i + 16) { + for (j = 0; j < 4; j++) { + temp[j] = in[3] << 24 | in[2] << 16 | in[1] << 8 | in[0]; + if (endian == AES_ENDIAN_BIG) { + aes_reg->datain[j] = temp[j]; + } else if (endian == AES_ENDIAN_LITTLE) { + aes_reg->datain[3 - j] = temp[j]; + } + + in += 4; + } + aes_enable(); + + while(block_cal_done == 0); + block_cal_done = 0; + + if (enc == AES_CRYPTO_MODE_ENCRYPT && mode == AES_MODE_CBC) { + aes_set_iv(mode, endian, out); + memcpy(iv, out, 16); + out += 16; + } else if (enc == AES_CRYPTO_MODE_DECRYPT && mode == AES_MODE_CBC) { + aes_set_iv(mode, endian, (uint8_t *)&temp); + memcpy(iv, temp, 16); + } + } + + return 0; +} + +void ck_aes_irqhandler(int32_t idx) +{ + ck_aes_priv_t *aes_priv = &aes_handle[idx]; + + volatile uint32_t j; + uint32_t tmp = 0; + /* get the result after aes calculating*/ + if (aes_priv->result_out != NULL) { + for (j = 0; j < 4; j++) { + if (aes_priv->endian == AES_ENDIAN_BIG) { + tmp = aes_reg->dataout[j]; + } else if (aes_priv->endian == AES_ENDIAN_LITTLE) { + tmp = aes_reg->dataout[3 - j]; + } + + memcpy(aes_priv->result_out, &tmp, 4); + aes_priv->result_out += 4; + aes_priv->len -= 4; + } + } + + block_cal_done = 1; + /* disable aes and clear the aes interrupt */ + aes_disable(); + aes_clear_interrupt(); + + /* execute the callback function */ + if (aes_priv->len == 0) { + if (aes_priv->cb) { + aes_priv->cb(AES_EVENT_CRYPTO_COMPLETE); + } + } +} + +/** + \brief get aes instance count. + \return aes handle count +*/ +int32_t csi_aes_get_instance_count(void) +{ + return target_get_aes_count(); +} + +/** + \brief Initialize AES Interface. 1. Initializes the resources needed for the AES interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_aes_get_instance_count(). + \param[in] cb_event Pointer to \ref aes_event_cb_t + \return return aes handle if success +*/ +aes_handle_t csi_aes_initialize(int32_t idx, aes_event_cb_t cb_event) +{ + + if (idx < 0 || idx >= CONFIG_AES_NUM) { + return NULL; + } + + uint32_t irq = 0u; + uint32_t base = 0u; + /* obtain the aes information */ + int32_t real_idx = target_get_aes(idx, &base, &irq); + + if (real_idx != idx) { + return NULL; + } + + ck_aes_priv_t *aes_priv = &aes_handle[idx]; + + aes_priv->base = base; + aes_priv->irq = irq; + + /* initialize the aes context */ + aes_reg = (ck_aes_reg_t *)(aes_priv->base); + aes_priv->cb = cb_event; + aes_priv->iv = NULL; + aes_priv->len = 16; + aes_priv->result_out = NULL; + aes_priv->mode = AES_MODE_CBC; + aes_priv->keylen = AES_KEY_LEN_BITS_128; + aes_priv->endian = AES_ENDIAN_LITTLE; + aes_priv->status.busy = 0; + + aes_enable_interrupt(); /* enable the aes interrupt */ + + drv_nvic_enable_irq(aes_priv->irq); /* enable the aes bit in nvic */ + + return (aes_handle_t)aes_priv; +} + +/** + \brief De-initialize AES Interface. stops operation and releases the software resources used by the interface + \param[in] handle aes handle to operate. + \return error code +*/ +int32_t csi_aes_uninitialize(aes_handle_t handle) +{ + AES_NULL_PARA_CHK(handle); + + ck_aes_priv_t *aes_priv = handle; + aes_priv->cb = NULL; + + aes_disable_interrupt(); /* disable the aes interrupt */ + + drv_nvic_disable_irq(aes_priv->irq); + + return 0; +} + +/** + \brief Get driver capabilities. + \param[in] handle aes handle to operate. + \return \ref aes_capabilities_t +*/ +aes_capabilities_t csi_aes_get_capabilities(aes_handle_t handle) +{ + return driver_capabilities; +} + +/** + \brief config aes mode. + \param[in] handle aes handle to operate. + \param[in] mode \ref aes_mode_e + \param[in] keylen_bits \ref aes_key_len_bits_e + \param[in] endian \ref aes_endian_mode_e + \param[in] arg Pointer to the iv address when mode is cbc_mode + \return error code +*/ +int32_t csi_aes_config(aes_handle_t handle, aes_mode_e mode, aes_key_len_bits_e keylen_bits, aes_endian_mode_e endian, uint32_t arg) +{ + AES_NULL_PARA_CHK(handle); + + ck_aes_priv_t *aes_priv = handle; + aes_reg = (ck_aes_reg_t *)(aes_priv->base); + + /* config the aes mode */ + switch (mode) { + case AES_MODE_CBC: + aes_priv->iv = (void *)arg; + aes_priv->mode = mode; + aes_set_mode(mode); + break; + + case AES_MODE_ECB: + aes_priv->mode = mode; + aes_set_mode(mode); + break; + + case AES_MODE_CFB: + case AES_MODE_OFB: + case AES_MODE_CTR: + return ERR_AES(EDRV_UNSUPPORTED); + + default: + return ERR_AES(EDRV_PARAMETER); + } + + /* config the key length */ + switch (keylen_bits) { + case AES_KEY_LEN_BITS_128: + case AES_KEY_LEN_BITS_192: + case AES_KEY_LEN_BITS_256: + aes_priv->keylen = keylen_bits; + aes_set_keylen(keylen_bits); + break; + + default: + return ERR_AES(EDRV_PARAMETER); + } + + /* config the endian mode */ + switch (endian) { + case AES_ENDIAN_LITTLE: + aes_priv->endian = endian; + aes_set_endian(endian); + break; + + case AES_ENDIAN_BIG: + aes_priv->endian = endian; + aes_set_endian(endian); + break; + + default: + return ERR_AES(EDRV_PARAMETER); + } + + return 0; +} + +/** + \brief set crypto key. + \param[in] handle aes handle to operate. + \param[in] context aes information context(NULL when hardware implementation) + \param[in] key Pointer to the key buf + \param[in] key_len Pointer to the aes_key_len_bits_e + \param[in] enc \ref aes_crypto_mode_e + \return error code +*/ +int32_t csi_aes_set_key(aes_handle_t handle, void *context, void *key, aes_key_len_bits_e key_len, aes_crypto_mode_e enc) +{ + AES_NULL_PARA_CHK(handle); + AES_NULL_PARA_CHK(key); + if ((key_len != AES_KEY_LEN_BITS_128 && + key_len != AES_KEY_LEN_BITS_192 && + key_len != AES_KEY_LEN_BITS_256) || + (enc != AES_CRYPTO_MODE_ENCRYPT && + enc != AES_CRYPTO_MODE_DECRYPT)) { + return ERR_AES(EDRV_PARAMETER); + } + + ck_aes_priv_t *aes_priv = handle; + aes_priv->enc = enc; + aes_set_key(context, key, key_len, enc, aes_priv->endian); + + return 0; +} + +/** + \brief encrypt or decrypt + \param[in] handle aes handle to operate. + \param[in] context aes information context(NULL when hardware implementation) + \param[in] in Pointer to the Source data + \param[out] out Pointer to the Result data. + \param[in] len the Source data len. + \param[in] padding \ref aes_padding_mode_e. + \return error code +*/ +int32_t csi_aes_crypto(aes_handle_t handle, void *context, void *in, void *out, uint32_t len, aes_padding_mode_e padding) +{ + AES_NULL_PARA_CHK(handle); + AES_NULL_PARA_CHK(in); + AES_NULL_PARA_CHK(out); + AES_NULL_PARA_CHK(len); + + ck_aes_priv_t *aes_priv = handle; + + aes_priv->status.busy = 1; + + uint8_t left_len = len & 0xf; + switch (padding) { + case AES_PADDING_MODE_NO: + if (left_len) { + return ERR_AES(EDRV_PARAMETER); + } + + /* crypto in padding no mode */ + aes_priv->result_out = out; + aes_priv->len = len; + aes_crypto(context, in, out, len, aes_priv->iv, aes_priv->mode, aes_priv->endian, aes_priv->enc); + break; + + case AES_PADDING_MODE_ZERO: + if (left_len == 0) { + return ERR_AES(EDRV_PARAMETER); + } + + uint8_t i = 0; + for (i = 0; i < (16 - left_len); i++) { + *((uint8_t *)in + len + i) = 0x0; + } + + /* crypto in padding zero mode */ + aes_priv->result_out = out; + aes_priv->len = len + 16 -left_len; + aes_crypto(context, in, out, len + 16 - left_len, aes_priv->iv, aes_priv->mode, aes_priv->endian, aes_priv->enc); + break; + + case AES_PADDING_MODE_PKCS5: + return ERR_AES(EDRV_UNSUPPORTED); + + default: + return ERR_AES(EDRV_PARAMETER); + } + + aes_priv->status.busy = 0; + return 0; +} + +/** + \brief Get AES status. + \param[in] handle aes handle to operate. + \return AES status \ref aes_status_t +*/ +aes_status_t csi_aes_get_status(aes_handle_t handle) +{ + ck_aes_priv_t *aes_priv = handle; + return aes_priv->status; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/aes/ck_aes.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/aes/ck_aes.h new file mode 100644 index 000000000..976ccad61 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/aes/ck_aes.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file ck_aes.h + * @brief header file for aes driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CK_AES_H_ +#define _CK_AES_H_ + +#include +#include "drv_aes.h" +#include "soc.h" + +#define AES_LITTLE_ENDIAN 0x00000100 + +#define AES_MAX_KEY_LENGTH 32 +#define AES_IT_DATAINT 0x4 +#define AES_IT_KEYINT 0x2 +#define AES_IT_BUSY 0x1 +#define AES_IT_ALL 0x7 +#define AES_CRYPTO_KEYEXP 0x2 + +#define AES_WORK_ENABLE_OFFSET 0 +#define AES_INT_ENABLE_OFFSET 2 +#define AES_MODE_OFFSET 3 +#define AES_KEY_LEN_OFFSET 4 +#define AES_OPCODE_OFFSET 6 + +typedef struct { + __IOM uint32_t datain[4]; /* Offset: 0x000 (R/W) Data input 0~127 */ + __IOM uint32_t key[8]; /* Offset: 0x010 (R/W) Key 0~255 */ + __IOM uint32_t iv[4]; /* Offset: 0x030 (R/W) Initial Vector: 0~127 */ + __IOM uint32_t ctrl; /* Offset: 0x040 (R/W) AES Control Register */ + __IOM uint32_t state; /* Offset: 0x044 (R/W) AES State Register */ + __IOM uint32_t dataout[4]; /* Offset: 0x048 (R/W) Data Output 0~31 */ +} ck_aes_reg_t; + +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/csi.mk b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/csi.mk new file mode 100644 index 000000000..f2696dede --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/csi.mk @@ -0,0 +1,52 @@ +ifeq ($(CONFIG_SHA), y) +TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/sha/ +ifeq ($(CONFIG_PLATFORM_PHOBOS), y) +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/sha/ck_sha_v2.c +endif +ifeq ($(CONFIG_PLATFORM_HOBBIT3), y) +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/sha/ck_sha_v2.c +endif +ifeq ($(CONFIG_PLATFORM_HOBBIT1_2), y) +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/sha/ck_sha_v1.c +endif +endif + +ifeq ($(CONFIG_TRNG), y) +ifeq ($(CONFIG_PLATFORM_HOBBIT3), y) +TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/trng/ +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/trng/osr_trng.c +endif +ifeq ($(CONFIG_PLATFORM_PHOBOS), y) +TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/trng/ +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/trng/ck_trng.c +endif +ifeq ($(CONFIG_PLATFORM_HOBBIT1_2), y) +TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/trng/ +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/trng/ck_trng.c +endif +endif + +ifeq ($(CONFIG_AES), y) +TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/aes/ +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/aes/ck_aes.c +endif + +ifeq ($(CONFIG_RSA), y) +TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/rsa/ +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/rsa/ck_rsa.c +endif + +ifeq ($(CONFIG_USART), y) +TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/usart/ +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/usart/dw_usart.c +endif + +ifeq ($(CONFIG_PMU), y) +TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/pmu/ +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/pmu/ck_pmu.c +endif + +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/wdt/dw_wdt.c + +TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/eflash/ck_eflash.c + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/eflash/ck_eflash.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/eflash/ck_eflash.c new file mode 100644 index 000000000..c2ed49315 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/eflash/ck_eflash.c @@ -0,0 +1,441 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file ck_eflash.c + * @brief CSI Source File for Embedded Flash Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#include +#include +#include "csi_core.h" +#include "drv_eflash.h" +#include "ck_eflash.h" + + +#define ERR_EFLASH(errno) (CSI_DRV_ERRNO_EFLASH_BASE | errno) +#define EFLASH_NULL_PARAM_CHK(para) \ + do { \ + if (para == NULL) { \ + return ERR_EFLASH(EDRV_PARAMETER); \ + } \ + } while (0) + +typedef struct { + uint32_t base; + eflash_info_t eflashinfo; + eflash_event_cb_t cb; + eflash_status_t status; +} ck_eflash_priv_t; + +extern int32_t target_get_eflash_count(void); +extern int32_t target_get_eflash(int32_t idx, uint32_t *base, eflash_info_t *info); + +static ck_eflash_priv_t eflash_handle[CONFIG_EFLASH_NUM]; +/* Driver Capabilities */ +static const eflash_capabilities_t driver_capabilities = { + .event_ready = 1, /* event_ready */ + .data_width = 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */ + .erase_chip = 0 /* erase_chip */ +}; + +// +// Functions +// + +static int32_t eflash_program_word(eflash_handle_t handle, uint32_t dstaddr, uint32_t *srcbuf, uint32_t len) +{ + ck_eflash_priv_t *eflash_priv = handle; + uint32_t fbase = eflash_priv->base; + uint32_t i; + + for (i = 0; i < len; i++) { + *(volatile uint32_t *)(fbase + 0x04) = dstaddr; + *(volatile uint32_t *)(fbase + 0x1c) = *srcbuf; + *(volatile uint32_t *)(fbase + 0x18) = 1; + srcbuf++; + dstaddr += 4; + } + + return (i << 2); +} + + +#ifdef CONFIG_CHIP_CH2201 +static uint32_t context[EFLASH_SECTOR_SIZE >> 2] = {0x0}; +static int32_t eflash_verify(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt) +{ + uint32_t i; + uint8_t error_flag = 1; + + uint8_t *block_addr = (uint8_t *)(addr & ~(EFLASH_SECTOR_SIZE - 1)); + uint32_t pre_offset = addr - (uint32_t)block_addr; + uint32_t pre_count = (cnt > (EFLASH_SECTOR_SIZE - pre_offset)) ? (EFLASH_SECTOR_SIZE - pre_offset) : cnt; + + uint8_t *p = NULL; + uint8_t *dst = NULL; + + p = (uint8_t *)data; + dst = (uint8_t *)addr; + uint32_t len = cnt; + volatile uint8_t verify_count = 100; + + while (error_flag) { + for (i = 0; i < pre_count; i++) { + if (*((uint8_t *)dst + i) != *((uint8_t *)p + i)) { + *(volatile uint32_t *) 0x50004000 = 'E'; /* for debug */ + *(volatile uint32_t *) 0x50004000 = 'E'; + *(volatile uint32_t *) 0x50004000 = 'E'; + *(volatile uint32_t *) 0x50004000 = 'E'; + *(volatile uint32_t *) 0x50004000 = '\n'; + memcpy(context, block_addr, EFLASH_SECTOR_SIZE); + memcpy((uint8_t *)context + pre_offset, p, pre_count); + csi_eflash_erase_sector(handle, (uint32_t)dst); + eflash_program_word(handle, (uint32_t)block_addr, context, EFLASH_SECTOR_SIZE >> 2); + break; + } + } + + if (i == pre_count || !(verify_count--)) { + error_flag = 0; + } + } + + if (!verify_count) { + return ERR_EFLASH(EDRV_TIMEOUT); + } + verify_count = 100; + + error_flag = 1; + p += pre_count; + dst += pre_count; + len -= pre_count; + + while (len >= EFLASH_SECTOR_SIZE) { + while (error_flag) { + for (i = 0; i < EFLASH_SECTOR_SIZE; i++) { + if (*((uint8_t *)dst + i) != *((uint8_t *)p + i)) { + *(volatile uint32_t *) 0x50004000 = 'E'; /* for debug */ + *(volatile uint32_t *) 0x50004000 = 'E'; + *(volatile uint32_t *) 0x50004000 = 'E'; + *(volatile uint32_t *) 0x50004000 = 'E'; + *(volatile uint32_t *) 0x50004000 = '\n'; + memcpy((uint8_t *)context, p, EFLASH_SECTOR_SIZE); + csi_eflash_erase_sector(handle, (uint32_t)dst); + eflash_program_word(handle, (uint32_t)dst, context, EFLASH_SECTOR_SIZE >> 2); + break; + } + } + + if (i == EFLASH_SECTOR_SIZE || !(verify_count--)) { + error_flag = 0; + } + } + + if (!verify_count) { + return ERR_EFLASH(EDRV_TIMEOUT); + } + + verify_count = 100; + + error_flag = 1; + dst += EFLASH_SECTOR_SIZE; + p += EFLASH_SECTOR_SIZE; + len -= EFLASH_SECTOR_SIZE; + } + + if (len > 0) { + while (error_flag) { + for (i = 0; i < len; i++) { + if (*((uint8_t *)dst + i) != *((uint8_t *)p + i)) { + *(volatile uint32_t *) 0x50004000 = 'E'; /* for debug */ + *(volatile uint32_t *) 0x50004000 = 'E'; + *(volatile uint32_t *) 0x50004000 = 'E'; + *(volatile uint32_t *) 0x50004000 = 'E'; + *(volatile uint32_t *) 0x50004000 = '\n'; + memcpy(context, dst, EFLASH_SECTOR_SIZE); + memcpy((uint8_t *)context + i, p + i, len - i); + csi_eflash_erase_sector(handle, (uint32_t)dst); + eflash_program_word(handle, (uint32_t)dst, context, EFLASH_SECTOR_SIZE >> 2); + break; + } + } + + if (i == len || !(verify_count--)) { + error_flag = 0; + } + } + + if (!verify_count) { + return ERR_EFLASH(EDRV_TIMEOUT); + } + + verify_count = 100; + } + + return 0; +} +#endif + +/** + \brief Initialize EFLASH Interface. 1. Initializes the resources needed for the EFLASH interface 2.registers event callback function + \param[in] idx device id + \param[in] cb_event Pointer to \ref eflash_event_cb_t + \return pointer to eflash handle +*/ +eflash_handle_t csi_eflash_initialize(int32_t idx, eflash_event_cb_t cb_event) +{ + if (idx < 0 || idx >= CONFIG_EFLASH_NUM) { + return NULL; + } + + /* obtain the eflash information */ + uint32_t base = 0u; + eflash_info_t info; + int32_t real_idx = target_get_eflash(idx, &base, &info); + + if (real_idx != idx) { + return NULL; + } + + ck_eflash_priv_t *eflash_priv = &eflash_handle[idx]; + + eflash_priv->base = base; + eflash_priv->eflashinfo.start = info.start; + eflash_priv->eflashinfo.end = info.end; + eflash_priv->eflashinfo.sector_count = info.sector_count; + + /* initialize the eflash context */ + eflash_priv->cb = cb_event; + eflash_priv->status.busy = 0; + eflash_priv->status.error = 0U; + eflash_priv->eflashinfo.sector_size = EFLASH_SECTOR_SIZE; + eflash_priv->eflashinfo.page_size = EFLASH_PAGE_SIZE; + eflash_priv->eflashinfo.program_unit = EFLASH_PROGRAM_UINT; + eflash_priv->eflashinfo.erased_value = EFLASH_ERASED_VALUE; + + return (eflash_handle_t)eflash_priv; +} + +/** + \brief De-initialize EFLASH Interface. stops operation and releases the software resources used by the interface + \param[in] handle eflash handle to operate. + \return error code +*/ +int32_t csi_eflash_uninitialize(eflash_handle_t handle) +{ + EFLASH_NULL_PARAM_CHK(handle); + + ck_eflash_priv_t *eflash_priv = handle; + eflash_priv->cb = NULL; + + return 0; +} + +/** + \brief Get driver capabilities. + \param[in] idx device id + \return \ref eflash_capabilities_t +*/ +eflash_capabilities_t csi_eflash_get_capabilities(eflash_handle_t handle) +{ + return driver_capabilities; +} + +/** + \brief Read data from Flash. + \param[in] handle eflash handle to operate. + \param[in] addr Data address. + \param[out] data Pointer to a buffer storing the data read from Flash. + \param[in] cnt Number of data items to read. + \return number of data items read or error code +*/ +int32_t csi_eflash_read(eflash_handle_t handle, uint32_t addr, void *data, uint32_t cnt) +{ + EFLASH_NULL_PARAM_CHK(handle); + EFLASH_NULL_PARAM_CHK(data); + EFLASH_NULL_PARAM_CHK(cnt); + + volatile uint8_t *src_addr = (uint8_t *)addr; + ck_eflash_priv_t *eflash_priv = handle; + + if (eflash_priv->eflashinfo.start > addr || eflash_priv->eflashinfo.end < addr || eflash_priv->eflashinfo.start > (addr + cnt - 1) || eflash_priv->eflashinfo.end < (addr + cnt - 1)) { + return ERR_EFLASH(EDRV_PARAMETER); + } + + if (eflash_priv->status.busy) { + return ERR_EFLASH(EDRV_BUSY); + } + + eflash_priv->status.error = 0U; + + int i; + + for (i = 0; i < cnt; i++) { + *((uint8_t *)data + i) = *(src_addr + i); + } + + return i; +} + +/** + \brief Program data to Flash. + \param[in] handle eflash handle to operate. + \param[in] addr Data address. + \param[in] data Pointer to a buffer containing the data to be programmed to Flash.. + \param[in] cnt Number of data items to program. + \return number of data items programmed or error code +*/ +int32_t csi_eflash_program(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt) +{ + EFLASH_NULL_PARAM_CHK(handle); + EFLASH_NULL_PARAM_CHK(data); + EFLASH_NULL_PARAM_CHK(cnt); + + ck_eflash_priv_t *eflash_priv = handle; + + if (eflash_priv->eflashinfo.start > addr || eflash_priv->eflashinfo.end < addr || eflash_priv->eflashinfo.start > (addr + cnt - 1) || eflash_priv->eflashinfo.end < (addr + cnt - 1)) { + return ERR_EFLASH(EDRV_PARAMETER); + } + + uint32_t cur = 0; + uint32_t pad_buf; + + if (addr & 0x3) { + return ERR_EFLASH(EDRV_PARAMETER); + } + + if (eflash_priv->status.busy) { + return ERR_EFLASH(EDRV_BUSY); + } + + eflash_priv->status.busy = 1U; + eflash_priv->status.error = 0U; + + if (((uint32_t)data & 0x3) == 0) { + cur = cnt - (cnt & 0x3); + eflash_program_word(handle, addr, (uint32_t *)data, cur >> 2); + } else { + uint8_t *buffer_b = (uint8_t *)data; + + for (; cur < cnt - 3; cur += 4, buffer_b += 4) { + pad_buf = buffer_b[0] | (buffer_b[1] << 8) | (buffer_b[2] << 16) | (buffer_b[3] << 24); + eflash_program_word(handle, addr + cur, &pad_buf, 1); + } + } + + if (cur < cnt) { + pad_buf = *((volatile uint32_t *)(addr + cur)); + uint8_t *pad = (uint8_t *)&pad_buf; + uint8_t *buff = (uint8_t *)data; + uint8_t i; + + for (i = 0; i < (cnt - cur); i++) { + pad[i] = buff[cur + i]; + } + + eflash_program_word(handle, addr + cur, &pad_buf, 1); + } + + + eflash_priv->status.busy = 0U; +#ifdef CONFIG_CHIP_CH2201 + eflash_verify(handle, addr, data, cnt); +#endif + + return cnt; +} + +/** + \brief Erase Flash Sector. + \param[in] handle eflash handle to operate. + \param[in] addr Sector address + \return error code +*/ +int32_t csi_eflash_erase_sector(eflash_handle_t handle, uint32_t addr) +{ + EFLASH_NULL_PARAM_CHK(handle); + + ck_eflash_priv_t *eflash_priv = handle; + + if (eflash_priv->eflashinfo.start > addr || eflash_priv->eflashinfo.end < addr) { + return ERR_EFLASH(EDRV_PARAMETER); + } + + + addr = addr & ~(EFLASH_SECTOR_SIZE - 1); + uint32_t fbase = eflash_priv->base; + + if (eflash_priv->status.busy) { + return ERR_EFLASH(EDRV_BUSY); + } + + eflash_priv->status.busy = 1U; + eflash_priv->status.error = 0U; + *(volatile uint32_t *)(fbase + 0x4) = addr; + *(volatile uint32_t *)(fbase + 0x10) = 0x1; + eflash_priv->status.busy = 0U; + + return 0; +} + +/** + \brief Erase complete Flash. + \param[in] handle eflash handle to operate. + \return error code +*/ +int32_t csi_eflash_erase_chip(eflash_handle_t handle) +{ + EFLASH_NULL_PARAM_CHK(handle); + + return ERR_EFLASH(EDRV_UNSUPPORTED); +} + +/** + \brief Get Flash information. + \param[in] handle eflash handle to operate. + \return Pointer to Flash information \ref eflash_info_t +*/ +eflash_info_t *csi_eflash_get_info(eflash_handle_t handle) +{ + if (handle == NULL) { + return NULL; + } + + ck_eflash_priv_t *eflash_priv = handle; + eflash_info_t *eflash_info = &(eflash_priv->eflashinfo); + + return eflash_info; +} + +/** + \brief Get EFLASH status. + \param[in] handle eflash handle to operate. + \return EFLASH status \ref eflash_status_t +*/ +eflash_status_t csi_eflash_get_status(eflash_handle_t handle) +{ + if (handle == NULL) { + eflash_status_t ret; + memset(&ret, 0, sizeof(eflash_status_t)); + return ret; + } + + ck_eflash_priv_t *eflash_priv = handle; + + return eflash_priv->status; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/eflash/ck_eflash.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/eflash/ck_eflash.h new file mode 100644 index 000000000..609529354 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/eflash/ck_eflash.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file ck_eflash.h + * @brief head file for ck eflash + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CK_EFLASH_H_ +#define _CK_EFLASH_H_ + +#include "drv_eflash.h" +#include "soc.h" + +#define EFLASH_SECTOR_SIZE 0x200 +#define EFLASH_ERASED_VALUE 0xff +#define EFLASH_PROGRAM_UINT 0x4 +#define EFLASH_PAGE_SIZE 0 + +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/pmu/ck_pmu.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/pmu/ck_pmu.c new file mode 100644 index 000000000..c3e0691c4 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/pmu/ck_pmu.c @@ -0,0 +1,366 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file ck_pmu.c + * @brief CSI Source File for Embedded Flash Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#include +#include +#include "drv_pmu.h" +#include "drv_tee.h" +#include "drv_eflash.h" +#include "ck_pmu.h" + +#define ERR_PMU(errno) (CSI_DRV_ERRNO_PMU_BASE | errno) +#define PMU_NULL_PARAM_CHK(para) \ + do { \ + if (para == NULL) { \ + return ERR_PMU(EDRV_PARAMETER); \ + } \ + } while (0) + +typedef struct { + uint8_t idx; + uint32_t base; + uint32_t irq; + pmu_event_cb_t cb; + pmu_action_cb_t callback[32]; +} ck_pmu_priv_t; + +extern int32_t target_get_pmu(int32_t idx, uint32_t *base, uint32_t *irq); +extern int32_t arch_do_cpu_save(void); +extern int32_t arch_do_cpu_resume(void); +extern int32_t arch_resume_context(void); + +static ck_pmu_priv_t pmu_handle[CONFIG_PMU_NUM]; +static uint32_t s_callback_count = 0; +#define CONFIG_PMU_REGISTER_NUM_SAVE 19 +static uint32_t pmu_regs_saved[CONFIG_PMU_REGISTER_NUM_SAVE]; + +#define CONFIG_CPU_REGISTER_NUM_SAVE 27 +uint32_t arch_cpu_saved[CONFIG_CPU_REGISTER_NUM_SAVE]; +/* Driver Capabilities */ +#if 0 +static const pmu_capabilities_t driver_capabilities = { + .event_ready = 1, /* event_ready */ + .data_width = 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */ + .erase_chip = 0 /* erase_chip */ +}; +#endif +// +// Functions +// + +static void do_prepare_sleep_action(int32_t idx) +{ + uint8_t i; + volatile ck_pmu_reg_t *pbase = (ck_pmu_reg_t *)pmu_handle[idx].base; + for (i = 0; i < sizeof(pmu_regs_saved)/4; i++) { + pmu_regs_saved[i] = *((volatile uint32_t *)pbase + i); + } +} + +static void do_wakeup_sleep_action(int32_t idx) +{ + uint8_t i; + volatile ck_pmu_reg_t *pbase = (ck_pmu_reg_t *)pmu_handle[idx].base; + *((volatile uint32_t *)pbase + 5) = pmu_regs_saved[5]; + while((*((volatile uint32_t *)pbase + 6) & 0xf) != 0xf); + *((volatile uint32_t *)pbase + 11) = pmu_regs_saved[11]; + while((*((volatile uint32_t *)pbase + 6) & 0x1f) != 0x1f); + for (i = 0; i < sizeof(pmu_regs_saved)/4; i++) { + if (i != 5 && i != 11) { + *((volatile uint32_t *)pbase + i) = pmu_regs_saved[i]; + } + } + +} + +static uint8_t s_action[CONFIG_PMU_NUM] = {0x0}; +int32_t ck_pmu_power_manager(int32_t idx) +{ + if (!(s_action[idx] % 2)) { + do_prepare_sleep_action(idx); + s_action[idx]++; + } else { + do_wakeup_sleep_action(idx); + s_action[idx]--; + } + return 0; +} + +int32_t ck_pmu_act_callback(pmu_handle_t handle, pmu_event_e event) +{ + ck_pmu_priv_t *pmu_priv = handle; + uint32_t i; + for (i = 0; i < s_callback_count; i++) { + if (pmu_priv->callback[i]) { + pmu_priv->callback[i](event); + } + } + + if (i != s_callback_count) { + return -1; + } + return 0; +} + +void resume_context_from_stop_mode(void) +{ + ck_pmu_priv_t *pmu_priv = &pmu_handle[0]; +// ck_pmu_power_manager(PMU_EVENT_SLEEP_DONE); +// ck_pmu_act_callback(pmu_priv, PMU_EVENT_SLEEP_DONE); + *((volatile uint32_t *)0x50006100) |= 0xa0000000; + if (pmu_priv->cb) { + pmu_priv->cb(pmu_priv->idx, PMU_EVENT_SLEEP_DONE, PMU_MODE_STDBY); + } + + arch_do_cpu_resume(); +} + +#define CONFIG_LPM_RESUME_ADDR 0x1003f7f0 +void set_resume_func(uint32_t *func) +{ + eflash_handle_t eflash = csi_eflash_initialize(0, NULL); + csi_eflash_erase_sector(eflash, CONFIG_LPM_RESUME_ADDR); + csi_eflash_program(eflash, CONFIG_LPM_RESUME_ADDR, &func, 4); +} + +typedef enum { + WAIT_MODE = 0, + DOZE_MODE, + STOP_MODE, + STANDBY_MODE, + SLEEP_MODE +} lpm_mode_t; + + +void soc_sleep(pmu_handle_t handle, lpm_mode_t mode) +{ +#ifdef CONFIG_TEE_CA + tee_lpm_mode_e lpm_mode = 0; + + if (mode == WAIT_MODE) { + lpm_mode = TEE_LPM_MODE_WAIT; + } else if (mode == DOZE_MODE) { + lpm_mode = TEE_LPM_MODE_DOZE; + } else if (mode == STOP_MODE) { + lpm_mode = TEE_LPM_MODE_STOP; + } else if (mode == STANDBY_MODE) { + lpm_mode = TEE_LPM_MODE_STANDBY; + } else { + lpm_mode = TEE_LPM_MODE_WAIT; + } + + csi_tee_enter_lpm(0, 0, lpm_mode); + + if (mode == STOP_MODE) { + resume_context_from_stop_mode(); + } +#else + + ck_pmu_priv_t *pmu_priv = handle; + ck_pmu_reg_t *pmu_reg = (ck_pmu_reg_t *)pmu_priv->base; + + if (mode == WAIT_MODE) { + pmu_reg->LPCR |= CONFIG_PMU_ENTER_WAIT_MODE; + __WFI(); + } else if (mode == DOZE_MODE) { + pmu_reg->LPCR |= CONFIG_PMU_ENTER_DOZE_MODE; + __DOZE(); + } else if (mode == STOP_MODE) { + pmu_reg->LPCR |= CONFIG_PMU_ENTER_STOP_MODE; + __STOP(); + } else if (mode == STANDBY_MODE) { + pmu_reg->LPCR |= CONFIG_PMU_ENTER_STANDBY_MODE; + __STOP(); + } else { + pmu_reg->LPCR |= CONFIG_PMU_ENTER_WAIT_MODE; + __WFI(); + } + +#endif +} + +/** + \brief Initialize PMU Interface. 1. Initializes the resources needed for the PMU interface 2.registers event callback function + \param[in] idx device id + \param[in] cb_event Pointer to \ref pmu_event_cb_t + \return pointer to pmu handle +*/ +pmu_handle_t drv_pmu_initialize(int32_t idx, pmu_event_cb_t cb_event) +{ + if (idx < 0 || idx >= CONFIG_PMU_NUM) { + return NULL; + } + + /* obtain the pmu information */ + uint32_t base = 0u; + uint32_t irq = 0u; + int32_t real_idx = target_get_pmu(idx, &base, &irq); + + if (real_idx != idx) { + return NULL; + } + + ck_pmu_priv_t *pmu_priv = &pmu_handle[idx]; + + /* initialize the pmu context */ + pmu_priv->idx = idx; + pmu_priv->base = base; + pmu_priv->irq = irq; + pmu_priv->cb = cb_event; + + return (pmu_handle_t)pmu_priv; +} + +/** + \brief De-initialize PMU Interface. stops operation and releases the software resources used by the interface + \param[in] handle pmu handle to operate. + \return error code +*/ +int32_t drv_pmu_uninitialize(pmu_handle_t handle) +{ + PMU_NULL_PARAM_CHK(handle); + + ck_pmu_priv_t *pmu_priv = handle; + pmu_priv->cb = NULL; + + return 0; +} + +int32_t drv_pmu_power_control(int32_t idx, csi_power_stat_e state) +{ + switch (state) { + case DRV_POWER_LOW: + break; + case DRV_POWER_FULL: + break; + case DRV_POWER_OFF: + ck_pmu_power_manager(idx); +// csi_pmu_register_module(dw_usart_power_manager); + break; + default: + break; + } + + return 0; +} + +/** + \brief Get driver capabilities. + \param[in] idx device id + \return \ref pmu_capabilities_t +*/ +#if 0 +pmu_capabilities_t csi_pmu_get_capabilities(int32_t idx) +{ + if (idx < 0 || idx >= CONFIG_PMU_NUM) { + pmu_capabilities_t ret; + memset(&ret, 0, sizeof(pmu_capabilities_t)); + return ret; + } + + return driver_capabilities; +} +#endif +/** + \brief choose the pmu mode to enter + \param[in] handle pmu handle to operate. + \param[in] mode \ref pmu_mode_e + \return error code +*/ +int32_t drv_pmu_enter_sleep(pmu_handle_t handle, pmu_mode_e mode) +{ + PMU_NULL_PARAM_CHK(handle); + + switch (mode) { + case PMU_MODE_RUN: + break; + case PMU_MODE_SLEEP: + soc_sleep(handle, WAIT_MODE); + break; + case PMU_MODE_DORMANT: +// soc_sleep(handle, DOZE_MODE); + if (arch_do_cpu_save() == 0) { + *(volatile unsigned int *)(0xe000e1c0) = 0xffffffff; // reload wakeup_IRQ + *(volatile unsigned int *)(0xe000e280) = 0xffffffff; // clear pend IRQ + soc_sleep(handle, STOP_MODE); + } + break; + case PMU_MODE_STDBY: + *(volatile unsigned int *)(0xe000e1c0) = 0xffffffff; // reload wakeup_IRQ + *(volatile unsigned int *)(0xe000e280) = 0xffffffff; // clear pend IRQ + soc_sleep(handle, STANDBY_MODE); + break; + case PMU_MODE_SHUTDOWN: + *(volatile unsigned int *)(0xe000e1c0) = 0xffffffff; // reload wakeup_IRQ + *(volatile unsigned int *)(0xe000e280) = 0xffffffff; // clear pend IRQ + soc_sleep(handle, STANDBY_MODE); + break; + default: + return ERR_PMU(EDRV_PARAMETER); + } + + return 0; +} + +/** + \brief register module to action pmu event + \param[in] handle pmu handle to operate. + \param[in] callback Pointer to \ref pmu_action_cb_t + \return error code +*/ +int32_t drv_pmu_register_module(pmu_action_cb_t callback) +{ + ck_pmu_priv_t *pmu_priv = (ck_pmu_priv_t *)&pmu_handle[0]; + + if (callback == NULL) { + return ERR_PMU(EDRV_PARAMETER); + } + pmu_priv->callback[s_callback_count] = callback; + s_callback_count++; + return 0; +} + +/** + \brief Config the wakeup source. + \param[in] handle pmu handle to operate + \param[in] type \ref pmu_wakeup_type + \param[in] pol \ref pmu_wakeup_pol + \param[in] enable flag control the wakeup source is enable or not + \return error code +*/ +int32_t drv_pmu_config_wakeup_source(pmu_handle_t handle, uint32_t irq_num, pmu_wakeup_type_e type, pmu_wakeup_pol_e pol, uint8_t enable) +{ + PMU_NULL_PARAM_CHK(handle); + + if (enable) { +// csi_vic_enable_irq(irq_num); +// csi_vic_enable_sirq(irq_num); +// csi_vic_set_wakeup_irq(irq_num); + drv_nvic_set_wakeup_irq(irq_num); + } else { +// csi_vic_disable_irq(irq_num); +// csi_vic_disable_sirq(irq_num); + drv_nvic_clear_wakeup_irq(irq_num); +// csi_vic_clear_wakeup_irq(irq_num); + } + return 0; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/pmu/ck_pmu.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/pmu/ck_pmu.h new file mode 100644 index 000000000..00478989e --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/pmu/ck_pmu.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file ck_pmu.h + * @brief head file for ck pmu + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CK_PMU_H_ +#define _CK_PMU_H_ + +#include "drv_pmu.h" +#include "soc.h" + +#define CONFIG_PMU_ENTER_WAIT_MODE 0x4 +#define CONFIG_PMU_ENTER_DOZE_MODE 0x4 +#define CONFIG_PMU_ENTER_STOP_MODE 0xc +#define CONFIG_PMU_ENTER_STANDBY_MODE 0x14 + +typedef struct { + __IOM uint32_t LPCR; /* Offset: 0x000 (R/W) low power control register */ + __IOM uint32_t MCLKSEL; /* Offset: 0x004 (R/W) MCLK select register */ + __IOM uint32_t CRCR; /* Offset: 0x008 (R/W) clock ratio control register */ + __IOM uint32_t CGCR; /* Offset: 0x00c (R/W) clock gate control register */ + __IOM uint32_t CGSR; /* Offset: 0x010 (R/W) clock gate status register */ + __IOM uint32_t CLKDSENR; /* Offset: 0x014 (R/W) clock disable register */ + __IOM uint32_t CLKSTBR; /* Offset: 0x018 (R/W) clock stable register */ + __IOM uint32_t CLKSTBST; /* Offset: 0x01c (R/W) clock stable interrupt statue register */ + __IOM uint32_t CLKSTBMK; /* Offset: 0x020 (R/W) clock stable interrupt mask register */ + __IOM uint32_t CSSCR; /* Offset: 0x024 (R/W) clock source stable counter register */ + __IOM uint32_t DFCC; /* Offset: 0x028 (R/W) dynamic frequence conversion control register */ + __IOM uint32_t PCR; /* Offset: 0x02c (R/W) pll control register */ + __IOM uint32_t PLTR; /* Offset: 0x030 (R/W) pll lock timer register */ + __IOM uint32_t SWHRC; /* Offset: 0x034 (R/W) software HRST control register */ + __IOM uint32_t SWHRD; /* Offset: 0x038 (R/W) software HRST duration register */ + __IOM uint32_t SWPRC; /* Offset: 0x03c (R/W) software PRST control register */ + __IOM uint32_t SWPRD; /* Offset: 0x040 (R/W) software PRST duration register */ + __IOM uint32_t SWRE; /* Offset: 0x044 (R/W) software reset enable register */ + __IOM uint32_t BOOTSEL; /* Offset: 0x048 (R/W) boot selection register */ + __IOM uint32_t SCGCR; /* Offset: 0x04c (R/W) security clock gate control register */ + __IOM uint32_t SCGSR; /* Offset: 0x050 (R/W) security clock gate status register */ +} ck_pmu_reg_t; + +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/rsa/ck_rsa.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/rsa/ck_rsa.c new file mode 100644 index 000000000..c7d999cdf --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/rsa/ck_rsa.c @@ -0,0 +1,1285 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file ck_rsa.c + * @brief CSI Source File for RSA Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include +#include "drv_rsa.h" +#include "ck_rsa.h" +#include "irq.h" + +#define ERR_RSA(errno) (CSI_DRV_ERRNO_RSA_BASE | errno) +#define RSA_NULL_PARAM_CHK(para) \ + do { \ + if (para == NULL) { \ + return ERR_RSA(EDRV_PARAMETER); \ + } \ + } while (0) + + +typedef struct { + uint32_t base; + uint32_t irq; + rsa_event_cb_t cb; + rsa_data_bits_e data_bit; + rsa_endian_mode_e endian; + rsa_padding_t padding; + rsa_status_t status; +} ck_rsa_priv_t; + +extern int32_t target_get_rsa_count(void); +extern int32_t target_get_rsa(int32_t idx, uint32_t *base, uint32_t *irq); + +static ck_rsa_priv_t rsa_handle[CONFIG_RSA_NUM]; + +extern uint8_t modulus[]; +static ck_rsa_reg_t *rsa_reg = NULL; +/* Driver Capabilities */ +static const rsa_capabilities_t driver_capabilities = { + .bits_192 = 1, /* 192bits modular mode */ + .bits_256 = 1, /* 256bits modular mode */ + .bits_512 = 1, /* 512bits modular mode */ + .bits_1024 = 1, /* 1024bits modular mode */ + .bits_2048 = 1 /* 2048bits modular mode */ +}; + +extern int32_t target_get_rsa(int32_t idx, uint32_t *base, uint32_t *irq); +extern int32_t target_get_rsa_count(void); +// +// Functions +// + +static uint32_t sw_exptmod_2_2m(const uint32_t *modulus, uint32_t words, uint32_t *tmp_c); +static uint32_t get_valid_bits(const uint32_t *addr, uint32_t wordsize, uint32_t keywords); + +#ifdef RSA_USING_ID2KEY +static uint32_t g_acc[RSA_KEY_WORD]; +#endif + +static inline void rsa_clear_int(void) +{ + rsa_reg->rsa_isr = 0xffff; + rsa_reg->rsa_imr = 0x0000; +} + +static inline void rsa_setm_width(uint32_t width) +{ + rsa_reg->rsa_mwid = width; +} + +static inline void rsa_setd_width(uint32_t width) +{ + rsa_reg->rsa_ckid = width; +} + +static inline void rsa_setb_width(uint32_t width) +{ + rsa_reg->rsa_bwid = width; +} + +static inline void rsa_cal_q(void) +{ + rsa_reg->rsa_ctrl = RAS_CALCULATE_Q; +} + +static inline void rsa_opr_start(void) +{ + rsa_reg->rsa_ctrl = RSA_ENABLE_MODULE; +} + +static inline void rsa_opr_reset(void) +{ + rsa_reg->rsa_ctrl = RSA_ENDIAN_MODE; + rsa_reg->rsa_rst |= RSA_RESET; + + while (rsa_reg->rsa_rst); +} + +static inline uint32_t rsa_loop_cnt(void) +{ + return rsa_reg->rsa_lp_cnt; +} + +static inline uint32_t rsa_cal_q_done(void) +{ + return (rsa_reg->rsa_isr >> RSA_CAL_Q_DONE_OFFSET) & 0x1; +} + +static inline uint32_t rsa_opr_done(void) +{ + return (rsa_reg->rsa_isr) & 0x1; +} + +static inline uint32_t rsa_raise_exception(void) +{ + return (rsa_reg->rsa_isr) & 0x1E; +} + +static inline uint32_t rsa_loadm(uint32_t *data, uint32_t length) +{ + uint32_t i; + uint32_t baseaddr = (uint32_t)&rsa_reg->rsa_rfm; + + for (i = 0; i < length; i++) { + *(volatile uint32_t *)baseaddr = data[i]; + baseaddr = baseaddr + 4; + } + + return 0; +} + +static void rsa_loadd(uint32_t *data, uint32_t length) +{ + uint32_t i; + uint32_t baseaddr = (uint32_t)&rsa_reg->rsa_rfd; + + for (i = 0; i < length; i++) { + *(volatile uint32_t *)baseaddr = data[i]; + baseaddr = baseaddr + 4; + } +} + +static void rsa_loadc(uint32_t *data, uint32_t length) +{ + uint32_t i; + uint32_t baseaddr = (uint32_t)&rsa_reg->rsa_rfc; + + for (i = 1; i < length + 1; i++) { + *(volatile uint32_t *)baseaddr = data[i - 1]; + baseaddr = baseaddr + 4; + } +} + +static void rsa_loadb(uint32_t *data, uint32_t length) +{ + uint32_t i; + uint32_t baseaddr = (uint32_t)&rsa_reg->rsa_rfb; + + for (i = 0; i < length; i++) { + *(volatile uint32_t *)baseaddr = data[i]; + baseaddr = baseaddr + 4; + } +} + +static void rsa_read_r(uint32_t data[], uint32_t length) +{ + uint32_t i; + uint32_t baseaddr = (uint32_t)&rsa_reg->rsa_rfr; + + for (i = 0; i < length; i++) { + data[i] = *(uint32_t *)baseaddr; + baseaddr = baseaddr + 4; + } +} + +#if (CONFIG_PLATFORM_HOBBIT1_2 > 0) +// FIXME +// Since there is a piece of memory hole in RSA engine. we should +// jump the hold to continue run without disable interrupt +#define RSA_SP_HOLE_DOWN 0x60000900 +#define RSA_SP_HOLE_UP 0x600009FF +#define TEE_CONEXT_SIZE 128 +static uint32_t rsa_run_adjust_sp_if_need(uint32_t sp) +{ + uint32_t sp_chg; + + // if current sp is in hole, adjust new sp + if ((sp < (RSA_SP_HOLE_UP + TEE_CONEXT_SIZE)) && (sp > RSA_SP_HOLE_DOWN)) + sp_chg = 1; + else + sp_chg = 0; + + return sp_chg; +} + +static void rsa_run_by_assemble(void) +{ + __asm__ __volatile__ ( + "subi sp, 0x10 \n" + "stm r4-r7, (sp) \n" + + // update sp + "mov r4, sp \n" + "subi r4, 0x180 \n" + "mov sp, r4 \n" + + // enable rsa engine + "lrw r5, 0x4000a00c \n" + "movi r6, 3 \n" + "stw r6, (r5) \n" + // check rsa end + "__chk_loop: \n" + "lrw r5, 0x4000a020 \n" + "ldw r6, (r5) \n" + "btsti r6, 0 \n" + "bt __chk_end \n" + + "lrw r5, 0x4000a020 \n" + "ldw r6, (r5) \n" + "movi r7, 0x1e \n" + "and r6, r7 \n" + "cmpnei r6, 0 \n" + "bf __chk_loop \n" + + "lrw r5, 0x4000a014 \n" + "ldw r6, (r5) \n" + "cmplti r6, 0x40 \n" + "bt __chk_loop \n" + + "__chk_end: \n" + + // update sp + "mov r4, sp \n" + "addi r4, 0x180 \n" + "mov sp, r4 \n" + + "ldm r4-r7, (sp) \n" + "addi sp, 0x10 \n" + ); +} +#endif + +static uint32_t rsa_exptmod(const uint32_t *modulus, const uint32_t *exponent, + const uint32_t *base, uint32_t *out, uint32_t keywords, + uint32_t *tmp_c) +{ + uint32_t ret = 0; + if ((NULL == exponent) || (NULL == base) || (NULL == out)) { + return 1; + } + +#ifdef RSA_USING_ID2KEY + memcpy(tmp_c, g_acc, sizeof(g_acc)); +#endif + + /* reset for safe */ + rsa_opr_reset(); + /* clear and disable int */ + rsa_clear_int(); + /* set m */ + rsa_setm_width(keywords >> 1); + rsa_loadm((uint32_t *)modulus, keywords); + /* set d */ + rsa_setd_width(get_valid_bits(exponent, keywords, keywords) - 1); + rsa_loadd((uint32_t *)exponent, keywords); + /* set b */ + rsa_setb_width(keywords >> 1); + rsa_loadb((uint32_t *)base, keywords); + /* set c */ +#ifndef RSA_USING_ID2KEY + rsa_loadc(tmp_c, keywords); +#else + rsa_loadc(g_acc, keywords); +#endif + + rsa_cal_q(); + + while (!rsa_cal_q_done() && (!rsa_raise_exception())); + + if (!rsa_raise_exception()) { +#if (CONFIG_PLATFORM_HOBBIT1_2 > 0) + ///////////////// FIXME //////////////////////// + if (rsa_run_adjust_sp_if_need(get_old_sp())) { + rsa_run_by_assemble(); + } else { +#endif + rsa_opr_start(); + while ((!rsa_opr_done()) && (rsa_loop_cnt() < MAX_RSA_LP_CNT) && (!rsa_raise_exception())); +#if (CONFIG_PLATFORM_HOBBIT1_2 > 0) + } +#endif + if ((rsa_loop_cnt() >= MAX_RSA_LP_CNT) + || rsa_raise_exception()) { + ret = 1; + } else { + rsa_read_r(out, keywords); + } + } else { + ret = 1; + } + + rsa_opr_reset(); + + return ret; + +} + +static uint32_t get_valid_bits(const uint32_t *addr, uint32_t wordsize, uint32_t keywords) +{ + uint32_t i = 0; + uint32_t j = 0; + + for (i = wordsize; i > 0; i--) { + if (addr[i - 1]) { + break; + } + } + + for (j = keywords; j > 0; j--) { + if (addr[i - 1] & (0x1 << (j - 1))) { + break; + } + } + + return ((i - 1) << 5) + j; +} + +static uint32_t get_first_nonzero_words(uint32_t *a, uint32_t max_words) +{ + uint32_t i = 0; + + for (i = max_words; i > 0; i--) { + if (a[i - 1]) { + return i; + } + } + + return 0; +} + +static uint32_t word_array_left_shift(uint32_t *a, uint32_t words, + uint32_t shift_bits, uint32_t *r) +{ + uint32_t i = 0; + uint32_t w = shift_bits >> 5; + uint32_t b = shift_bits - (w << 5); + + for (i = 0; i < w; i++) { + r[i] = 0; + } + + uint32_t tmp = 0; + + for (i = 0; i < words; i++) { + r[w + i] = (tmp | ((a[i] << b) & (~((0x1 << b) - 1)))); + tmp = ((a[i] >> (32 - b)) & ((0x1 << b) - 1)); + } + + r[w + i] = tmp; + + return 0; +} + +/* r = a - b */ +static uint32_t _word_array_sub(uint32_t *a, uint32_t a_words, + uint32_t *b, uint32_t b_words, + uint32_t *r) +{ + uint32_t i; + uint64_t tmp = 0; + uint32_t borrow = 0; + + for (i = 0; i < b_words; i++) { + tmp = UINT32_TO_UINT64(a[i]) - UINT32_TO_UINT64(b[i]) - UINT32_TO_UINT64(borrow); + r[i] = UINT64L_TO_UINT32(tmp); + borrow = ((UINT64H_TO_UINT32(tmp) == 0) ? (0) : (0xffffffff - UINT64H_TO_UINT32(tmp) + 1)); + } + + for (i = b_words; i < a_words; i++) { + tmp = UINT32_TO_UINT64(a[i]) - UINT32_TO_UINT64(borrow); + r[i] = UINT64L_TO_UINT32(tmp); + borrow = ((UINT64H_TO_UINT32(tmp) == 0) ? (0) : (0xffffffff - UINT64H_TO_UINT32(tmp) + 1)); + } + + if (borrow) { + return -1; + } + + return 0; +} + +static uint32_t word_array_mod(uint32_t *a, uint32_t a_words, + uint32_t *b, uint32_t b_words, + uint32_t *r, uint32_t keywords) +{ + uint32_t ret; + bignum_t tmpa; + bignum_t tmpb; + + memset(&tmpa, 0, sizeof(tmpa)); + memset(&tmpb, 0, sizeof(tmpa)); + + uint32_t b_valid_bits = get_valid_bits(b, b_words, keywords); + + memcpy(tmpa.pdata, a, (a_words << 2)); + + do { + uint32_t tmpa_words = get_first_nonzero_words(tmpa.pdata, a_words); + uint32_t tmpa_valid_bits = get_valid_bits(tmpa.pdata, tmpa_words, keywords); + + if (tmpa_valid_bits > b_valid_bits + 1) { + memset(tmpb.pdata, 0, (a_words << 2)); + word_array_left_shift(b, b_words, tmpa_valid_bits - b_valid_bits - 1, + tmpb.pdata); + uint32_t tmpb_words = get_first_nonzero_words(tmpb.pdata, a_words); + ret = _word_array_sub(tmpa.pdata, tmpa_words, tmpb.pdata, tmpb_words, tmpa.pdata); + } else if (tmpa_words == b_words) { + memcpy(r, tmpa.pdata, (tmpa_words << 2)); + ret = _word_array_sub(r, tmpa_words, b, b_words, tmpa.pdata); + } else { + ret = _word_array_sub(tmpa.pdata, tmpa_words, b, b_words, tmpa.pdata); + } + } while (ret == 0); + + return 0; +} + +static uint32_t sw_exptmod_2_2m(const uint32_t *modulus, uint32_t words, uint32_t *tmp_c) +{ + bignum_t tmp; + + memset(&tmp, 0, sizeof(bignum_t)); + + uint32_t m_valid_bits = (words << 5); + + uint32_t data1 = 0x1; + word_array_left_shift(&data1, 1, (m_valid_bits << 1), tmp.pdata); + tmp.words = get_first_nonzero_words(tmp.pdata, words * 2 + 1); + + uint32_t ret = word_array_mod(tmp.pdata, tmp.words, + (uint32_t *)modulus, words, tmp_c, words); + + if (ret != 0) { + return ret; + } + + return 0; +} + +static void convert_byte_array(uint8_t *in, uint8_t *out, uint32_t len) +{ + uint32_t idx, round = len >> 1; + + for (idx = 0; idx < round; idx++) { + uint8_t tmp = *(in + idx); + *(out + idx) = *(in + len - 1 - idx); + *(out + len - 1 - idx) = tmp; + } + + if (len & 0x1) { + *(out + round) = *(in + round); + } +} + +static void convert_buf_to_bndata(const uint8_t *src, uint32_t src_bytes, + uint32_t *dst, uint32_t dst_words) +{ + memset(dst, 0, dst_words << 2); + convert_byte_array((uint8_t *)src, (uint8_t *)dst, src_bytes); +} + +static void convert_bndata_to_buf(const uint32_t *src, uint32_t src_words, + uint8_t *dst, uint32_t dst_bytes) +{ + memset(dst, 0, dst_bytes); + convert_byte_array((uint8_t *)src, (uint8_t *)dst, dst_bytes); +} + +static const uint8_t der_sha256_t[] = { + 0x30, 0x31, + 0x30, 0x0d, + 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */ + 0x05, 0x00, + 0x04, 0x20 +}; + +static const uint8_t der_sha1_t[] = { + 0x30, 0x21, + 0x30, 0x09, + 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x05, 0x00, + 0x04, 0x14 +}; + +static const uint8_t der_md5_t[] = { + 0x30, 0x20, /* type Sequence, length 0x20 (32) */ + 0x30, 0x0c, /* type Sequence, length 0x09 */ + 0x06, 0x08, /* type OID, length 0x05 */ + 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */ + 0x05, 0x00, /* NULL */ + 0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */ +}; + +static uint32_t rsa_padding_pkcs(uint8_t *dgst, + uint8_t *out, + uint32_t type, + uint32_t keybytes) + +{ + uint32_t i; + uint8_t *p; + uint8_t *der; + uint32_t der_len; + uint32_t hashlen; + uint32_t pslen; + + if (type == MD5_PADDING) { + der = (uint8_t *)der_md5_t; + der_len = sizeof(der_md5_t); + hashlen = MD5_HASH_SZ; + } else if (type == SHA256_PADDING) { + der = (uint8_t *)der_sha256_t; + der_len = sizeof(der_sha256_t); + hashlen = SHA256_HASH_SZ; + } else { + der = (uint8_t *)der_sha1_t; + der_len = sizeof(der_sha1_t); + hashlen = SHA1_HASH_SZ; + } + + p = (uint8_t *)out; + + *(p++) = 0x00; + *(p++) = 0x01; + + /* pad out with 0xff data */ + pslen = keybytes - 3 - der_len - hashlen; + + for (i = 0; i < pslen; i++) { + p[i] = 0xff; /* PS */ + } + + p += pslen; + *(p++) = 0x0; + + for (i = 0; i < der_len; i++) { + p[i] = der[i]; + } + + p += der_len; + + for (i = 0; i < hashlen; i++) { + p[i] = dgst[i]; + } + + return 0; +} + +static uint32_t rsa_checking_pkcs(uint8_t *dgst, + uint8_t *in, + uint32_t inlen, + uint8_t *is_valid, + uint32_t type, + uint32_t keybytes) +{ + uint32_t i; + uint32_t ret; + const uint8_t *p; + uint8_t *der = NULL; + uint32_t der_len = 0; + uint32_t hashlen = 0; + uint32_t pslen; + + if (type == MD5_PADDING) { + der = (uint8_t *)der_md5_t; + der_len = sizeof(der_md5_t); + hashlen = MD5_HASH_SZ; + } else if (type == SHA1_PADDING) { + der = (uint8_t *)der_sha1_t; + der_len = sizeof(der_sha1_t); + hashlen = SHA1_HASH_SZ; + } else if (type == SHA256_PADDING) { + der = (uint8_t *)der_sha256_t; + der_len = sizeof(der_sha256_t); + hashlen = SHA256_HASH_SZ; + } + + *is_valid = 0; + + pslen = keybytes - 3 - der_len - hashlen; + p = in; + p++; + + if (*(p) != 0x01) { + ret = -1; + goto _verify_fail; + } + + p++; + + /* scan PS */ + for (i = 0; i < pslen; i++) { + if (*(p + i) != 0xff) { + ret = -2; + goto _verify_fail; + } + } + + p += pslen; + + if ((*p) != 0x00) { + ret = -1; + goto _verify_fail; + } + + p++; + + /* scan t */ + for (i = 0; i < der_len; i++) { + if (*(p + i) != der[i]) { + ret = -3; + goto _verify_fail; + } + } + + p += der_len; + + for (i = 0; i < hashlen; i++) { + if (*(p + i) != dgst[i]) { + ret = -4; + goto _verify_fail; + } + } + + *is_valid = 1; + ret = 0; + +_verify_fail: + + return ret; +} + +static uint32_t rsa_padding_es_pkcs(uint8_t *dgst, + uint32_t dgstlen, + uint8_t *out, + uint32_t padding, + uint32_t keybytes) + +{ + uint32_t i; + uint8_t *p; + uint32_t pslen; + + p = (uint8_t *)out; + + *(p++) = 0x00; + *(p++) = 0x02; + + /* pad out with 0xff data */ + pslen = keybytes - 3 - dgstlen; + + for (i = 0; i < pslen; i++) { + p[i] = 0xff; /* PS */ + } + + p += pslen; + *(p++) = 0x0; + + for (i = 0; i < dgstlen; i++) { + p[i] = dgst[i]; + } + + return 0; +} + +static uint32_t rsa_checking_es_pkcs(uint8_t *out, + uint32_t *out_size, + uint8_t *src, + uint32_t src_size, + uint32_t padding, + uint32_t keybytes) +{ + uint32_t i; + uint8_t *p; + uint8_t *p_src; + uint32_t pslen; + + p = (uint8_t *)src; + p_src = p; + *(p++) = 0x00; + + if (padding == PKCS1_PADDING) { + if (*(p++) != 0x02) { + return -1; + } + } else { + if (*(p++) != 0x01) { + return -2; + } + } + + pslen = src_size - 2; + + while (pslen--) { + if (*(p++) == 0x0) { + break; + } + } + + if (padding == PKCS1_PADDING) { + *out_size = pslen; + } else { + *out_size = keybytes; + } + + for (i = 0; i < *out_size; i++) { + if (padding == PKCS1_PADDING) { + out[i] = p[i]; + } else { + out[i] = p_src[i]; + } + } + + return 0; +} + +int rsa_encrypt(uint8_t *n, uint8_t *e, + uint8_t *src, uint32_t src_size, + uint8_t *out, uint32_t *out_size, + uint32_t padding, uint32_t keybits_len, + uint32_t *tmp_c) +{ + uint32_t ret; + uint32_t tmp_n[RSA_KEY_WORD]; + uint32_t tmp_e[RSA_KEY_WORD]; + uint32_t tmp_in_out[RSA_KEY_WORD]; + uint32_t keywords = 0, keybytes = 0; + + keywords = GET_KEY_WORD(keybits_len); + keybytes = GET_KEY_BYTE(keybits_len); + + convert_buf_to_bndata(n, keybytes, tmp_n, keywords); + convert_buf_to_bndata(e, keybytes, tmp_e, keywords); + + if (padding == PKCS1_PADDING) { + ret = rsa_padding_es_pkcs(src, + src_size, + (uint8_t *)tmp_in_out, + padding, + keybytes); + + if (ret != 0) { + return ret; + } + + convert_byte_array((uint8_t *)tmp_in_out, (uint8_t *)tmp_in_out, keybytes); + } else { + convert_byte_array((uint8_t *)src, (uint8_t *)tmp_in_out, keybytes); + } + + ret = rsa_exptmod(tmp_n, tmp_e, tmp_in_out, tmp_in_out, keywords, tmp_c); + + if (ret != 0) { + return ret; + } + + convert_bndata_to_buf(tmp_in_out, keywords, out, keybytes); + *out_size = keybytes; + return ret; +} + +int rsa_decrypt(uint8_t *n, uint8_t *d, + uint8_t *src, uint32_t src_size, + uint8_t *out, uint32_t *out_size, + uint32_t padding, uint32_t keybits_len, + uint32_t *tmp_c) +{ + uint32_t ret; + uint32_t tmp_n[RSA_KEY_WORD]; + uint32_t tmp_d[RSA_KEY_WORD]; + uint32_t tmp_in_out[RSA_KEY_WORD]; + uint32_t keywords = 0, keybytes = 0; + + keywords = GET_KEY_WORD(keybits_len); + keybytes = GET_KEY_BYTE(keybits_len); + + convert_buf_to_bndata(n, keybytes, tmp_n, keywords); + convert_buf_to_bndata(d, keybytes, tmp_d, keywords); + convert_buf_to_bndata(src, src_size, tmp_in_out, keywords); + + ret = rsa_exptmod(tmp_n, tmp_d, tmp_in_out, tmp_in_out, keywords, tmp_c); + + if (ret != 0) { + return ret; + } + + convert_byte_array((uint8_t *)tmp_in_out, (uint8_t *)tmp_in_out, keybytes); + + ret = rsa_checking_es_pkcs(out, + out_size, + (uint8_t *)tmp_in_out, + keybytes, + padding, + keybytes); + + return ret; +} + +int rsa_sign(uint8_t *n, uint8_t *d, + uint8_t *src, uint32_t src_size, + uint8_t *signature, uint32_t *sig_size, + uint32_t type, uint32_t keybits_len, + uint32_t *tmp_c) +{ + uint32_t ret; + uint32_t tmp_n[RSA_KEY_WORD]; + uint32_t tmp_d[RSA_KEY_WORD]; + uint32_t tmp_in_out[RSA_KEY_WORD]; + + uint32_t keywords = 0, keybytes = 0; + + keywords = GET_KEY_WORD(keybits_len); + keybytes = GET_KEY_BYTE(keybits_len); + + convert_buf_to_bndata(n, keybytes, tmp_n, keywords); + convert_buf_to_bndata(d, keybytes, tmp_d, keywords); + + ret = rsa_padding_pkcs(src, + (uint8_t *)tmp_in_out, + type, + keybytes); + + if (ret != 0) { + return ret; + } + + convert_byte_array((uint8_t *)tmp_in_out, (uint8_t *)tmp_in_out, keybytes); + + ret = rsa_exptmod(tmp_n, tmp_d, tmp_in_out, tmp_in_out, keywords, tmp_c); + + if (ret != 0) { + return ret; + } + + convert_bndata_to_buf(tmp_in_out, keywords, signature, keybytes); + *sig_size = keybytes; + + return 0; +} + +int rsa_verify(uint8_t *n, uint8_t *e, + uint8_t *src, uint32_t src_size, + uint8_t *signature, uint32_t sig_size, + uint32_t type, uint32_t keybits_len, + uint8_t *result, uint32_t *tmp_c) +{ + uint32_t ret; + uint32_t tmp_n[RSA_KEY_WORD]; + uint32_t tmp_e[RSA_KEY_WORD]; + uint32_t tmp_in_out[RSA_KEY_WORD]; + uint32_t keywords = 0, keybytes = 0; + + *result = 0; + + keywords = GET_KEY_WORD(keybits_len); + keybytes = GET_KEY_BYTE(keybits_len); + + convert_buf_to_bndata(n, keybytes, tmp_n, keywords); + convert_buf_to_bndata(e, keybytes, tmp_e, keywords); + convert_buf_to_bndata(signature, sig_size, tmp_in_out, keywords); + + ret = rsa_exptmod(tmp_n, tmp_e, tmp_in_out, tmp_in_out, keywords, tmp_c); + + if (ret != 0) { + return ret; + } + + convert_byte_array((uint8_t *)tmp_in_out, (uint8_t *)tmp_in_out, keybytes); + + ret = rsa_checking_pkcs(src, + (uint8_t *)tmp_in_out, + keybytes, + result, + type, + keybytes); + + return ret; +} + +static int rsa_sw_exptmod_2_2m(uint8_t *modulus, uint32_t keybits_len, uint32_t *tmp_c) +{ + uint32_t keywords = 0, keybytes = 0; + uint32_t tmp_n[RSA_KEY_WORD]; + + keywords = GET_KEY_WORD(keybits_len); + keybytes = GET_KEY_BYTE(keybits_len); + + convert_buf_to_bndata(modulus, keybytes, tmp_n, keywords); + + sw_exptmod_2_2m(tmp_n, keywords, tmp_c); + return 0; +} + +int rsa_sw_calc_modulus(uint8_t *modulus, uint32_t keybits_len) +{ +#ifdef RSA_USING_ID2KEY + static uint32_t current_keybits_len; + + if (current_keybits_len != keybits_len) { + rsa_sw_exptmod_2_2m((uint8_t *)modulus, keybits_len, g_acc); + current_keybits_len = keybits_len; + } + +#endif + return 0; +} + +/** + \brief get rsa handle count. + \return rsa handle count +*/ +int32_t csi_rsa_get_instance_count(void) +{ + return target_get_rsa_count(); +} + +/** + \brief Initialize RSA Interface. 1. Initializes the resources needed for the RSA interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_rsa_get_instance_count() + \param[in] cb_event Pointer to \ref rsa_event_cb_t + \return pointer to rsa handle +*/ +rsa_handle_t csi_rsa_initialize(int32_t idx, rsa_event_cb_t cb_event) +{ + if (idx < 0 || idx >= CONFIG_RSA_NUM) { + return NULL; + } + + /* obtain the rsa information */ + uint32_t base = 0u; + uint32_t irq; + int32_t real_idx = target_get_rsa(idx, &base, &irq); + + if (real_idx != idx) { + return NULL; + } + + ck_rsa_priv_t *rsa_priv = &rsa_handle[idx]; + + rsa_priv->base = base; + rsa_priv->irq = irq; + + /* initialize the rsa context */ + rsa_priv->cb = cb_event; + rsa_priv->data_bit = RSA_DATA_BITS_1024; + rsa_priv->endian = RSA_ENDIAN_MODE_LITTLE; + rsa_priv->padding.padding_type = RSA_PADDING_MODE_PKCS1; + rsa_priv->padding.hash_type = RSA_HASH_TYPE_SHA1; + rsa_priv->status.busy = 0; + +#ifdef RSA_USING_ID2KEY + memset(g_acc, 0x0, sizeof(g_acc)); +#endif + + return (rsa_handle_t)rsa_priv; +} + +/** + \brief De-initialize RSA Interface. stops operation and releases the software resources used by the interface + \param[in] handle rsa handle to operate. + \return error code +*/ +int32_t csi_rsa_uninitialize(rsa_handle_t handle) +{ + RSA_NULL_PARAM_CHK(handle); + + ck_rsa_priv_t *rsa_priv = handle; + rsa_priv->cb = NULL; + + return 0; +} + +/** + \brief Get driver capabilities. + \param[in] handle rsa handle to operate. + \return \ref rsa_capabilities_t +*/ +rsa_capabilities_t csi_rsa_get_capabilities(rsa_handle_t handle) +{ + return driver_capabilities; +} + +/** + \brief config rsa mode. + \param[in] handle rsa handle to operate. + \param[in] data_bits \ref rsa_data_bits_e + \param[in] endian \ref rsa_endian_mode_e + \return error code +*/ +int32_t csi_rsa_config(rsa_handle_t handle, + rsa_data_bits_e data_bits, + rsa_endian_mode_e endian, + void *arg + ) +{ + RSA_NULL_PARAM_CHK(handle); + + ck_rsa_priv_t *rsa_priv = handle; + rsa_reg = (ck_rsa_reg_t *)(rsa_priv->base); + + /* config the data bits */ + switch (data_bits) { + case RSA_DATA_BITS_192: + case RSA_DATA_BITS_256: + case RSA_DATA_BITS_512: + return ERR_RSA(EDRV_UNSUPPORTED); + + case RSA_DATA_BITS_1024: + case RSA_DATA_BITS_2048: + rsa_priv->data_bit = data_bits; + break; + + default: + return ERR_RSA(EDRV_PARAMETER); + } + + /* config the endian mode */ + if (endian == RSA_ENDIAN_MODE_LITTLE) { + rsa_priv->endian = endian; + } else if (endian == RSA_ENDIAN_MODE_BIG) { + return ERR_RSA(EDRV_UNSUPPORTED); + } else { + return ERR_RSA(EDRV_PARAMETER); + } + + if (arg != NULL) { +#ifdef RSA_USING_ID2KEY + uint32_t keybits_len = 1024; + + if (data_bits == RSA_DATA_BITS_2048) { + keybits_len = 2048; + } + + rsa_sw_calc_modulus(arg, keybits_len); +#else + //memcpy(g_acc, arg, sizeof(g_acc)); +#endif + } + + return 0; +} + +/** + \brief encrypt + \param[in] handle rsa handle to operate. + \param[in] n Pointer to the public modulus + \param[in] e Pointer to the public exponent + \param[in] src Pointer to the source data. + \param[in] src_size the source data len + \param[out] out Pointer to the result buffer + \param[out] out_size the result size + \param[in] padding \ref rsa_padding_t + \return error code +*/ +int32_t csi_rsa_encrypt(rsa_handle_t handle, void *n, void *e, void *src, int32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding) +{ +#ifndef RSA_USING_ID2KEY + uint32_t tmp_c[RSA_KEY_WORD]; +#endif + RSA_NULL_PARAM_CHK(handle); + RSA_NULL_PARAM_CHK(n); + RSA_NULL_PARAM_CHK(e); + RSA_NULL_PARAM_CHK(src); + RSA_NULL_PARAM_CHK(out); + RSA_NULL_PARAM_CHK(out_size); + + if (src_size <= 0 || (padding.padding_type != RSA_PADDING_MODE_PKCS1 && padding.padding_type != RSA_PADDING_MODE_NO)) { + return ERR_RSA(EDRV_PARAMETER); + } + + ck_rsa_priv_t *rsa_priv = handle; + rsa_priv->status.busy = 1U; + + uint32_t bit_length = 1024; + + if (rsa_priv->data_bit == RSA_DATA_BITS_2048) { + bit_length = 2048; + } + +#ifndef RSA_USING_ID2KEY + rsa_sw_exptmod_2_2m(n, bit_length, tmp_c); +#endif + + rsa_encrypt((uint8_t *)n, (uint8_t *)e, (uint8_t *)src, (uint32_t)src_size, (uint8_t *)out, (uint32_t *)out_size, (uint32_t)(padding.padding_type), bit_length, tmp_c); + rsa_priv->status.busy = 0U; + + if (rsa_priv->cb) { + rsa_priv->cb(RSA_EVENT_ENCRYPT_COMPLETE); + } + + return 0; +} + +/** + \brief decrypt + \param[in] handle rsa handle to operate. + \param[in] n Pointer to the public modulus + \param[in] d Pointer to the privte exponent + \param[in] src Pointer to the source data. + \param[in] src_size the source data len + \param[out] out Pointer to the result buffer + \param[out] out_size the result size + \param[in] padding \ref rsa_padding_t + \return error code +*/ +int32_t csi_rsa_decrypt(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding) +{ +#ifndef RSA_USING_ID2KEY + uint32_t tmp_c[RSA_KEY_WORD]; +#endif + RSA_NULL_PARAM_CHK(handle); + RSA_NULL_PARAM_CHK(n); + RSA_NULL_PARAM_CHK(d); + RSA_NULL_PARAM_CHK(src); + RSA_NULL_PARAM_CHK(out); + RSA_NULL_PARAM_CHK(out_size); + + if (src_size <= 0 || (padding.padding_type != RSA_PADDING_MODE_PKCS1 && padding.padding_type != RSA_PADDING_MODE_NO)) { + return ERR_RSA(EDRV_PARAMETER); + } + + ck_rsa_priv_t *rsa_priv = handle; + rsa_priv->status.busy = 1U; + + uint32_t bit_length = 1024; + + if (rsa_priv->data_bit == RSA_DATA_BITS_2048) { + bit_length = 2048; + } + +#ifndef RSA_USING_ID2KEY + rsa_sw_exptmod_2_2m(n, bit_length, tmp_c); +#endif + + rsa_decrypt((uint8_t *)n, (uint8_t *)d, (uint8_t *)src, (uint32_t)src_size, (uint8_t *)out, (uint32_t *)out_size, (uint32_t)(padding.padding_type), bit_length, tmp_c); + rsa_priv->status.busy = 0U; + + if (rsa_priv->cb) { + rsa_priv->cb(RSA_EVENT_DECRYPT_COMPLETE); + } + + return 0; +} + +/** + \brief rsa sign + \param[in] handle rsa handle to operate. + \param[in] n Pointer to the public modulus + \param[in] d Pointer to the privte exponent + \param[in] src Pointer to the source data. + \param[in] src_size the source data len + \param[out] signature Pointer to the signature + \param[out] sig_size the signature size + \param[in] padding \ref rsa_padding_t + \return error code +*/ +int32_t csi_rsa_sign(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *signature, void *sig_size, rsa_padding_t padding) +{ +#ifndef RSA_USING_ID2KEY + uint32_t tmp_c[RSA_KEY_WORD]; +#endif + RSA_NULL_PARAM_CHK(handle); + RSA_NULL_PARAM_CHK(n); + RSA_NULL_PARAM_CHK(d); + RSA_NULL_PARAM_CHK(src); + RSA_NULL_PARAM_CHK(signature); + RSA_NULL_PARAM_CHK(sig_size); + + if (src_size <= 0 || (padding.hash_type != RSA_HASH_TYPE_MD5 + && padding.hash_type != RSA_HASH_TYPE_SHA1 + && padding.hash_type != RSA_HASH_TYPE_SHA256)) { + return ERR_RSA(EDRV_PARAMETER); + } + + ck_rsa_priv_t *rsa_priv = handle; + rsa_priv->status.busy = 1U; + uint32_t bit_length = 1024; + + if (rsa_priv->data_bit == RSA_DATA_BITS_2048) { + bit_length = 2048; + } + +#ifndef RSA_USING_ID2KEY + rsa_sw_exptmod_2_2m(n, bit_length, tmp_c); +#endif + + rsa_sign((uint8_t *)n, (uint8_t *)d, (uint8_t *)src, (uint32_t)src_size, (uint8_t *)signature, (uint32_t *)sig_size, (uint32_t)(padding.hash_type), bit_length, tmp_c); + rsa_priv->status.busy = 0U; + + if (rsa_priv->cb) { + rsa_priv->cb(RSA_EVENT_SIGN_COMPLETE); + } + + return 0; +} + +/** + \brief rsa verify + \param[in] handle rsa handle to operate. + \param[in] n Pointer to the public modulus + \param[in] e Pointer to the public exponent + \param[in] src Pointer to the source data. + \param[in] src_size the source data len + \param[in] signature Pointer to the signature + \param[in] sig_size the signature size + \param[out] result Pointer to the result + \param[in] padding \ref rsa_padding_t + \return error code +*/ +int32_t csi_rsa_verify(rsa_handle_t handle, void *n, void *e, void *src, uint32_t src_size, void *signature, uint32_t sig_size, void *result, rsa_padding_t padding) +{ +#ifndef RSA_USING_ID2KEY + uint32_t tmp_c[RSA_KEY_WORD]; +#endif + RSA_NULL_PARAM_CHK(handle); + RSA_NULL_PARAM_CHK(n); + RSA_NULL_PARAM_CHK(e); + RSA_NULL_PARAM_CHK(src); + RSA_NULL_PARAM_CHK(signature); + RSA_NULL_PARAM_CHK(result); + + if (src_size <= 0 || sig_size <= 0 || (padding.hash_type != RSA_HASH_TYPE_MD5 && padding.hash_type != RSA_HASH_TYPE_SHA1 && padding.hash_type != RSA_HASH_TYPE_SHA256)) { + return ERR_RSA(EDRV_PARAMETER); + } + + ck_rsa_priv_t *rsa_priv = handle; + rsa_priv->status.busy = 1U; + + uint32_t bit_length = 1024; + + if (rsa_priv->data_bit == RSA_DATA_BITS_2048) { + bit_length = 2048; + } + +#ifndef RSA_USING_ID2KEY + rsa_sw_exptmod_2_2m(n, bit_length, tmp_c); +#endif + + rsa_verify((uint8_t *)n, (uint8_t *)e, (uint8_t *)src, (uint32_t)src_size, (uint8_t *)signature, sig_size, (uint32_t)(padding.hash_type), bit_length, (uint8_t *)result, tmp_c); + rsa_priv->status.busy = 0U; + + if (rsa_priv->cb) { + rsa_priv->cb(RSA_EVENT_VERIFY_COMPLETE); + } + + return 0; +} + +/** + \brief Get RSA status. + \param[in] handle rsa handle to operate. + \return RSA status \ref rsa_status_t +*/ +rsa_status_t csi_rsa_get_status(rsa_handle_t handle) +{ + ck_rsa_priv_t *rsa_priv = handle; + return rsa_priv->status; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/rsa/ck_rsa.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/rsa/ck_rsa.h new file mode 100644 index 000000000..1ae03c9aa --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/rsa/ck_rsa.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file ck_rsa.h + * @brief header file for rsa driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CK_RSA_H_ +#define _CK_RSA_H_ + +#include +#include "drv_rsa.h" +#include "soc.h" + +#define RSA_KEY_LEN 2048 +#define RSA_KEY_BYTE (RSA_KEY_LEN >> 3) +#define RSA_KEY_WORD (RSA_KEY_LEN >> 5) + +#define BN_MAX_BITS ((RSA_KEY_LEN << 1) + 32) +#define BN_MAX_BYTES ((BN_MAX_BITS + 7) >> 3) +#define BN_MAX_WORDS ((BN_MAX_BYTES + 3) >> 2) + +#define MAX_RSA_LP_CNT 10000 + +#define GET_KEY_BYTE(k) (k >> 3) +#define GET_KEY_WORD(k) (k >> 5) + +#define UINT32_TO_UINT64(data) ((uint64_t)(((uint64_t)(data)) & 0x00000000ffffffffU)) +#define UINT64L_TO_UINT32(data) ((uint32_t)(((uint64_t)(data)) & 0x00000000ffffffffU)) +#define UINT64H_TO_UINT32(data) ((uint32_t)((((uint64_t)(data)) >> 32) & 0x00000000ffffffffU)) + +#define PKCS1_PADDING 0x01 +#define NO_PADDING 0x02 + +#define MD5_PADDING 0x00 +#define SHA1_PADDING 0x01 +#define SHA256_PADDING 0x03 + +#define MD5_HASH_SZ 16 +#define SHA1_HASH_SZ 20 +#define SHA256_HASH_SZ 32 + +#define RAS_CALCULATE_Q 0x6 +#define RSA_ENABLE_MODULE 0x3 +#define RSA_ENDIAN_MODE 0x8 +#define RSA_RESET 0x1 +#define RSA_CAL_Q_DONE_OFFSET 0x5 + +typedef struct bignum { + uint32_t pdata[BN_MAX_WORDS]; + uint32_t words; +} bignum_t; + +typedef struct { + __IOM uint32_t rsa_mwid; /* Offset: 0x000 (R/W) Width of M register */ + __IOM uint32_t rsa_ckid; /* Offset: 0x004 (R/W) Width of D register */ + __IOM uint32_t rsa_bwid; /* Offset: 0x008 (R/W) Width of B register */ + __IOM uint32_t rsa_ctrl; /* Offset: 0x00c (R/W) RSA control register */ + __OM uint32_t rsa_rst; /* Offset: 0x010 (W) RSA reset register */ + __IM uint32_t rsa_lp_cnt; /* Offset: 0x014 (R) Loop counter for inquiry register*/ + __IM uint32_t rsa_q0; /* Offset: 0x018 (R) High-radix MM algorithm assistant register,part 1*/ + __IM uint32_t rsa_q1; /* Offset: 0x01c (R) High-radix MM algorithm assistant register,part 2*/ + __IOM uint32_t rsa_isr; /* Offset: 0x020 (W/R) Interrupt raw status register */ + __IOM uint32_t rsa_imr; /* Offset: 0x024 (W/R) Interrupt mask register */ + __IOM uint32_t rev1[54]; /* Reserve regiser */ + __IOM uint32_t rsa_rfm; /* Offset: 0x100 (W/R) Register file for modulus M */ + __IOM uint32_t rev2[63]; /* Reserve regiser */ + __IOM uint32_t rsa_rfd; /* Offset: 0x200 (W/R) Register file for exponent D */ + __IOM uint32_t rev3[63]; /* Reserve regiser */ + __IOM uint32_t rsa_rfc; /* Offset: 0x300 (W/R) Register file for hard C */ + __IOM uint32_t rev4[63]; /* Reserve regiser */ + __IOM uint32_t rsa_rfb; /* Offset: 0x400 (W/R) Register file for data B */ + __IOM uint32_t rev5[63]; /* Reserve regiser */ + __IM uint32_t rsa_rfr; /* Offset: 0x500 (R) Register file for storing the result */ +} ck_rsa_reg_t; + +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/Kconfig b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/Kconfig new file mode 100644 index 000000000..78c2a1fce --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/Kconfig @@ -0,0 +1,20 @@ +choice + prompt "select sha type " + help + select sha type +config SHA_CK_V2 + bool "csky v2 sha" + help + select the ck sha driver + +config SHA_CK_V1 + bool "csky v1 sha" + help + select the ck sha driver + +config SHA_ZX29 + bool "csky zx29 sha" + help + select the zx29 sha driver + +endchoice diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v1.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v1.c new file mode 100644 index 000000000..66fbf097e --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v1.c @@ -0,0 +1,559 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file ck_sha.c + * @brief CSI Source File for SHA Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include +#include +#include "csi_core.h" +#include "drv_sha.h" +#include "ck_sha_v1.h" + +#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD +#define CONFIG_SHA_SUPPORT_MUL_THREAD 1 +#endif + +typedef struct { + uint32_t base; + uint32_t irq; + sha_event_cb_t cb; + sha_status_t status; + sha_mode_e mode; + sha_endian_mode_e endian; +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + uint32_t state[16]; + uint32_t sha_buffer[32]; + uint32_t total; + uint8_t first_cal; +#endif +} ck_sha_priv_t; + +#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD +static ck_sha_priv_t sha_handle[CONFIG_SHA_NUM]; +#endif +bool finish_flag = 0; + +/* Driver Capabilities */ +static const sha_capabilities_t driver_capabilities = { + .sha1 = 1, /* sha1 mode */ + .sha224 = 1, /* sha224 mode */ + .sha256 = 1, /* sha256 mode */ + .sha384 = 1, /* sha384 mode */ + .sha512 = 1, /* sha512 mode */ + .sha512_224 = 1, /* sha512_224 mode */ + .sha512_256 = 1, /* sha512_256 mode */ + .endianmode = 1, /* endian mode */ + .interruptmode = 1 /* interrupt mode */ +}; + +#define ERR_SHA(errno) (CSI_DRV_ERRNO_SHA_BASE | errno) +#define SHA_NULL_PARAM_CHK(para) \ + do { \ + if (para == NULL) { \ + return ERR_SHA(EDRV_PARAMETER); \ + } \ + } while (0) + +extern int32_t target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq); +extern int32_t target_get_sha_count(void); +// +// Functions +// + +ck_sha_reg_t *sha_reg = NULL; + +#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD +static uint32_t sha_buffer[32]; +static uint32_t total[2] = {0x0}; +static uint8_t first_cal = 1; +#endif +static uint8_t sha_result[64] = {0x0}; + +static int32_t sha_set_mode(sha_mode_e mode) +{ + sha_reg->SHA_MODE &= ~0x7; + sha_reg->SHA_MODE |= mode; + return 0; +} + +static void sha_set_source_message(uint32_t baseaddr) +{ + sha_reg->SHA_BASEADDR = baseaddr; +} + +static void sha_set_dest_message(uint32_t destaddr) +{ + sha_reg->SHA_DESTADDR = destaddr; +} + +static void sha_enable_without_count(void) +{ + sha_reg->SHA_MODE |= 1<<25; +} + +static void sha_disable_without_count(void) +{ + sha_reg->SHA_MODE &= ~(1<<25); +} + +static void sha_set_message_count(uint32_t count) +{ + sha_reg->SHA_COUNTER0 = count; + sha_reg->SHA_COUNTER1 = 0; +} + +static int32_t sha_enable_initial(void) +{ + sha_reg->SHA_MODE |= 1 << SHA_INIT_OFFSET; + return 0; +} + +static int32_t sha_disable_initial(void) +{ + sha_reg->SHA_MODE &= ~(1 << SHA_INIT_OFFSET); + return 0; +} + +static int32_t sha_enable_calculate(void) +{ + sha_reg->SHA_CON |= 1; + return 0; +} + +static int32_t sha_message_done(void) +{ + while(sha_reg->SHA_CON & 0x1); + return 0; +} + +static void sha_new_encode(void) +{ + sha_reg->SHA_INTSTATE = 0; + sha_reg->SHA_MODE = 0; +} + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD +static int32_t sha_restore_context(sha_handle_t handle, uint32_t *data) +{ + uint32_t *result = (uint32_t *)&sha_reg->SHA_H0L; + + uint8_t i; + for (i = 0; i < 16; i++) { + result[i] = data[i]; + } + return 0; +} + +static int32_t sha_save_context(sha_handle_t handle, uint32_t *data) +{ + uint32_t *result = (uint32_t *)&sha_reg->SHA_H0L; + + uint8_t i; + for (i = 0; i < 16; i++) { + data[i] = result[i]; + } + return 0; +} +#endif + +static inline void sha_reverse_order(uint8_t *pdata, int32_t length) +{ + uint8_t input_data[length]; + uint8_t result[length]; + uint32_t tmp = 0; + int32_t i = 0; + memcpy((void *)input_data, (void *)pdata, length); + + for (i = 0; i < length; i++) { + tmp = i >> 2; + tmp = tmp << 3; + result[i] = input_data[tmp + 3 - i]; + } + + memcpy((void *)pdata, (void *)result, length); +} + +/** + \brief get sha handle count. + \return sha handle count +*/ +int32_t csi_sha_get_instance_count(void) +{ + return target_get_sha_count(); +} + +/** + \brief Initialize SHA Interface. 1. Initializes the resources needed for the SHA interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_sha_get_instance_count() + \param[in] cb_event Pointer to \ref sha_event_cb_t + \return return sha handle if success +*/ +sha_handle_t csi_sha_initialize(sha_handle_t handle, sha_event_cb_t cb_event) +{ +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + uint32_t base = 0u; + uint32_t irq; + /* obtain the sha information */ + target_get_sha(0, &base, &irq); + ck_sha_priv_t *sha_priv = handle; + memset(sha_priv->state, 0, sizeof(sha_priv->state)); + sha_priv->total = 0; + sha_priv->first_cal = 1; + +#else + if (idx < 0 || idx >= CONFIG_SHA_NUM) { + return NULL; + } + + uint32_t base = 0u; + uint32_t irq; + /* obtain the sha information */ + int32_t real_idx = target_get_sha(idx, &base, &irq); + + if (real_idx != idx) { + return NULL; + } + ck_sha_priv_t *sha_priv = &sha_handle[idx]; +#endif + sha_priv->base = base; + sha_priv->irq = irq; + + /* initialize the sha context */ + sha_priv->cb = cb_event; + sha_priv->status.busy = 0; + + return (sha_handle_t)sha_priv; +} + +/** + \brief De-initialize SHA Interface. stops operation and releases the software resources used by the interface + \param[in] handle sha handle to operate. + \return error code +*/ +int32_t csi_sha_uninitialize(sha_handle_t handle) +{ + SHA_NULL_PARAM_CHK(handle); + + ck_sha_priv_t *sha_priv = handle; + sha_priv->cb = NULL; + + return 0; +} + +/** + \brief Get driver capabilities. + \param[in] handle sha handle to operate. + \return \ref sha_capabilities_t +*/ +sha_capabilities_t csi_sha_get_capabilities(sha_handle_t handle) +{ + return driver_capabilities; +} + +/** + \brief config sha mode. + \param[in] handle sha handle to operate. + \param[in] mode \ref sha_mode_e + \param[in] endian \ref sha_endian_mode_e + \return error code +*/ +int32_t csi_sha_config(sha_handle_t handle, sha_mode_e mode, sha_endian_mode_e endian_mode) +{ + SHA_NULL_PARAM_CHK(handle); + + ck_sha_priv_t *sha_priv = handle; + sha_reg = (ck_sha_reg_t *)(sha_priv->base); + + /* config the sha mode */ + switch (mode) { + case SHA_MODE_512_256: + case SHA_MODE_512_224: + return ERR_SHA(EDRV_UNSUPPORTED); + + case SHA_MODE_1: + case SHA_MODE_224: + case SHA_MODE_256: + case SHA_MODE_384: + case SHA_MODE_512: + sha_priv->mode = mode; + break; + + default: + return ERR_SHA(EDRV_PARAMETER); + } + + return 0; +} + +/** + \brief start the engine + \param[in] handle sha handle to operate. + \param[in] context Pointer to the sha context. + \return error code +*/ +int32_t csi_sha_starts(sha_handle_t handle, void *context) +{ + SHA_NULL_PARAM_CHK(handle); + + ck_sha_priv_t *sha_priv = handle; + sha_priv->status.busy = 1; + + sha_new_encode(); + sha_set_mode(sha_priv->mode); + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + memset(sha_priv->sha_buffer, 0, sizeof(sha_priv->sha_buffer)); + memset(sha_priv->state, 0, sizeof(sha_priv->state)); + sha_priv->first_cal = 1; + sha_priv->total = 0; +#endif + + return 0; +} + +/** + \brief updata the engine + \param[in] handle sha handle to operate. + \param[in] context Pointer to the sha context. + \param[in] input Pointer to the Source data + \param[in] len the data len + \return error code +*/ +int32_t csi_sha_update(sha_handle_t handle, void *context, const void *input, uint32_t len) +{ + SHA_NULL_PARAM_CHK(handle); + SHA_NULL_PARAM_CHK(input); + if (len <= 0) { + return ERR_SHA(EDRV_PARAMETER); + } + + ck_sha_priv_t *sha_priv = handle; + sha_reg = (ck_sha_reg_t *)(sha_priv->base); + + uint8_t total_len_num; + uint32_t block_size; + if (sha_priv->mode < 4) { + block_size = 64; + total_len_num = 2; + } else { + block_size = 128; + total_len_num = 4; + } + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + uint32_t *sha_buffer = sha_priv->sha_buffer; + uint8_t first_cal = sha_priv->first_cal; + sha_set_mode(sha_priv->mode); + uint32_t left = sha_priv->total & (block_size - 1); + uint32_t fill = block_size - left; + uint32_t total_length = sha_priv->total << 3; + uint32_t index = left >> 2; + + if (left & 0x3) { + index++; + } + sha_priv->total += len; + sha_priv->total &= 0xffffffff; +#else + uint32_t left = total[0] & (block_size - 1); + uint32_t fill = block_size - left; + uint32_t total_length = total[0] << 3; + uint32_t index = left >> 2; + + if (left & 0x3) { + index++; + } + total[0] += len; + total[0] &= 0xffffffff; +#endif + uint8_t *p = (uint8_t *)input; + /* when the text is not aligned by block and len > fill */ + if (left && len >= fill) { + if (finish_flag) { +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + memset(((uint8_t *)sha_buffer + left), 0x0, sizeof(sha_priv->sha_buffer) - left); +#else + memset(((uint8_t *)sha_buffer + left), 0x0, sizeof(sha_buffer) - left); +#endif + sha_buffer[index + total_len_num - 1] = total_length; + + sha_disable_without_count(); + sha_set_message_count(left << 3); + } else { + memcpy((void *)(((uint8_t *)sha_buffer) + left), p, fill); + p += fill; + + sha_enable_without_count(); + sha_set_message_count(block_size << 3); + } + + sha_set_source_message((uint32_t)sha_buffer); + sha_set_dest_message((uint32_t)sha_result); + if (first_cal == 0) { + sha_enable_initial(); + } else { + sha_disable_initial(); + } + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_restore_context(handle, (uint32_t *)sha_priv->state); +#endif + + sha_enable_calculate(); + sha_message_done(); + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_save_context(handle, (uint32_t *)sha_priv->state); +#endif + len -= fill; + left = 0; +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_priv->first_cal = 0; + first_cal = 0; +#else + first_cal = 0; +#endif + } + + /* calculate the hash by block */ + while (len >= block_size) { + if (finish_flag) { +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + memset(sha_buffer, 0, sizeof(sha_priv->sha_buffer)); +#else + memset(sha_buffer, 0, sizeof(sha_buffer)); +#endif + sha_buffer[total_len_num - 1] = total_length; + + sha_set_source_message((uint32_t)sha_buffer); + sha_disable_without_count(); + sha_set_message_count(0); + } else { + memcpy(sha_buffer, p, block_size); + sha_set_source_message((uint32_t)sha_buffer); + sha_enable_without_count(); + sha_set_message_count(block_size << 3); + p += block_size; + } + sha_set_dest_message((uint32_t)sha_result); + if (first_cal == 0) { + sha_enable_initial(); + } else { + sha_disable_initial(); + } +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_restore_context(handle, (uint32_t *)sha_priv->state); +#endif + + sha_enable_calculate(); + sha_message_done(); +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_save_context(handle, (uint32_t *)sha_priv->state); +#endif +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_priv->first_cal = 0; + first_cal = 0; +#else + first_cal = 0; +#endif + len -= block_size; + } + + /* when the text is not aligned by block and len < fill */ + if (len > 0) { + memcpy((void *)(((uint8_t *)sha_buffer) + left), p, len); + } + + sha_priv->status.busy = 0; + + return 0; +} + +/** + \brief finish the engine + \param[in] handle sha handle to operate. + \param[in] context Pointer to the sha context. + \param[out] output Pointer to the dest data + \return error code +*/ +int32_t csi_sha_finish(sha_handle_t handle, void *context, void *output) +{ + SHA_NULL_PARAM_CHK(handle); + SHA_NULL_PARAM_CHK(output); + + ck_sha_priv_t *sha_priv = handle; + uint32_t block_size; + if (sha_priv->mode < 4) { + block_size = 64; + } else { + block_size = 128; + } + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + uint32_t last = sha_priv->total & (block_size - 1); +#else + uint32_t last = total[0] & (block_size - 1); +#endif + uint32_t padn = block_size - last; + + finish_flag = 1; + + csi_sha_update(handle, NULL, output, padn); + + uint8_t result_len = 20; + /* convert the data endian according the sha mode */ + if (sha_priv->mode == SHA_MODE_1) { + result_len = 20; + } else if (sha_priv->mode == SHA_MODE_224) { + result_len = 28; + } else if (sha_priv->mode == SHA_MODE_256) { + result_len = 32; + } else if (sha_priv->mode == SHA_MODE_512) { + result_len = 64; + } else if (sha_priv->mode == SHA_MODE_384) { + result_len = 48; + } + sha_reverse_order(sha_result, result_len); + memcpy((uint8_t*)output, sha_result, result_len); + + finish_flag = 0; +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + memset(sha_priv->sha_buffer, 0, sizeof(sha_priv->sha_buffer)); + sha_priv->first_cal = 1; + sha_priv->total = 0; +#else + memset(sha_buffer, 0, sizeof(sha_buffer)); + first_cal = 1; + total[0] = 0; +#endif + return 0; +} + +/** + \brief Get SHA status. + \param[in] handle sha handle to operate. + \return SHA status \ref sha_status_t +*/ +sha_status_t csi_sha_get_status(sha_handle_t handle) +{ + ck_sha_priv_t *sha_priv = handle; + return sha_priv->status; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v1.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v1.h new file mode 100644 index 000000000..bb9d0ebc3 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v1.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file ck_sha.h + * @brief header file for sha driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CK_SHA_H_ +#define _CK_SHA_H_ + +#include +#include "drv_sha.h" +#include "soc.h" + +#define SHA_INIT_OFFSET 3 +#define SHA_INT_ENABLE_OFFSET 4 +#define SHA_ENDIAN_OFFSET 5 +#define SHA_CAL_OFFSET 6 +typedef struct { + __IOM uint32_t SHA_CON; /* Offset: 0x000 (R/W) Control register */ + __IOM uint32_t SHA_MODE; /* Offset: 0x004 (R/W) Mode register */ + __IOM uint32_t SHA_INTSTATE; /* Offset: 0x008 (R/W) Instatus register */ + __IOM uint32_t SHA_BASEADDR; /* Offset: 0x00c (R/W) Baseaddr register */ + __IOM uint32_t SHA_DESTADDR; /* Offset: 0x010 (R/W) Dest addr register */ + __IOM uint32_t SHA_COUNTER0; /* Offset: 0x014 (R/W) count0 register */ + __IOM uint32_t SHA_COUNTER1; /* Offset: 0x018 (R/W) count1 register */ + __IOM uint32_t SHA_COUNTER2; /* Offset: 0x01c (R/W) count2 register */ + __IOM uint32_t SHA_COUNTER3; /* Offset: 0x020 (R/W) count3 register */ + __IOM uint32_t SHA_H0L; /* Offset: 0x024 (R/W) H0L register */ + __IOM uint32_t SHA_H1L; /* Offset: 0x028 (R/W) H1L register */ + __IOM uint32_t SHA_H2L; /* Offset: 0x02c (R/W) H2L register */ + __IOM uint32_t SHA_H3L; /* Offset: 0x030 (R/W) H3L register */ + __IOM uint32_t SHA_H4L; /* Offset: 0x034 (R/W) H4L register */ + __IOM uint32_t SHA_H5L; /* Offset: 0x038 (R/W) H5L register */ + __IOM uint32_t SHA_H6L; /* Offset: 0x03c (R/W) H6L register */ + __IOM uint32_t SHA_H7L; /* Offset: 0x040 (R/W) H7L register */ + __IOM uint32_t SHA_H0H; /* Offset: 0x044 (R/W) H0H register */ + __IOM uint32_t SHA_H1H; /* Offset: 0x048 (R/W) H1H register */ + __IOM uint32_t SHA_H2H; /* Offset: 0x04c (R/W) H2H register */ + __IOM uint32_t SHA_H3H; /* Offset: 0x050 (R/W) H3H register */ + __IOM uint32_t SHA_H4H; /* Offset: 0x054 (R/W) H4H register */ + __IOM uint32_t SHA_H5H; /* Offset: 0x058 (R/W) H5H register */ + __IOM uint32_t SHA_H6H; /* Offset: 0x05c (R/W) H6H register */ + __IOM uint32_t SHA_H7H; /* Offset: 0x060 (R/W) H7H register */ +} ck_sha_reg_t; + +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v2.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v2.c new file mode 100644 index 000000000..9c8b142b8 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v2.c @@ -0,0 +1,700 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file ck_sha.c + * @brief CSI Source File for SHA Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include +#include +#include "csi_core.h" +#include "drv_sha.h" +#include "ck_sha_v2.h" + +#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD +#define CONFIG_SHA_SUPPORT_MUL_THREAD 1 +#endif + +typedef struct { + uint32_t base; + uint32_t irq; + sha_event_cb_t cb; + sha_status_t status; + sha_mode_e mode; + sha_endian_mode_e endian; +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + uint8_t state[64]; + uint8_t sha_buffer[128]; + uint32_t total; + uint32_t last_left; +#endif +} ck_sha_priv_t; + +#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD +static ck_sha_priv_t sha_handle[CONFIG_SHA_NUM]; +#endif +static uint32_t g_sha_context[CONFIG_SHA_NUM]; +bool finish_flag = 0; + +/* Driver Capabilities */ +static const sha_capabilities_t driver_capabilities = { + .sha1 = 1, /* sha1 mode */ + .sha224 = 1, /* sha224 mode */ + .sha256 = 1, /* sha256 mode */ + .sha384 = 1, /* sha384 mode */ + .sha512 = 1, /* sha512 mode */ + .sha512_224 = 1, /* sha512_224 mode */ + .sha512_256 = 1, /* sha512_256 mode */ + .endianmode = 1, /* endian mode */ + .interruptmode = 1 /* interrupt mode */ +}; + +#define ERR_SHA(errno) (CSI_DRV_ERRNO_SHA_BASE | errno) +#define SHA_NULL_PARAM_CHK(para) \ + do { \ + if (para == NULL) { \ + return ERR_SHA(EDRV_PARAMETER); \ + } \ + } while (0) +// +// Functions +// + +ck_sha_reg_t *sha_reg = NULL; +volatile static uint8_t sha_int_flag = 1; + +extern int32_t target_get_sha_count(void); +extern int32_t target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq); + +static int32_t sha_set_mode(sha_mode_e mode) +{ + sha_reg->SHA_CON &= ~0x7; + sha_reg->SHA_CON |= mode; + return 0; +} + +#ifndef CONFIG_SHA_BLOCK_MODE +static int32_t sha_enable_interrupt(void) +{ + sha_reg->SHA_CON |= 1 << SHA_INT_ENABLE_OFFSET; + return 0; +} + +#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD +static int32_t sha_disable_interrupt(void) +{ + sha_reg->SHA_CON &= ~(1 << SHA_INT_ENABLE_OFFSET); + return 0; +} +#endif +#endif + +static void sha_clear_interrupt(void) +{ + sha_reg->SHA_INTSTATE = 0; +} + +static int32_t sha_enable_initial(void) +{ + sha_reg->SHA_CON |= 1 << SHA_INIT_OFFSET; + return 0; +} + +static int32_t sha_enable_calculate(void) +{ + sha_reg->SHA_CON |= 1 << SHA_CAL_OFFSET; + return 0; +} + +#ifdef CONFIG_SHA_BLOCK_MODE +static int32_t sha_message_done(void) +{ + while((sha_reg->SHA_CON & 0x40)); + return 0; +} +#endif + +static int32_t sha_select_endian_mode(sha_endian_mode_e mode) +{ + sha_reg->SHA_CON &= ~(1 << SHA_ENDIAN_OFFSET); + sha_reg->SHA_CON |= mode << SHA_ENDIAN_OFFSET; + return 0; +} + +static int32_t sha_input_data(uint32_t *data, uint32_t length) +{ + uint8_t i; + uint32_t tmp; + uint32_t *input_data = (uint32_t *) & (sha_reg->SHA_DATA1); + + for (i = 0; i < length; i++) { + memcpy(&tmp, (uint8_t *)(data+i), 4); + *(input_data + i) = tmp; + } + + return 0; +} + +static int32_t sha_get_data(sha_handle_t handle, uint32_t *data) +{ + ck_sha_priv_t *sha_priv = handle; + + uint8_t len = 0; + uint8_t i; + uint32_t temp; + uint32_t *result = (uint32_t *)&sha_reg->SHA_H0L; + /* according to different mode to obtain the hash result */ + if (sha_priv->mode == SHA_MODE_1 || sha_priv->mode == SHA_MODE_224 || sha_priv->mode == SHA_MODE_256) { + if (sha_priv->mode == SHA_MODE_1) { + len = 5; + } else if (sha_priv->mode == SHA_MODE_224) { + len = 7; + } else if (sha_priv->mode == SHA_MODE_256) { + len = 8; + } + + for (i = 0; i < len; i++) { + temp = *(result + i); + memcpy(&data[i], &temp, 4); + } + } else { + if (sha_priv->mode == SHA_MODE_384) { + len = 6; + } else if (sha_priv->mode == SHA_MODE_512) { + len = 8; + } + + uint32_t *resulth = (uint32_t *)&sha_reg->SHA_H0H; + for (i = 0; i < len; i++) { +// data[i << 1] = *(resulth + i); +// data[(i << 1) + 1] = *(result + i); + temp = *(resulth + i); + memcpy(&data[i<<1], &temp, 4); + temp = *(result + i); + memcpy(&data[(i<<1)+1], &temp, 4); + } + } + + return 0; +} + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD +static int32_t sha_set_data(sha_handle_t handle, uint32_t *data) +{ + ck_sha_priv_t *sha_priv = handle; + + uint8_t len = 0; + uint8_t i; + uint32_t *result = (uint32_t *)&sha_reg->SHA_H0L; + /* according to different mode to obtain the hash result */ + if (sha_priv->mode == SHA_MODE_1 || sha_priv->mode == SHA_MODE_224 || sha_priv->mode == SHA_MODE_256) { + if (sha_priv->mode == SHA_MODE_1) { + len = 5; + } else if (sha_priv->mode == SHA_MODE_224) { + len = 7; + } else if (sha_priv->mode == SHA_MODE_256) { + len = 8; + } + + for (i = 0; i < len; i++) { + *(result + i) = data[i]; + } + } else { + if (sha_priv->mode == SHA_MODE_384) { + len = 6; + } else if (sha_priv->mode == SHA_MODE_512) { + len = 8; + } + + uint32_t *resulth = (uint32_t *)&sha_reg->SHA_H0H; + for (i = 0; i < len; i++) { + *(resulth + i) = data[i << 1]; + *(result + i) = data[(i << 1) + 1] ; + } + } + + return 0; +} +#endif + +static inline void sha_reverse_order(uint8_t *pdata, int32_t length) +{ + uint8_t input_data[length]; + uint8_t result[length]; + uint32_t tmp = 0; + int32_t i = 0; + memcpy((void *)input_data, (void *)pdata, length); + + for (i = 0; i < length; i++) { + tmp = i >> 2; + tmp = tmp << 3; + result[i] = input_data[tmp + 3 - i]; + } + + memcpy((void *)pdata, (void *)result, length); +} + +void ck_sha_irqhandler(int32_t idx) +{ + sha_int_flag = 0; + sha_clear_interrupt(); //clear sha interrupt + +#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD + ck_sha_priv_t *sha_priv = &sha_handle[idx]; +#else + ck_sha_priv_t *sha_priv = (ck_sha_priv_t *)g_sha_context[idx]; +#endif + if (finish_flag != 0) { + if (sha_priv->cb != NULL) { + sha_priv->cb(SHA_EVENT_COMPLETE); //execute the callback function + } + } +} + +/** + \brief get sha handle count. + \return sha handle count +*/ +int32_t csi_sha_get_instance_count(void) +{ + return target_get_sha_count(); +} + +/** + \brief Initialize SHA Interface. 1. Initializes the resources needed for the SHA interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_sha_get_instance_count() + \param[in] cb_event Pointer to \ref sha_event_cb_t + \return return sha handle if success +*/ +sha_handle_t csi_sha_initialize(sha_handle_t handle, sha_event_cb_t cb_event) +{ + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + uint32_t base = 0u; + uint32_t irq; + /* obtain the sha information */ + target_get_sha(0, &base, &irq); + ck_sha_priv_t *sha_priv = handle; + memset(sha_priv->state, 0, sizeof(sha_priv->state)); + sha_priv->last_left = 0; + sha_priv->total = 0; + g_sha_context[0] = (uint32_t)handle; +#else + if (idx < 0 || idx >= CONFIG_SHA_NUM) { + return NULL; + } + + uint32_t base = 0u; + uint32_t irq; + /* obtain the sha information */ + int32_t real_idx = target_get_sha(idx, &base, &irq); + + if (real_idx != idx) { + return NULL; + } + ck_sha_priv_t *sha_priv = &sha_handle[idx]; +#endif + sha_priv->base = base; + sha_priv->irq = irq; + + /* initialize the sha context */ + sha_priv->cb = cb_event; + sha_priv->status.busy = 0; + +#ifndef CONFIG_SHA_BLOCK_MODE + drv_nvic_enable_irq(sha_priv->irq); +#endif + + return (sha_handle_t)sha_priv; +} + +/** + \brief De-initialize SHA Interface. stops operation and releases the software resources used by the interface + \param[in] handle sha handle to operate. + \return error code +*/ +int32_t csi_sha_uninitialize(sha_handle_t handle) +{ + SHA_NULL_PARAM_CHK(handle); + + ck_sha_priv_t *sha_priv = handle; + sha_priv->cb = NULL; + +#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD +#ifndef CONFIG_SHA_BLOCK_MODE + sha_disable_interrupt(); + drv_nvic_disable_irq(sha_priv->irq); +#endif +#endif + + return 0; +} + +/** + \brief Get driver capabilities. + \param[in] handle sha handle to operate. + \return \ref sha_capabilities_t +*/ +sha_capabilities_t csi_sha_get_capabilities(sha_handle_t handle) +{ + return driver_capabilities; +} + +/** + \brief config sha mode. + \param[in] handle sha handle to operate. + \param[in] mode \ref sha_mode_e + \param[in] endian \ref sha_endian_mode_e + \return error code +*/ +int32_t csi_sha_config(sha_handle_t handle, sha_mode_e mode, sha_endian_mode_e endian_mode) +{ + SHA_NULL_PARAM_CHK(handle); + + ck_sha_priv_t *sha_priv = handle; + sha_reg = (ck_sha_reg_t *)(sha_priv->base); + + /* config the sha mode */ + switch (mode) { + case SHA_MODE_512_256: + case SHA_MODE_512_224: + return ERR_SHA(EDRV_UNSUPPORTED); + + case SHA_MODE_1: + case SHA_MODE_224: + case SHA_MODE_256: + case SHA_MODE_384: + case SHA_MODE_512: + sha_priv->mode = mode; + break; + + default: + return ERR_SHA(EDRV_PARAMETER); + } + + sha_set_mode(mode); + + /*config the sha endian mode */ + if (endian_mode == SHA_ENDIAN_MODE_LITTLE) { + sha_priv->endian = endian_mode; + sha_select_endian_mode(endian_mode); + } else if (endian_mode == SHA_ENDIAN_MODE_BIG) { + sha_priv->endian = endian_mode; + sha_select_endian_mode(endian_mode); + } else { + return ERR_SHA(EDRV_PARAMETER); + } + +#ifndef CONFIG_SHA_BLOCK_MODE + sha_enable_interrupt(); +#endif + + return 0; +} + +/** + \brief start the engine + \param[in] handle sha handle to operate. + \param[in] context Pointer to the sha context. + \return error code +*/ +int32_t csi_sha_starts(sha_handle_t handle, void *context) +{ + SHA_NULL_PARAM_CHK(handle); + + ck_sha_priv_t *sha_priv = handle; + sha_enable_initial(); + sha_priv->status.busy = 1; + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_get_data(handle, (uint32_t *)sha_priv->state); +#endif + + return 0; +} + +/** + \brief updata the engine + \param[in] handle sha handle to operate. + \param[in] context Pointer to the sha context. + \param[in] input Pointer to the Source data + \param[in] len the data len + \return error code +*/ +#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD +static uint8_t sha_buffer[128]; +static uint32_t total[2] = {0x0}; +static uint32_t last_left = 0; +#endif +int32_t csi_sha_update(sha_handle_t handle, void *context, const void *input, uint32_t len) +{ + SHA_NULL_PARAM_CHK(handle); + SHA_NULL_PARAM_CHK(input); + if (len <= 0) { + return ERR_SHA(EDRV_PARAMETER); + } + g_sha_context[0] = (uint32_t)handle; + ck_sha_priv_t *sha_priv = handle; + sha_reg = (ck_sha_reg_t *)(sha_priv->base); + + uint32_t block_size; + if (sha_priv->mode < 4) { + block_size = 64; + } else { + block_size = 128; + } + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + uint8_t *sha_buffer = sha_priv->sha_buffer; + uint32_t last_left = sha_priv->last_left; + sha_set_mode(sha_priv->mode); + uint32_t left = sha_priv->total & (block_size - 1); + uint32_t fill = block_size - left; + uint32_t total_length = sha_priv->total << 3; + + sha_priv->total += len; + sha_priv->total &= 0xffffffff; + uint32_t word_left = sha_priv->total & 0x3; +#else + uint32_t left = total[0] & (block_size - 1); + uint32_t fill = block_size - left; + uint32_t total_length = total[0] << 3; + + total[0] += len; + total[0] &= 0xffffffff; + uint32_t word_left = total[0] & 0x3; +#endif + uint8_t temp_data[4]; + uint32_t j; + if (finish_flag) { + /*calculate the final word*/ + for (j = 0; j < 4; j++) { + temp_data[j] = (total_length >> (8 * j)) & 0xff; + } + } + + uint8_t *p = (uint8_t *)input; + /* when the text is not aligned by block and len > fill */ + if (left && len >= fill) { + if (finish_flag) { + if (sha_priv->endian == SHA_ENDIAN_MODE_BIG) { + memset(&sha_buffer[left], 0x0, len); + sha_buffer[left] = 0x80; + for (j=0; j<4; j++) { + sha_buffer[left + len - 4 + j] = temp_data[3 - j]; + } + } else { + memset(&sha_buffer[left + 4 - last_left], 0x0, len - 4 + last_left); + sha_buffer[left - last_left + 3 - last_left] = 0x80; + for (j = 1; j < 4 - last_left; j++) { + sha_buffer[left - last_left + 3 - last_left - j] = 0x00; + } + for (j=0; j<4; j++) { + sha_buffer[left + len - 4 + j] = temp_data[j]; + } + } + } else { + if (last_left && sha_priv->endian == SHA_ENDIAN_MODE_LITTLE) { + uint32_t i; + for (i = 0; i < 4 - last_left; i++) { + *(sha_buffer + left + 3 - last_left - i) = *((uint8_t *)p + 3 - last_left - i); + } + + fill = fill - 4 + last_left; + p = (p + 4 - last_left); + } + else if (last_left) { + memcpy((void *)(sha_buffer + left + 4 - last_left), p, fill); + } else { + memcpy((void *)(sha_buffer + left), p, fill); + } + p += fill; + } + + /* set the input data */ +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_set_data(handle, (uint32_t *)sha_priv->state); +#endif + sha_input_data((uint32_t *)sha_buffer, block_size >> 2); + sha_enable_calculate(); + +#ifdef CONFIG_SHA_BLOCK_MODE + sha_message_done(); + +#else + while (sha_int_flag); + + sha_int_flag = 1; +#endif + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_get_data(handle, (uint32_t *)sha_priv->state); +#endif + len -= fill; + left = 0; + } else { + if (finish_flag) { +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + memset(sha_buffer, 0, sizeof(sha_priv->sha_buffer)); +#else + memset(sha_buffer, 0, sizeof(sha_buffer)); +#endif + if (sha_priv->endian == SHA_ENDIAN_MODE_BIG) { + sha_buffer[0] = 0x80; + for (j = 0; j < 4; j++) { + sha_buffer[block_size - 4 + j] = temp_data[3 - j]; + } + } else { + sha_buffer[3 - last_left] = 0x80; + for (j = 0; j < 4; j++) { + sha_buffer[block_size - 4 + j] = temp_data[j]; + } + } + } + } + + /* calculate the hash by block */ + while (len >= block_size) { +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_set_data(handle, (uint32_t *)sha_priv->state); +#endif + if (finish_flag) { + if (fill == block_size) { + sha_input_data((uint32_t *)sha_buffer, block_size >> 2); + } else { + sha_input_data((uint32_t *)&sha_buffer[block_size], block_size >> 2); + } + } + else { + sha_input_data((uint32_t *)p, block_size >> 2); + p += block_size; + } + sha_enable_calculate(); + +#ifdef CONFIG_SHA_BLOCK_MODE + sha_message_done(); + +#else + while (sha_int_flag); + + sha_int_flag = 1; +#endif + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_get_data(handle, (uint32_t *)sha_priv->state); +#endif + len -= block_size; + } + + /* when the text is not aligned by block and len < fill */ + if (len > 0) { + if (sha_priv->endian == SHA_ENDIAN_MODE_BIG || word_left == 0) { + memcpy((void *)(sha_buffer + left), p, len); + } else { + memcpy((void *)(sha_buffer + left), p, len + 4 - word_left); +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_priv->last_left = word_left; +#else + last_left = word_left; +#endif + } + } + + sha_priv->status.busy = 0; + + return 0; +} + +/** + \brief finish the engine + \param[in] handle sha handle to operate. + \param[in] context Pointer to the sha context. + \param[out] output Pointer to the dest data + \return error code +*/ +//static uint32_t total_length; +int32_t csi_sha_finish(sha_handle_t handle, void *context, void *output) +{ + SHA_NULL_PARAM_CHK(handle); + SHA_NULL_PARAM_CHK(output); + + ck_sha_priv_t *sha_priv = handle; + uint32_t block_size; + uint8_t message_len; + if (sha_priv->mode < 4) { + block_size = 64; + message_len = 8; + } else { + block_size = 128; + message_len = 16; + } + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + uint32_t last = sha_priv->total & (block_size - 1); + uint32_t padn = (last < (block_size - message_len)) ? (block_size - last) : (block_size + block_size - last); + +#else + uint32_t last = total[0] & (block_size - 1); + uint32_t padn = (last < (block_size - message_len)) ? (block_size - last) : (block_size + block_size - last); + +#endif + + finish_flag = 1; + + csi_sha_update(handle, NULL, output, padn); + + /* get the hash result */ + sha_get_data(handle, (uint32_t *)output); + + uint8_t *p = output; + /* convert the data endian according the sha mode */ + if (sha_priv->mode == SHA_MODE_1) { + sha_reverse_order(p, 20); + } else if (sha_priv->mode == SHA_MODE_224) { + sha_reverse_order(p, 28); + } else if (sha_priv->mode == SHA_MODE_256) { + sha_reverse_order(p, 32); + } else if (sha_priv->mode == SHA_MODE_512) { + sha_reverse_order(p, 64); + } else if (sha_priv->mode == SHA_MODE_384) { + sha_reverse_order(p, 48); + } + +#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD + sha_priv->total = 0; + sha_priv->last_left = 0; +#else + total[0] = 0; + last_left = 0; +#endif + finish_flag = 0; + + return 0; +} + +/** + \brief Get SHA status. + \param[in] handle sha handle to operate. + \return SHA status \ref sha_status_t +*/ +sha_status_t csi_sha_get_status(sha_handle_t handle) +{ + ck_sha_priv_t *sha_priv = handle; + return sha_priv->status; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v2.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v2.h new file mode 100644 index 000000000..c6fea6438 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/sha/ck_sha_v2.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file ck_sha.h + * @brief header file for sha driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CK_SHA_H_ +#define _CK_SHA_H_ + +#include +#include "drv_sha.h" +#include "soc.h" + +#define SHA_INIT_OFFSET 3 +#define SHA_INT_ENABLE_OFFSET 4 +#define SHA_ENDIAN_OFFSET 5 +#define SHA_CAL_OFFSET 6 +typedef struct { + __IOM uint32_t SHA_CON; /* Offset: 0x000 (R/W) Control register */ + __IOM uint32_t SHA_INTSTATE; /* Offset: 0x004 (R/W) Instatus register */ + __IOM uint32_t SHA_H0L; /* Offset: 0x008 (R/W) H0L register */ + __IOM uint32_t SHA_H1L; /* Offset: 0x00c (R/W) H1L register */ + __IOM uint32_t SHA_H2L; /* Offset: 0x010 (R/W) H2L register */ + __IOM uint32_t SHA_H3L; /* Offset: 0x014 (R/W) H3L register */ + __IOM uint32_t SHA_H4L; /* Offset: 0x018 (R/W) H4L register */ + __IOM uint32_t SHA_H5L; /* Offset: 0x01c (R/W) H5L register */ + __IOM uint32_t SHA_H6L; /* Offset: 0x020 (R/W) H6L register */ + __IOM uint32_t SHA_H7L; /* Offset: 0x024 (R/W) H7L register */ + __IOM uint32_t SHA_H0H; /* Offset: 0x028 (R/W) H0H register */ + __IOM uint32_t SHA_H1H; /* Offset: 0x02c (R/W) H1H register */ + __IOM uint32_t SHA_H2H; /* Offset: 0x030 (R/W) H2H register */ + __IOM uint32_t SHA_H3H; /* Offset: 0x034 (R/W) H3H register */ + __IOM uint32_t SHA_H4H; /* Offset: 0x038 (R/W) H4H register */ + __IOM uint32_t SHA_H5H; /* Offset: 0x03c (R/W) H5H register */ + __IOM uint32_t SHA_H6H; /* Offset: 0x040 (R/W) H6H register */ + __IOM uint32_t SHA_H7H; /* Offset: 0x044 (R/W) H7H register */ + __IOM uint32_t SHA_DATA1; /* Offset: 0x048 (R/W) DATA1 register */ + uint32_t REV[15]; + __IOM uint32_t SHA_DATA2; /* Offset: 0x088 (R/W) DATA2 register */ +} ck_sha_reg_t; +#endif + +typedef enum { + SHA_STATUS_START_END = 0, /* the one time count mode */ + SHA_STATUS_START = 1, /* the first time of the cal */ + SHA_STATUS_CONTINUE = 2, /* the middle stage of the cal */ + SHA_STATUS_END = 3 /* the last time of the cal*/ +} enum_sha_status; diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/Kconfig b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/Kconfig new file mode 100644 index 000000000..b7e48231f --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/Kconfig @@ -0,0 +1,20 @@ +choice + prompt "select trng type " + help + select trng type +config TRNG_CK + bool "csky trng" + help + select the ck trng driver + +config TRNG_ZX29 + bool "zx29 trng" + help + select the zx29 trng driver + +config TRNG_XX + bool "example trng" + help + this option for test + +endchoice diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/ck_trng.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/ck_trng.c new file mode 100644 index 000000000..33be9eff1 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/ck_trng.c @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file ck_trng.c + * @brief CSI Source File for TRNG Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include +#include +#include "drv_trng.h" +#include "ck_trng.h" + + +#define ERR_TRNG(errno) (CSI_DRV_ERRNO_TRNG_BASE | errno) +#define TRNG_NULL_PARAM_CHK(para) \ + do { \ + if (para == NULL) { \ + return ERR_TRNG(EDRV_PARAMETER); \ + } \ + } while (0) + +typedef struct { + uint32_t base; + trng_event_cb_t cb; + trng_status_t status; +} ck_trng_priv_t; + +extern int32_t target_get_trng_count(void); +extern int32_t target_get_trng(int32_t idx, uint32_t *base); + +static ck_trng_priv_t trng_handle[CONFIG_TRNG_NUM]; + +/* Driver Capabilities */ +static const trng_capabilities_t driver_capabilities = { + .lowper_mode = 1 /* low power mode */ +}; + +extern int32_t target_get_trng(int32_t idx, uint32_t *base); +extern int32_t target_get_trng_count(void); +// +// Functions +// + +ck_trng_reg_t *trng_reg = NULL; + +static int32_t trng_enable(void) +{ + trng_reg->TCR |= TRNG_EN; + return 0; +} + +static int32_t trng_get_data(void) +{ + int data = trng_reg->TDR; + return data; +} + +static int32_t trng_data_is_ready(void) +{ + int flag = (trng_reg->TCR & TRNG_DATA_READY); + return flag; +} + +/** + \brief get trng handle count. + \return trng handle count +*/ +int32_t csi_trng_get_instance_count(void) +{ + return target_get_trng_count(); +} + +/** + \brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_trng_get_instance_count() + \param[in] cb_event Pointer to \ref trng_event_cb_t + \return pointer to trng handle +*/ +trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event) +{ + + if (idx < 0 || idx >= CONFIG_TRNG_NUM) { + return NULL; + } + + /* obtain the trng information */ + uint32_t base = 0u; + int32_t real_idx = target_get_trng(idx, &base); + + if (real_idx != idx) { + return NULL; + } + + ck_trng_priv_t *trng_priv = &trng_handle[idx]; + trng_priv->base = base; + + /* initialize the trng context */ + trng_reg = (ck_trng_reg_t *)(trng_priv->base); + trng_priv->cb = cb_event; + trng_priv->status.busy = 0; + trng_priv->status.data_valid = 0; + + return (trng_handle_t)trng_priv; +} + +/** + \brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface + \param[in] handle trng handle to operate. + \return error code +*/ +int32_t csi_trng_uninitialize(trng_handle_t handle) +{ + TRNG_NULL_PARAM_CHK(handle); + + ck_trng_priv_t *trng_priv = handle; + trng_priv->cb = NULL; + + return 0; +} + +/** + \brief Get driver capabilities. + \param[in] trng handle to operate. + \return \ref trng_capabilities_t +*/ +trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle) +{ + return driver_capabilities; +} + +/** + \brief Get data from the TRNG. + \param[in] handle trng handle to operate. + \param[out] data Pointer to buffer with data get from TRNG + \param[in] num Number of data items to obtain + \return error code +*/ +int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num) +{ + TRNG_NULL_PARAM_CHK(handle); + TRNG_NULL_PARAM_CHK(data); + TRNG_NULL_PARAM_CHK(num); + + ck_trng_priv_t *trng_priv = handle; + + trng_priv->status.busy = 1U; + trng_priv->status.data_valid = 0U; + + uint8_t left_len = (uint32_t)data & 0x3; + uint32_t result = 0; + + /* if the data addr is not aligned by word */ + if (left_len) { + trng_enable(); + while (!trng_data_is_ready()); + result = trng_get_data(); + /* wait the data is ready */ + while (trng_data_is_ready()); + + if (num > (4 - left_len)) { + memcpy(data, &result, 4 - left_len); + } else { + memcpy(data, &result, num); + trng_priv->status.busy = 0U; + trng_priv->status.data_valid = 1U; + + if (trng_priv->cb) { + trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE); + } + return 0; + } + num -= (4 - left_len); + data += (4 - left_len); + } + + uint32_t word_len = num >> 2; + left_len = num & 0x3; + + /* obtain the data by word */ + while (word_len--) { + trng_enable(); + while (!trng_data_is_ready()); + result = trng_get_data(); + while (trng_data_is_ready()); + *(uint32_t *)data = result; + data = (void *)((uint32_t)data + 4); + } + + /* if the num is not aligned by word */ + if (left_len) { + trng_enable(); + while (!trng_data_is_ready()); + result = trng_get_data(); + while (trng_data_is_ready()); + memcpy(data, &result, left_len); + } + + trng_priv->status.busy = 0U; + trng_priv->status.data_valid = 1U; + + if (trng_priv->cb) { + trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE); + } + + return 0; +} + +/** + \brief Get TRNG status. + \param[in] handle trng handle to operate. + \return TRNG status \ref trng_status_t +*/ +trng_status_t csi_trng_get_status(trng_handle_t handle) +{ + ck_trng_priv_t *trng_priv = handle; + return trng_priv->status; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/ck_trng.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/ck_trng.h new file mode 100644 index 000000000..4255cf262 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/ck_trng.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file ck_trng.h + * @brief header file for trng driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CK_TRNG_H_ +#define _CK_TRNG_H_ + +#include "drv_trng.h" +#include "soc.h" + +/* + * define the bits for TCR + */ +#define TRNG_EN (1UL << 1) +#define TRNG_LOWPER_MODE (1UL << 2) +#define TRNG_DATA_READY 1 + +typedef struct { + __IOM uint32_t TCR; /* Offset: 0x000 (W/R) TRNG control register */ + __IM uint32_t TDR; /* Offset: 0x004 (R) TRNG Data register */ + +} ck_trng_reg_t; +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/osr_trng.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/osr_trng.c new file mode 100644 index 000000000..5e1a65563 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/osr_trng.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file osr_trng.c + * @brief CSI Source File for TRNG Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#include +#include +#include +#include "drv_trng.h" +#include "osr_trng.h" + + +#define ERR_TRNG(errno) (CSI_DRV_ERRNO_TRNG_BASE | errno) +#define TRNG_NULL_PARAM_CHK(para) \ + do { \ + if (para == NULL) { \ + return ERR_TRNG(EDRV_PARAMETER); \ + } \ + } while (0) + +typedef struct { + uint32_t base; + uint32_t irq; + trng_event_cb_t cb; + trng_status_t status; +} osr_trng_priv_t; + +extern int32_t target_get_trng(int32_t idx, uint32_t *base, uint32_t *irq); + +static osr_trng_priv_t trng_handle[CONFIG_TRNG_NUM]; + +/* Driver Capabilities */ +static const trng_capabilities_t driver_capabilities = { + .lowper_mode = 0 /* low power mode */ +}; + +// +// Functions +// + +osr_trng_reg_t *trng_reg = NULL; + +static int32_t trng_disable_irq(void) +{ + trng_reg->RBG_CR &= ~TRNG_IRQ_BIT; + return 0; +} + +static int32_t trng_enable(void) +{ + trng_reg->RBG_CR |= TRNG_EN; + return 0; +} + +static int32_t trng_get_data(void) +{ + int data = trng_reg->RBG_DR; + return data; +} + +static int32_t trng_data_is_ready(void) +{ + int flag = (trng_reg->RBG_FIFO_SR & TRNG_DATA_READY); + return flag; +} + +/** + \brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function + \param[in] idx device id + \param[in] cb_event Pointer to \ref trng_event_cb_t + \return pointer to trng handle +*/ +trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event) +{ + + if (idx < 0 || idx >= CONFIG_TRNG_NUM) { + return NULL; + } + + /* obtain the trng information */ + uint32_t base = 0u; + uint32_t irq = 0u; + int32_t real_idx = target_get_trng(idx, &base, &irq); + + if (real_idx != idx) { + return NULL; + } + + osr_trng_priv_t *trng_priv = &trng_handle[idx]; + trng_priv->base = base; + trng_priv->irq = irq; + + /* initialize the trng context */ + trng_reg = (osr_trng_reg_t *)(trng_priv->base); + trng_priv->cb = cb_event; + trng_priv->status.busy = 0; + trng_priv->status.data_valid = 0; + + trng_disable_irq(); + + return (trng_handle_t)trng_priv; +} + +/** + \brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface + \param[in] handle trng handle to operate. + \return error code +*/ +int32_t csi_trng_uninitialize(trng_handle_t handle) +{ + TRNG_NULL_PARAM_CHK(handle); + + osr_trng_priv_t *trng_priv = handle; + trng_priv->cb = NULL; + + return 0; +} + +/** + \brief Get driver capabilities. + \param[in] idx device id. + \return \ref trng_capabilities_t +*/ +//trng_capabilities_t csi_trng_get_capabilities(int32_t idx) +trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle) +{ + /* + if (idx < 0 || idx >= CONFIG_TRNG_NUM) { + trng_capabilities_t ret; + memset(&ret, 0, sizeof(trng_capabilities_t)); + return ret; + }*/ + return driver_capabilities; +} + +/** + \brief Get data from the TRNG. + \param[in] handle trng handle to operate. + \param[out] data Pointer to buffer with data get from TRNG + \param[in] num Number of data items to obtain + \return error code +*/ +int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num) +{ + TRNG_NULL_PARAM_CHK(handle); + TRNG_NULL_PARAM_CHK(data); + TRNG_NULL_PARAM_CHK(num); + + osr_trng_priv_t *trng_priv = handle; + + trng_priv->status.busy = 1U; + trng_priv->status.data_valid = 0U; + + uint8_t left_len = (uint32_t)data & 0x3; + uint32_t result = 0; + + trng_enable(); + /* if the data addr is not aligned by word */ + if (left_len) { + while (!trng_data_is_ready()); + result = trng_get_data(); + + if (num > (4 - left_len)) { + memcpy(data, &result, 4 - left_len); + } else { + memcpy(data, &result, num); + trng_priv->status.busy = 0U; + trng_priv->status.data_valid = 1U; + + if (trng_priv->cb) { + //trng_priv->cb(0, TRNG_EVENT_DATA_GENERATE_COMPLETE); + trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE); + } + return 0; + } + num -= (4 - left_len); + data += (4 - left_len); + } + + uint32_t word_len = num >> 2; + left_len = num & 0x3; + + /* obtain the data by word */ + while (word_len--) { + while (!trng_data_is_ready()); + result = trng_get_data(); + *(uint32_t *)data = result; + data = (void *)((uint32_t)data + 4); + } + + /* if the num is not aligned by word */ + if (left_len) { + while (!trng_data_is_ready()); + result = trng_get_data(); + memcpy(data, &result, left_len); + } + + trng_priv->status.busy = 0U; + trng_priv->status.data_valid = 1U; + + if (trng_priv->cb) { + //trng_priv->cb(0, TRNG_EVENT_DATA_GENERATE_COMPLETE); + trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE); + } + + return 0; +} + +/** + \brief Get TRNG status. + \param[in] handle trng handle to operate. + \return TRNG status \ref trng_status_t +*/ +trng_status_t csi_trng_get_status(trng_handle_t handle) +{ + if (handle == NULL) { + trng_status_t ret; + memset(&ret, 0, sizeof(trng_status_t)); + return ret; + } + osr_trng_priv_t *trng_priv = handle; + return trng_priv->status; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/osr_trng.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/osr_trng.h new file mode 100644 index 000000000..d1fb9f956 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/trng/osr_trng.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file osr_trng.h + * @brief header file for trng driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _OSR_TRNG_H_ +#define _OSR_TRNG_H_ + +#include "drv_trng.h" +#include "soc.h" + +/* + * define the bits for TCR + */ +#define TRNG_EN (1UL << 0) +#define TRNG_DATA_READY (0xff << 16) +#define TRNG_IRQ_BIT (1UL << 24) + +typedef struct { + __IOM uint32_t RBG_CR; /* Offset: 0x000 (W/R) RBG control register */ + __IOM uint32_t RBG_RTCR; /* Offset: 0x004 (W/R) RBG mode selection register */ + __IOM uint32_t RBG_SR; /* Offset: 0x008 (W/R) RBG status register */ + __IM uint32_t RBG_DR; /* Offset: 0x00c ( /R) RBG data register */ + uint32_t Reserved[4]; + __IOM uint32_t RBG_FIFO_CR; /* Offset: 0x020 (W/R) FIFO control register */ + __IM uint32_t RBG_FIFO_SR; /* Offset: 0x024 ( /R) FIFO status register */ +} osr_trng_reg_t; +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/Kconfig b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/Kconfig new file mode 100644 index 000000000..8e3e09630 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/Kconfig @@ -0,0 +1,25 @@ +choice + prompt "select usart type " + help + select usart type +config USART_DW + bool "designware usart" + help + select the dw usart driver + +config USART_CK + bool "csky usart" + help + select the ck usart driver + +config USART_SILAN + bool "silan usart" + help + select the silan usart driver + +config USART_ZX29 + bool "zx29 usart" + help + select the zx29 usart driver +endchoice + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/ck_usart.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/ck_usart.c new file mode 100644 index 000000000..4abd8e779 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/ck_usart.c @@ -0,0 +1,710 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file ck_usart.c + * @brief CSI Source File for usart Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include "csi_core.h" +#include "drv_usart.h" +#include "ck_usart.h" +#include "soc.h" + +#define ERR_USART(errno) (CSI_DRV_ERRNO_USART_BASE | errno) + +/* + * setting config may be accessed when the USART is not + * busy(USR[0]=0) and the DLAB bit(LCR[7]) is set. + */ + +#define WAIT_USART_IDLE(addr)\ + do { \ + int32_t timecount = 0; \ + while ((addr->USR & USR_UART_BUSY) && (timecount < UART_BUSY_TIMEOUT)) {\ + timecount++;\ + }\ + if (timecount >= UART_BUSY_TIMEOUT) {\ + return ERR_USART(EDRV_TIMEOUT);\ + } \ + } while(0) + +#define USART_NULL_PARAM_CHK(para) \ + do { \ + if (para == NULL) { \ + return ERR_USART(EDRV_PARAMETER); \ + } \ + } while (0) + +typedef struct { + uint32_t base; + uint32_t irq; + usart_event_cb_t cb_event; ///< Event callback + void *cb_arg; + uint32_t rx_total_num; + uint32_t tx_total_num; + uint8_t *rx_buf; + uint8_t *tx_buf; + volatile uint32_t rx_cnt; + volatile uint32_t tx_cnt; + volatile uint32_t tx_busy; + volatile uint32_t rx_busy; +} dw_usart_priv_t; + +extern int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq); + +static dw_usart_priv_t usart_instance[CONFIG_USART_NUM]; + +static const usart_capabilities_t usart_capabilities = { + .asynchronous = 1, /* supports USART (Asynchronous) mode */ + .synchronous_master = 0, /* supports Synchronous Master mode */ + .synchronous_slave = 0, /* supports Synchronous Slave mode */ + .single_wire = 0, /* supports USART Single-wire mode */ + .event_tx_complete = 1, /* Transmit completed event */ + .event_rx_timeout = 0, /* Signal receive character timeout event */ +}; + +/** + \brief set the bautrate of usart. + \param[in] addr usart base to operate. + \param[in] baudrate. + \param[in] apbfreq the frequence of the apb. + \return error code +*/ +static int32_t dw_usart_set_baudrate(dw_usart_reg_t *addr, uint32_t baudrate, uint32_t apbfreq) +{ + WAIT_USART_IDLE(addr); + + /* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/ + uint32_t divisor = ((apbfreq * 10) / baudrate) >> 4; + + if ((divisor % 10) >= 5) { + divisor = (divisor / 10) + 1; + } else { + divisor = divisor / 10; + } + + addr->LCR |= LCR_SET_DLAB; + /* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/ + addr->DLL = divisor & 0xff; + addr->DLH = (divisor >> 8) & 0xff; + /* + * The DLAB must be cleared after the baudrate is setted + * to access other registers. + */ + addr->LCR &= (~LCR_SET_DLAB); + + return 0; +} + +/** + \brief enable or disable parity. + \param[in] addr usart base to operate. + \param[in] parity ODD=8, EVEN=16, or NONE=0. + \return error code +*/ + +static int32_t dw_usart_set_parity(dw_usart_reg_t *addr, usart_parity_e parity) +{ + WAIT_USART_IDLE(addr); + + switch (parity) { + case USART_PARITY_NONE: + /*CLear the PEN bit(LCR[3]) to disable parity.*/ + addr->LCR &= (~LCR_PARITY_ENABLE); + break; + + case USART_PARITY_ODD: + /* Set PEN and clear EPS(LCR[4]) to set the ODD parity. */ + addr->LCR |= LCR_PARITY_ENABLE; + addr->LCR &= LCR_PARITY_ODD; + break; + + case USART_PARITY_EVEN: + /* Set PEN and EPS(LCR[4]) to set the EVEN parity.*/ + addr->LCR |= LCR_PARITY_ENABLE; + addr->LCR |= LCR_PARITY_EVEN; + break; + + default: + return ERR_USART(EDRV_USART_PARITY); + } + + return 0; +} + +/** + \brief set the stop bit. + \param[in] addr usart base to operate. + \param[in] stopbit two possible value: USART_STOP_BITS_1 and USART_STOP_BITS_2. + \return error code +*/ +static int32_t dw_usart_set_stopbit(dw_usart_reg_t *addr, usart_stop_bits_e stopbit) +{ + WAIT_USART_IDLE(addr); + + switch (stopbit) { + case USART_STOP_BITS_1: + /* Clear the STOP bit to set 1 stop bit*/ + addr->LCR &= LCR_STOP_BIT1; + break; + + case USART_STOP_BITS_2: + /* + * If the STOP bit is set "1",we'd gotten 1.5 stop + * bits when DLS(LCR[1:0]) is zero, else 2 stop bits. + */ + addr->LCR |= LCR_STOP_BIT2; + break; + + default: + return ERR_USART(EDRV_USART_STOP_BITS); + } + + return 0; +} + +/** + \brief the transmit data length,and we have four choices:5, 6, 7, and 8 bits. + \param[in] addr usart base to operate. + \param[in] databits the data length that user decides. + \return error code +*/ +static int32_t dw_usart_set_databit(dw_usart_reg_t *addr, usart_data_bits_e databits) +{ + WAIT_USART_IDLE(addr); + /* The word size decides by the DLS bits(LCR[1:0]), and the + * corresponding relationship between them is: + * DLS word size + * 00 -- 5 bits + * 01 -- 6 bits + * 10 -- 7 bits + * 11 -- 8 bits + */ + + switch (databits) { + case USART_DATA_BITS_5: + addr->LCR &= LCR_WORD_SIZE_5; + break; + + case USART_DATA_BITS_6: + addr->LCR &= 0xfd; + addr->LCR |= LCR_WORD_SIZE_6; + break; + + case USART_DATA_BITS_7: + addr->LCR &= 0xfe; + addr->LCR |= LCR_WORD_SIZE_7; + break; + + case USART_DATA_BITS_8: + addr->LCR |= LCR_WORD_SIZE_8; + break; + + default: + return ERR_USART(EDRV_USART_DATA_BITS); + } + + return 0; +} + +/** + \brief get character in query mode. + \param[in] instance usart instance to operate. + \param[in] the pointer to the recieve charater. + \return error code +*/ +int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch) +{ + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + while (!(addr->LSR & LSR_DATA_READY)); + + *ch = addr->RBR; + + return 0; +} + +/** + \brief transmit character in query mode. + \param[in] instance usart instance to operate. + \param[in] ch the input charater + \return error code +*/ +int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch) +{ + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + while ((!(addr->LSR & DW_LSR_TRANS_EMPTY))); + + addr->THR = ch; + + return 0; + +} + +/** + \brief interrupt service function for transmitter holding register empty. + \param[in] usart_priv usart private to operate. +*/ +static void dw_usart_intr_threshold_empty(dw_usart_priv_t *usart_priv) +{ + if (usart_priv->tx_total_num == 0) { + return; + } + + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + addr->THR = *((uint8_t *)usart_priv->tx_buf); + usart_priv->tx_cnt++; + usart_priv->tx_buf++; + + if (usart_priv->tx_cnt >= usart_priv->tx_total_num) { + addr->IER &= (~IER_THRE_INT_ENABLE); + + while ((!(addr->LSR & DW_LSR_TEMT))); + + usart_priv->tx_cnt = 0; + usart_priv->tx_busy = 0; + usart_priv->tx_buf = NULL; + usart_priv->tx_total_num = 0; + + if (usart_priv->cb_event) { + usart_priv->cb_event(USART_EVENT_SEND_COMPLETE, usart_priv->cb_arg); + } + } + +} + +/** + \brief interrupt service function for receiver data available. + \param[in] usart_priv usart private to operate. +*/ +static void dw_usart_intr_recv_data(dw_usart_priv_t *usart_priv) +{ + if (usart_priv->cb_event && (usart_priv->rx_total_num == 0)) { + usart_priv->cb_event(USART_EVENT_RECEIVED, usart_priv->cb_arg); + return; + } + + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + uint8_t data = addr->RBR; + + if ((usart_priv->rx_total_num == 0) || (usart_priv->rx_buf == NULL)) { + return; + } + + *((uint8_t *)usart_priv->rx_buf) = data; + usart_priv->rx_cnt++; + usart_priv->rx_buf++; + + if (usart_priv->rx_cnt >= usart_priv->rx_total_num) { + usart_priv->rx_cnt = 0; + usart_priv->rx_buf = NULL; + usart_priv->rx_busy = 0; + usart_priv->rx_total_num = 0; + + if (usart_priv->cb_event) { + usart_priv->cb_event(USART_EVENT_RECEIVE_COMPLETE, usart_priv->cb_arg); + } + } + +} + +/** + \brief the interrupt service function. + \param[in] index of usart instance. +*/ +void dw_usart_irqhandler(int32_t idx) +{ + dw_usart_priv_t *usart_priv = &usart_instance[idx]; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + uint8_t intr_state = addr->IIR & 0xf; + + switch (intr_state) { + case DW_IIR_THR_EMPTY: /* interrupt source:transmitter holding register empty */ + dw_usart_intr_threshold_empty(usart_priv); + break; + + case DW_IIR_RECV_DATA: /* interrupt source:receiver data available or receiver fifo trigger level reached */ + dw_usart_intr_recv_data(usart_priv); + break; + + default: + break; + } +} + +/** + \brief Get driver capabilities. + \param[in] handle usart handle to operate. + \return \ref usart_capabilities_t +*/ +usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle) +{ + return usart_capabilities; +} + +/** + \brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function + \param[in] usart pin of tx + \param[in] usart pin of rx + \param[in] cb_event Pointer to \ref usart_event_cb_t + \return return usart handle if success +*/ +usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg) +{ + uint32_t base = 0u; + uint32_t irq = 0u; + + int32_t idx = target_usart_init(tx, rx, &base, &irq); + + if (idx < 0 || idx >= CONFIG_USART_NUM) { + return NULL; + } + + dw_usart_priv_t *usart_priv = &usart_instance[idx]; + usart_priv->base = base; + usart_priv->irq = irq; + usart_priv->cb_event = cb_event; + usart_priv->cb_arg = cb_arg; + + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + /* enable received data available */ + addr->IER = IER_RDA_INT_ENABLE; + drv_nvic_enable_irq(usart_priv->irq); + + return usart_priv; +} + +/** + \brief De-initialize UART Interface. stops operation and releases the software resources used by the interface + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_uninitialize(usart_handle_t handle) +{ + USART_NULL_PARAM_CHK(handle); + + dw_usart_priv_t *usart_priv = handle; + + drv_nvic_disable_irq(usart_priv->irq); + usart_priv->cb_event = NULL; + + return 0; +} + +/** + \brief config usart mode. + \param[in] handle usart handle to operate. + \param[in] sysclk configured system clock. + \param[in] mode \ref usart_mode_e + \param[in] parity \ref usart_parity_e + \param[in] stopbits \ref usart_stop_bits_e + \param[in] bits \ref usart_data_bits_e + \param[in] baud configured baud + \return error code +*/ +int32_t csi_usart_config(usart_handle_t handle, + uint32_t sysclk, + uint32_t baud, + usart_mode_e mode, + usart_parity_e parity, + usart_stop_bits_e stopbits, + usart_data_bits_e bits) +{ + USART_NULL_PARAM_CHK(handle); + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + /* control the data_bit of the usart*/ + int32_t ret = dw_usart_set_baudrate(addr, baud, sysclk); + + if (ret < 0) { + return ret; + } + + /* control the parity of the usart*/ + ret = dw_usart_set_parity(addr, parity); + + if (ret < 0) { + return ret; + } + + /* control the stopbit of the usart*/ + ret = dw_usart_set_stopbit(addr, stopbits); + + if (ret < 0) { + return ret; + } + + ret = dw_usart_set_databit(addr, bits); + + if (ret < 0) { + return ret; + } + + return 0; +} +/** + \brief config usart default tx value. used in syn mode + \param[in] handle usart handle to operate. + \param[in] value default tx value + \return error code +*/ +int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value) +{ + USART_NULL_PARAM_CHK(handle); + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief Start sending data to UART transmitter,(received data is ignored). + The function is non-blocking,UART_EVENT_TRANSFER_COMPLETE is signaled when transfer completes. + csi_usart_get_status can indicates if transmission is still in progress or pending + \param[in] handle usart handle to operate. + \param[in] data Pointer to buffer with data to send to UART transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits, + \param[in] num Number of data items to send + \return error code +*/ +int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num) +{ + USART_NULL_PARAM_CHK(handle); + USART_NULL_PARAM_CHK(data); + + if (num == 0) { + return ERR_USART(EDRV_PARAMETER); + } + + dw_usart_priv_t *usart_priv = handle; + uint8_t *source = NULL; + source = (uint8_t *)data; + + usart_priv->tx_buf = (uint8_t *)data; + usart_priv->tx_total_num = num; + usart_priv->tx_cnt = 0; + usart_priv->tx_busy = 1; + + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + /* enable the interrupt*/ + addr->IER |= IER_THRE_INT_ENABLE; + return 0; +} + +/** + \brief Abort Send data to UART transmitter + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_abort_send(usart_handle_t handle) +{ + USART_NULL_PARAM_CHK(handle); + dw_usart_priv_t *usart_priv = handle; + + usart_priv->tx_cnt = usart_priv->tx_total_num; + return 0; +} + +/** + \brief Start receiving data from UART receiver.transmits the default value as specified by csi_usart_set_default_tx_value + \param[in] handle usart handle to operate. + \param[out] data Pointer to buffer for data to receive from UART receiver + \param[in] num Number of data items to receive + \return error code +*/ +int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num) +{ + USART_NULL_PARAM_CHK(handle); + USART_NULL_PARAM_CHK(data); + + uint8_t *dest = NULL; + dw_usart_priv_t *usart_priv = handle; + dest = (uint8_t *)data; + + usart_priv->rx_buf = (uint8_t *)data; // Save receive buffer usart + usart_priv->rx_total_num = num; // Save number of data to be received + usart_priv->rx_cnt = 0; + usart_priv->rx_busy = 1; + + return 0; + +} + +/** + \brief query data from UART receiver FIFO. + \param[in] handle usart handle to operate. + \param[out] data Pointer to buffer for data to receive from UART receiver + \param[in] num Number of data items to receive + \return receive fifo data num +*/ +int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num) +{ + USART_NULL_PARAM_CHK(handle); + USART_NULL_PARAM_CHK(data); + + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + int32_t recv_num = 0; + + while (addr->LSR & 0x1) { + *((uint8_t *)data++) = addr->RBR; + recv_num++; + + if (recv_num >= num) { + break; + } + } + + return recv_num; + +} + +/** + \brief Abort Receive data from UART receiver + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_abort_receive(usart_handle_t handle) +{ + USART_NULL_PARAM_CHK(handle); + dw_usart_priv_t *usart_priv = handle; + + usart_priv->rx_cnt = usart_priv->rx_total_num; + return 0; +} + +/** + \brief Start sending/receiving data to/from UART transmitter/receiver. + \param[in] handle usart handle to operate. + \param[in] data_out Pointer to buffer with data to send to USART transmitter + \param[out] data_in Pointer to buffer for data to receive from USART receiver + \param[in] num Number of data items to transfer + \return error code +*/ +int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num) +{ + USART_NULL_PARAM_CHK(handle); + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief abort sending/receiving data to/from USART transmitter/receiver. + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_abort_transfer(usart_handle_t handle) +{ + USART_NULL_PARAM_CHK(handle); + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief Get USART status. + \param[in] handle usart handle to operate. + \return USART status \ref usart_status_t +*/ +usart_status_t csi_usart_get_status(usart_handle_t handle) +{ + usart_status_t usart_status; + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + uint32_t line_status_reg = addr->LSR; + + usart_status.tx_busy = usart_priv->tx_busy; + usart_status.rx_busy = usart_priv->rx_busy; + + if (line_status_reg & DW_LSR_BI) { + usart_status.rx_break = 1; + } + + if (line_status_reg & DW_LSR_FE) { + usart_status.rx_framing_error = 1; + } + + if (line_status_reg & DW_LSR_PE) { + usart_status.rx_parity_error = 1; + } + + return usart_status; +} + +/** + \brief control the transmit. + \param[in] handle usart handle to operate. + \param[in] 1 - enable the transmitter. 0 - disable the transmitter + \return error code +*/ +int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable) +{ + USART_NULL_PARAM_CHK(handle); + return 0; +} + +/** + \brief control the receive. + \param[in] handle usart handle to operate. + \param[in] 1 - enable the receiver. 0 - disable the receiver + \return error code +*/ +int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable) +{ + USART_NULL_PARAM_CHK(handle); + return 0; +} + +/** + \brief control the break. + \param[in] handle usart handle to operate. + \param[in] 1- Enable continuous Break transmission,0 - disable continuous Break transmission + \return error code +*/ +int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable) +{ + USART_NULL_PARAM_CHK(handle); + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief flush receive/send data. + \param[in] handle usart handle to operate. + \param[in] type \ref usart_flush_type_e. + \return error code +*/ +int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type) +{ + USART_NULL_PARAM_CHK(handle); + + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + if (type == USART_FLUSH_WRITE) { + while ((!(addr->LSR & DW_LSR_TEMT))); + } else if (type == USART_FLUSH_READ) { + while (addr->LSR & 0x1) { + addr->RBR; + } + } else { + return ERR_USART(EDRV_PARAMETER); + } + + return 0; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/ck_usart.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/ck_usart.h new file mode 100644 index 000000000..250da246f --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/ck_usart.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file dw_usart.h + * @brief header file for usart driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef __CK_USART_H +#define __CK_USART_H + +#include +#include "errno.h" +#include "soc.h" + +#define BAUDRATE_DEFAULT 19200 +#define UART_BUSY_TIMEOUT 1000000 +#define UART_RECEIVE_TIMEOUT 1000 +#define UART_TRANSMIT_TIMEOUT 1000 +#define UART_MAX_FIFO 0x10 +/* UART register bit definitions */ + +#define USR_UART_BUSY 0x01 +#define USR_UART_TFE 0x04 +#define USR_UART_RFNE 0x08 +#define LSR_DATA_READY 0x01 +#define LSR_THR_EMPTY 0x20 +#define IER_RDA_INT_ENABLE 0x01 +#define IER_THRE_INT_ENABLE 0x02 +#define IIR_NO_ISQ_PEND 0x01 + +#define LCR_SET_DLAB 0x80 /* enable r/w DLR to set the baud rate */ +#define LCR_PARITY_ENABLE 0x08 /* parity enabled */ +#define LCR_PARITY_EVEN 0x10 /* Even parity enabled */ +#define LCR_PARITY_ODD 0xef /* Odd parity enabled */ +#define LCR_WORD_SIZE_5 0xfc /* the data length is 5 bits */ +#define LCR_WORD_SIZE_6 0x01 /* the data length is 6 bits */ +#define LCR_WORD_SIZE_7 0x02 /* the data length is 7 bits */ +#define LCR_WORD_SIZE_8 0x03 /* the data length is 8 bits */ +#define LCR_STOP_BIT1 0xfb /* 1 stop bit */ +#define LCR_STOP_BIT2 0x04 /* 1.5 stop bit */ + +#define DW_LSR_PFE 0x80 +#define DW_LSR_TEMT 0x40 +#define DW_LSR_THRE 0x40 +#define DW_LSR_BI 0x10 +#define DW_LSR_FE 0x08 +#define DW_LSR_PE 0x04 +#define DW_LSR_OE 0x02 +#define DW_LSR_DR 0x01 +#define DW_LSR_TRANS_EMPTY 0x20 + +#define DW_IIR_THR_EMPTY 0x02 /* threshold empty */ +#define DW_IIR_RECV_DATA 0x04 /* received data available */ + +typedef struct { + union { + __IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */ + __OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */ + __IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */ + }; + union { + __IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */ + __IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */ + }; + __IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */ + __IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */ + uint32_t RESERVED0; + __IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */ + __IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */ + uint32_t RESERVED1[24]; + __IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */ +} dw_usart_reg_t; + +#endif /* __CK_USART_H */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/dw_usart.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/dw_usart.c new file mode 100644 index 000000000..2b9e47c75 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/dw_usart.c @@ -0,0 +1,761 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file dw_usart.c + * @brief CSI Source File for usart Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include "csi_core.h" +#include "drv_usart.h" +#include "dw_usart.h" +#include "soc.h" + +#define ERR_USART(errno) (CSI_DRV_ERRNO_USART_BASE | errno) + +/* + * setting config may be accessed when the USART is not + * busy(USR[0]=0) and the DLAB bit(LCR[7]) is set. + */ + +#define WAIT_USART_IDLE(addr)\ + do { \ + int32_t timecount = 0; \ + while ((addr->USR & USR_UART_BUSY) && (timecount < UART_BUSY_TIMEOUT)) {\ + timecount++;\ + }\ + if (timecount >= UART_BUSY_TIMEOUT) {\ + return ERR_USART(EDRV_TIMEOUT);\ + } \ + } while(0) + +#define USART_NULL_PARAM_CHK(para) \ + do { \ + if (para == NULL) { \ + return ERR_USART(EDRV_PARAMETER); \ + } \ + } while (0) + +typedef struct { + uint32_t base; +} dw_usart_priv_t; + +extern int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq); +extern int32_t target_usart_flowctrl_init(pin_t tx_flow, pin_t rx_flow, uint32_t flag); + +static dw_usart_priv_t usart_instance[CONFIG_USART_NUM]; + +static const usart_capabilities_t usart_capabilities = { + .asynchronous = 0, /* supports USART (Asynchronous) mode */ + .synchronous_master = 0, /* supports Synchronous Master mode */ + .synchronous_slave = 0, /* supports Synchronous Slave mode */ + .single_wire = 0, /* supports USART Single-wire mode */ + .event_tx_complete = 0, /* Transmit completed event */ + .event_rx_timeout = 0, /* Signal receive character timeout event */ +}; + +/** + \brief set the baut drate of usart. + \param[in] addr usart base to operate. + \param[in] baudrate baud rate + \param[in] apbfreq the frequency of the apb. + \return error code +*/ +int32_t csi_usart_config_baudrate(usart_handle_t handle, uint32_t baudrate, uint32_t apbfreq) +{ + USART_NULL_PARAM_CHK(handle); + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + +#ifdef CONFIG_CHIP_HOBBIT1_2 + uint8_t data[16]; + csi_usart_receive_query(handle, data, 16); +#endif + + WAIT_USART_IDLE(addr); + + /* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/ + uint32_t divisor = ((apbfreq * 10) / baudrate) >> 4; + + if ((divisor % 10) >= 5) { + divisor = (divisor / 10) + 1; + } else { + divisor = divisor / 10; + } + + addr->LCR |= LCR_SET_DLAB; + /* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/ + addr->DLL = divisor & 0xff; + addr->DLH = (divisor >> 8) & 0xff; + /* + * The DLAB must be cleared after the baudrate is setted + * to access other registers. + */ + addr->LCR &= (~LCR_SET_DLAB); + + return 0; +} + +/** + \brief config usart mode. + \param[in] handle usart handle to operate. + \param[in] mode \ref usart_mode_e + \return error code +*/ +int32_t csi_usart_config_mode(usart_handle_t handle, usart_mode_e mode) +{ + if (mode == USART_MODE_ASYNCHRONOUS) { + return 0; + } + + return ERR_USART(EDRV_USART_MODE); +} + +/** + \brief config usart parity. + \param[in] handle usart handle to operate. + \param[in] parity \ref usart_parity_e + \return error code +*/ +int32_t csi_usart_config_parity(usart_handle_t handle, usart_parity_e parity) +{ + USART_NULL_PARAM_CHK(handle); + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + WAIT_USART_IDLE(addr); + + switch (parity) { + case USART_PARITY_NONE: + /*CLear the PEN bit(LCR[3]) to disable parity.*/ + addr->LCR &= (~LCR_PARITY_ENABLE); + break; + + case USART_PARITY_ODD: + /* Set PEN and clear EPS(LCR[4]) to set the ODD parity. */ + addr->LCR |= LCR_PARITY_ENABLE; + addr->LCR &= LCR_PARITY_ODD; + break; + + case USART_PARITY_EVEN: + /* Set PEN and EPS(LCR[4]) to set the EVEN parity.*/ + addr->LCR |= LCR_PARITY_ENABLE; + addr->LCR |= LCR_PARITY_EVEN; + break; + + default: + return ERR_USART(EDRV_USART_PARITY); + } + + return 0; +} + +/** + \brief config usart stop bit number. + \param[in] handle usart handle to operate. + \param[in] stopbits \ref usart_stop_bits_e + \return error code +*/ +int32_t dw_usart_config_stopbits(usart_handle_t handle, usart_stop_bits_e stopbit) +{ + USART_NULL_PARAM_CHK(handle); + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + WAIT_USART_IDLE(addr); + + switch (stopbit) { + case USART_STOP_BITS_1: + /* Clear the STOP bit to set 1 stop bit*/ + addr->LCR &= LCR_STOP_BIT1; + break; + + case USART_STOP_BITS_2: + /* + * If the STOP bit is set "1",we'd gotten 1.5 stop + * bits when DLS(LCR[1:0]) is zero, else 2 stop bits. + */ + addr->LCR |= LCR_STOP_BIT2; + break; + + default: + return ERR_USART(EDRV_USART_STOP_BITS); + } + + return 0; +} + +/** + \brief config usart data length. + \param[in] handle usart handle to operate. + \param[in] databits \ref usart_data_bits_e + \return error code +*/ +int32_t csi_usart_config_databits(usart_handle_t handle, usart_data_bits_e databits) +{ + USART_NULL_PARAM_CHK(handle); + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + +#ifdef CONFIG_CHIP_HOBBIT1_2 + uint8_t data[16]; + csi_usart_receive_query(handle, data, 16); +#endif + + WAIT_USART_IDLE(addr); + /* The word size decides by the DLS bits(LCR[1:0]), and the + * corresponding relationship between them is: + * DLS word size + * 00 -- 5 bits + * 01 -- 6 bits + * 10 -- 7 bits + * 11 -- 8 bits + */ + + switch (databits) { + case USART_DATA_BITS_5: + addr->LCR &= LCR_WORD_SIZE_5; + break; + + case USART_DATA_BITS_6: + addr->LCR &= 0xfd; + addr->LCR |= LCR_WORD_SIZE_6; + break; + + case USART_DATA_BITS_7: + addr->LCR &= 0xfe; + addr->LCR |= LCR_WORD_SIZE_7; + break; + + case USART_DATA_BITS_8: + addr->LCR |= LCR_WORD_SIZE_8; + break; + + default: + return ERR_USART(EDRV_USART_DATA_BITS); + } + + return 0; +} + +/** + \brief get character in query mode. + \param[in] handle usart handle to operate. + \param[in] the pointer to the received character if return 0. + \return error code +*/ +int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch) +{ + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + while (!(addr->LSR & LSR_DATA_READY)); + + *ch = addr->RBR; + + return 0; +} + +/** + \brief transmit character in query mode. + \param[in] handle usart handle to operate. + \param[in] ch the input character + \return error code +*/ +int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch) +{ + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + while ((!(addr->LSR & DW_LSR_TRANS_EMPTY))); + + addr->THR = ch; + + return 0; +} + +/** + \brief the interrupt service function. + \param[in] index of usart instance. +*/ +void dw_usart_irqhandler(int32_t idx) +{ + (void)idx; +} + +/** + \brief Get driver capabilities. + \param[in] handle usart handle to operate. + \return \ref usart_capabilities_t +*/ +usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle) +{ + return usart_capabilities; +} + +/** + \brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function + \param[in] usart pin of tx + \param[in] usart pin of rx + \param[in] cb_event Pointer to \ref usart_event_cb_t + \return return usart handle if success +*/ +usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg) +{ + uint32_t base = 0u; + uint32_t irq = 0u; + int32_t idx = target_usart_init(tx, rx, &base, &irq); + + if (idx < 0 || idx >= CONFIG_USART_NUM) { + return NULL; + } + + dw_usart_priv_t *usart_priv = &usart_instance[idx]; + usart_priv->base = base; + + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + /* FIFO enable */ + addr->FCR = DW_FCR_FIFOE | DW_FCR_RT_FIFO_HALF; + + return usart_priv; +} + +/** + \brief De-initialize UART Interface. stops operation and releases the software resources used by the interface + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_uninitialize(usart_handle_t handle) +{ + USART_NULL_PARAM_CHK(handle); + return 0; +} + +/** + \brief config usart mode. + \param[in] handle usart handle to operate. + \param[in] sysclk configured system clock. + \param[in] baud baud rate + \param[in] mode \ref usart_mode_e + \param[in] parity \ref usart_parity_e + \param[in] stopbits \ref usart_stop_bits_e + \param[in] bits \ref usart_data_bits_e + \return error code +*/ +int32_t csi_usart_config(usart_handle_t handle, + uint32_t sysclk, + uint32_t baud, + usart_mode_e mode, + usart_parity_e parity, + usart_stop_bits_e stopbits, + usart_data_bits_e bits) +{ + int32_t ret; + + /* control the data_bit of the usart*/ + ret = csi_usart_config_baudrate(handle, baud, sysclk); + + if (ret < 0) { + return ret; + } + + /* control mode of the usart*/ + ret = csi_usart_config_mode(handle, mode); + + if (ret < 0) { + return ret; + } + + /* control the parity of the usart*/ + ret = csi_usart_config_parity(handle, parity); + + if (ret < 0) { + return ret; + } + + /* control the stopbit of the usart*/ + ret = dw_usart_config_stopbits(handle, stopbits); + + if (ret < 0) { + return ret; + } + + ret = csi_usart_config_databits(handle, bits); + + if (ret < 0) { + return ret; + } + + return 0; +} + +/** + \brief config usart default tx value. used in syn mode + \param[in] handle usart handle to operate. + \param[in] value default tx value + \return error code +*/ +int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value) +{ + USART_NULL_PARAM_CHK(handle); + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief Start sending data to UART transmitter,(received data is ignored). + The function is non-blocking,UART_EVENT_TRANSFER_COMPLETE is signaled when transfer completes. + csi_usart_get_status can indicates if transmission is still in progress or pending + \param[in] handle usart handle to operate. + \param[in] data Pointer to buffer with data to send to UART transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits, + \param[in] num Number of data items to send + \return error code +*/ +int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num) +{ + USART_NULL_PARAM_CHK(handle); + USART_NULL_PARAM_CHK(data); + + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief Abort Send data to UART transmitter + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_abort_send(usart_handle_t handle) +{ + USART_NULL_PARAM_CHK(handle); + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief Start receiving data from UART receiver.transmits the default value as specified by csi_usart_set_default_tx_value + \param[in] handle usart handle to operate. + \param[out] data Pointer to buffer for data to receive from UART receiver + \param[in] num Number of data items to receive + \return error code +*/ +int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num) +{ + return ERR_USART(EDRV_UNSUPPORTED); + +} + +/** + \brief query data from UART receiver FIFO. + \param[in] handle usart handle to operate. + \param[out] data Pointer to buffer for data to receive from UART receiver + \param[in] num Number of data items to receive + \return receive fifo data num +*/ +int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num) +{ + return ERR_USART(EDRV_UNSUPPORTED); + +} + +/** + \brief Abort Receive data from UART receiver + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_abort_receive(usart_handle_t handle) +{ + USART_NULL_PARAM_CHK(handle); + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief Start sending/receiving data to/from UART transmitter/receiver. + \param[in] handle usart handle to operate. + \param[in] data_out Pointer to buffer with data to send to USART transmitter + \param[out] data_in Pointer to buffer for data to receive from USART receiver + \param[in] num Number of data items to transfer + \return error code +*/ +int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num) +{ + USART_NULL_PARAM_CHK(handle); + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief abort sending/receiving data to/from USART transmitter/receiver. + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_abort_transfer(usart_handle_t handle) +{ + USART_NULL_PARAM_CHK(handle); + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief Get USART status. + \param[in] handle usart handle to operate. + \return USART status \ref usart_status_t +*/ +usart_status_t csi_usart_get_status(usart_handle_t handle) +{ + usart_status_t status = {0}; + return status; +} + +/** + \brief control the transmit. + \param[in] handle usart handle to operate. + \param[in] 1 - enable the transmitter. 0 - disable the transmitter + \return error code +*/ +int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable) +{ + USART_NULL_PARAM_CHK(handle); + return 0; +} + +/** + \brief control the receive. + \param[in] handle usart handle to operate. + \param[in] 1 - enable the receiver. 0 - disable the receiver + \return error code +*/ +int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable) +{ + USART_NULL_PARAM_CHK(handle); + return 0; +} + +/** + \brief control the break. + \param[in] handle usart handle to operate. + \param[in] 1- Enable continuous Break transmission,0 - disable continuous Break transmission + \return error code +*/ +int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable) +{ + USART_NULL_PARAM_CHK(handle); + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief flush receive/send data. + \param[in] handle usart handle to operate. + \param[in] type \ref usart_flush_type_e. + \return error code +*/ +int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type) +{ + USART_NULL_PARAM_CHK(handle); + + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + if (type == USART_FLUSH_WRITE) { + addr->FCR |= DW_FCR_XFIFOR; + + while (addr->FCR & DW_FCR_XFIFOR); + } else if (type == USART_FLUSH_READ) { + addr->FCR |= DW_FCR_RFIFOR; + + while (addr->FCR & DW_FCR_RFIFOR); + } else { + return ERR_USART(EDRV_PARAMETER); + } + + return 0; +} + +/** + \brief control interrupt on/off. + \param[in] handle usart handle to operate. + \param[in] type \ref usart_intr_type_e. + \param[in] flag 0-OFF, 1-ON. + \return error code +*/ +int32_t csi_usart_interrupt_on_off(usart_handle_t handle, usart_intr_type_e type, int flag) +{ + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief Get usart send data count. + \param[in] handle usart handle to operate. + \return number of data bytes transferred +*/ +uint32_t csi_usart_get_tx_count(usart_handle_t handle) +{ + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief Get usart receive data count. + \param[in] handle usart handle to operate. + \return number of data bytes transferred +*/ +uint32_t csi_usart_get_rx_count(usart_handle_t handle) +{ + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief control usart power. + \param[in] handle usart handle to operate. + \param[in] state power state.\ref csi_power_stat_e. + \return error code +*/ +int32_t csi_usart_power_control(usart_handle_t handle, csi_power_stat_e state) +{ + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief config usart flow control type. + \param[in] handle usart handle to operate. + \param[in] flowctrl_type flow control type.\ref usart_flowctrl_type_e. + \param[in] tx_flow The TX flow pin name + \param[in] rx_flow The RX flow pin name + \return error code +*/ +int32_t csi_usart_config_flowctrl(usart_handle_t handle, + usart_flowctrl_type_e flowctrl_type, + pin_t tx_flow, pin_t rx_flow) +{ + USART_NULL_PARAM_CHK(handle); + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + int32_t ret; + + switch (flowctrl_type) { + case USART_FLOWCTRL_CTS: + return ERR_USART(EDRV_UNSUPPORTED); + + case USART_FLOWCTRL_RTS: + return ERR_USART(EDRV_UNSUPPORTED); + + case USART_FLOWCTRL_CTS_RTS: + ret = target_usart_flowctrl_init(tx_flow, rx_flow, 1); + + if (ret < 0) { + return ERR_USART(EDRV_PARAMETER); + } + + WAIT_USART_IDLE(addr); + addr->MCR |= DW_MCR_AFCE | DW_MCR_RTS; + break; + + case USART_FLOWCTRL_NONE: + ret = target_usart_flowctrl_init(tx_flow, rx_flow, 0); + + if (ret < 0) { + return ERR_USART(EDRV_PARAMETER); + } + + WAIT_USART_IDLE(addr); + addr->MCR = 0; + break; + + default: + return ERR_USART(EDRV_UNSUPPORTED); + } + + return 0; +} + +/** + \brief usart modem control. + \param[in] handle usart handle to operate. + \param[in] modem_ctrl modem control action.\ref usart_modem_ctrl_e. + \return error code +*/ +int32_t csi_usart_modem_ctrl(usart_handle_t handle, usart_modem_ctrl_e modem_ctrl) +{ + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief get usart modem status. + \param[in] handle usart handle to operate. + \param[in] modem_ctrl modem control action.\ref usart_modem_ctrl_e. + \return modem status.\ref usart_modem_stat_t. +*/ +usart_modem_stat_t csi_usart_get_modem_stat(usart_handle_t handle) +{ + usart_modem_stat_t modem_stat = {0}; + return modem_stat; +} + +/** + \brief config usart clock Polarity and Phase. + \param[in] handle usart handle to operate. + \param[in] cpol Clock Polarity.\ref usart_cpol_e. + \param[in] cpha Clock Phase.\ref usart_cpha_e. + \return error code +*/ +int32_t csi_usart_config_clock(usart_handle_t handle, usart_cpol_e cpol, usart_cpha_e cpha) +{ + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief config usart guard time. + \param[in] handle usart handle to operate. + \param[in] num_of_bits guard time in number of bit periods. + \return error code +*/ +int32_t csi_usart_config_guard_time(usart_handle_t handle, uint32_t num_of_bits) +{ + return ERR_USART(EDRV_UNSUPPORTED); +} + +/** + \brief check if usart is readable(data received). + \param[in] handle usart handle to operate. + \return 1 - a character can be read, 0 if nothing to read ,negative for error code +*/ +int32_t csi_usart_readable(usart_handle_t handle) +{ + USART_NULL_PARAM_CHK(handle); + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + if (addr->LSR & LSR_DATA_READY) { + return 1; + } else { + return 0; + } +} + +/** + \brief check if usart is writable(free for data sending). + \param[in] handle usart handle to operate. + \return 1 - a character can be written, 0 - cannot be written ,negative for error code +*/ +int32_t csi_usart_writable(usart_handle_t handle) +{ + USART_NULL_PARAM_CHK(handle); + dw_usart_priv_t *usart_priv = handle; + dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base); + + if (addr->LSR & DW_LSR_TRANS_EMPTY) { + return 1; + } else { + return 0; + } +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/dw_usart.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/dw_usart.h new file mode 100644 index 000000000..04666a23c --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/dw_usart.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file dw_usart.h + * @brief header file for usart driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef __DW_USART_H +#define __DW_USART_H + +#include +#include "errno.h" +#include "soc.h" + +#define BAUDRATE_DEFAULT 19200 +#define UART_BUSY_TIMEOUT 1000000 +#define UART_RECEIVE_TIMEOUT 1000 +#define UART_TRANSMIT_TIMEOUT 1000 +#define UART_MAX_FIFO 0x10 +/* UART register bit definitions */ + +#define USR_UART_BUSY 0x01 +#define USR_UART_TFE 0x04 +#define USR_UART_RFNE 0x08 +#define LSR_DATA_READY 0x01 +#define LSR_THR_EMPTY 0x20 +#define IER_RDA_INT_ENABLE 0x01 +#define IER_THRE_INT_ENABLE 0x02 +#define IIR_NO_ISQ_PEND 0x01 +#define IIR_RECV_LINE_ENABLE 0x04 + +#define LCR_SET_DLAB 0x80 /* enable r/w DLR to set the baud rate */ +#define LCR_PARITY_ENABLE 0x08 /* parity enabled */ +#define LCR_PARITY_EVEN 0x10 /* Even parity enabled */ +#define LCR_PARITY_ODD 0xef /* Odd parity enabled */ +#define LCR_WORD_SIZE_5 0xfc /* the data length is 5 bits */ +#define LCR_WORD_SIZE_6 0x01 /* the data length is 6 bits */ +#define LCR_WORD_SIZE_7 0x02 /* the data length is 7 bits */ +#define LCR_WORD_SIZE_8 0x03 /* the data length is 8 bits */ +#define LCR_STOP_BIT1 0xfb /* 1 stop bit */ +#define LCR_STOP_BIT2 0x04 /* 1.5 stop bit */ + +#define DW_LSR_PFE 0x80 +#define DW_LSR_TEMT 0x40 +#define DW_LSR_THRE 0x40 +#define DW_LSR_BI 0x10 +#define DW_LSR_FE 0x08 +#define DW_LSR_PE 0x04 +#define DW_LSR_OE 0x02 +#define DW_LSR_DR 0x01 +#define DW_LSR_TRANS_EMPTY 0x20 + +#define DW_FCR_FIFOE 0x01 +#define DW_FCR_RFIFOR 0x02 +#define DW_FCR_XFIFOR 0x04 +#define DW_FCR_RT_FIFO_SINGLE 0x0 << 6 /* rcvr trigger 1 character in the FIFO */ +#define DW_FCR_RT_FIFO_QUARTER 0x1 << 6 /* rcvr trigger FIFO 1/4 full */ +#define DW_FCR_RT_FIFO_HALF 0x2 << 6 /* rcvr trigger FIFO 1/2 full */ +#define DW_FCR_RT_FIFO_LESSTWO 0x3 << 6 /* rcvr trigger FIFO 2 less than full */ +#define DW_FCR_TET_FIFO_EMPTY 0x0 << 4 /* tx empty trigger FIFO empty */ +#define DW_FCR_TET_FIFO_TWO 0x1 << 4 /* tx empty trigger 2 characters in the FIFO */ +#define DW_FCR_TET_FIFO_QUARTER 0x2 << 4 /* tx empty trigger FIFO 1/4 full */ +#define DW_FCR_TET_FIFO_HALF 0x3 << 4 /* tx empty trigger FIFO 1/2 full*/ + +#define DW_IIR_THR_EMPTY 0x02 /* threshold empty */ +#define DW_IIR_RECV_DATA 0x04 /* received data available */ +#define DW_IIR_RECV_LINE 0x06 /* receiver line status */ +#define DW_IIR_CHAR_TIMEOUT 0x0c /* character timeout */ + +#define DW_MCR_AFCE 0x20 /* Auto Flow Control Enable */ +#define DW_MCR_RTS 0x02 + +typedef struct { + union { + __IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */ + __OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */ + __IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */ + }; + union { + __IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */ + __IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */ + }; + union { + __IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */ + __OM uint32_t FCR; /* Offset: 0x008 ( /W) FIFO control register */ + }; + __IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */ + __IOM uint32_t MCR; /* Offset: 0x010 (R/W) Modem control register */ + __IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */ + __IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */ + uint32_t RESERVED1[21]; + __IOM uint32_t FAR; /* Offset: 0x070 (R/W) FIFO accesss register */ + __IM uint32_t TFR; /* Offset: 0x074 (R/ ) transmit FIFO read */ + __OM uint32_t RFW; /* Offset: 0x078 ( /W) receive FIFO write */ + __IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */ + __IM uint32_t TFL; /* Offset: 0x080 (R/ ) transmit FIFO level */ + __IM uint32_t RFL; /* Offset: 0x084 (R/ ) receive FIFO level */ + +} dw_usart_reg_t; + +#endif /* __DW_USART_H */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/wdt/Kconfig b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/wdt/Kconfig new file mode 100644 index 000000000..09cf48781 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/wdt/Kconfig @@ -0,0 +1,11 @@ +choice + prompt "select wdt type " + help + select wdt type +config WDT_DW + bool "designware wdt" + help + select the dw wdt driver + +endchoice + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/wdt/dw_wdt.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/wdt/dw_wdt.c new file mode 100644 index 000000000..f0461aeb2 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/wdt/dw_wdt.c @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file dw_wdt.c + * @brief CSI Source File for WDT Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include "drv_wdt.h" +#include "dw_wdt.h" +#include "soc.h" +#include "csi_core.h" + +#define ERR_WDT(errno) (CSI_DRV_ERRNO_WDT_BASE | errno) + +static uint32_t timeout_ms[16] = {4, 7, 13, 26, 52, 105, 210, 419, 839, 1678, 3355, 6711, + 13422, 26844, 53687, 107374 + }; + +#define WDT_NULL_PARAM_CHK(para) \ + do { \ + if (para == NULL) { \ + return ERR_WDT(EDRV_PARAMETER); \ + } \ + } while (0) + +typedef struct { + uint32_t base; + uint32_t irq; + wdt_event_cb_t cb_event; +} dw_wdt_priv_t; + +extern int32_t target_get_wdt_count(void); +extern int32_t target_get_wdt(int32_t idx, uint32_t *base, uint32_t *irq); + +static dw_wdt_priv_t wdt_instance[CONFIG_WDT_NUM]; + +/* Driver Capabilities */ +static const wdt_capabilities_t wdt_capabilities = { + .interrupt = 1, ///< supports interrupt +}; + +static inline void dw_wdt_enable(dw_wdt_reg_t *addr) +{ + uint32_t value = addr->WDT_CR; + value |= 1 << 0; + addr->WDT_CR = value; +} + +static inline void dw_wdt_disable(dw_wdt_reg_t *addr) +{ + uint32_t value = addr->WDT_CR; + value &= ~(1 << 0); + addr->WDT_CR = value; +} + + +void dw_wdt_irqhandler(int32_t idx) +{ + dw_wdt_priv_t *wdt_priv = &wdt_instance[idx]; + dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base); + + addr->WDT_EOI; + + if (wdt_priv->cb_event) { + wdt_priv->cb_event(WDT_EVENT_TIMEOUT); + } +} + +/** + \brief get wdt instance count. + \return wdt instance count +*/ +int32_t csi_wdt_get_instance_count(void) +{ + return target_get_wdt_count(); +} + +/** + \brief Initialize WDT Interface. 1. Initializes the resources needed for the WDT interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_wdt_get_instance_count() + \param[in] cb_event Pointer to \ref wdt_event_cb_t + \return pointer to wdt instance +*/ +wdt_handle_t csi_wdt_initialize(int32_t idx, wdt_event_cb_t cb_event) +{ + if (idx < 0 || idx >= CONFIG_WDT_NUM) { + return NULL; + } + + uint32_t base = 0u; + uint32_t irq = 0u; + + int32_t real_idx = target_get_wdt(idx, &base, &irq); + + if (real_idx != idx) { + return NULL; + } + + dw_wdt_priv_t *wdt_priv = &wdt_instance[idx]; + wdt_priv->base = base; + wdt_priv->irq = irq; + + wdt_priv->cb_event = cb_event; + drv_nvic_enable_irq(wdt_priv->irq); + + return (wdt_handle_t)wdt_priv; +} + +/** + \brief De-initialize WDT Interface. stops operation and releases the software resources used by the interface + \param[in] instance wdt instance to operate. + \return \ref execution_status +*/ +int32_t csi_wdt_uninitialize(wdt_handle_t handle) +{ + WDT_NULL_PARAM_CHK(handle); + + dw_wdt_priv_t *wdt_priv = handle; + + wdt_priv->cb_event = NULL; + drv_nvic_disable_irq(wdt_priv->irq); + return 0; +} +/** + \brief Get driver capabilities. + \param[in] wdt instance to operate. + \return \ref wdt_capabilities_t +*/ +wdt_capabilities_t csi_wdt_get_capabilities(wdt_handle_t handle) +{ + return wdt_capabilities; +} + +/** + \brief Set the WDT value. value = (2^t*0xffff * 10^6 /freq)/10^3(t: 0 ~ 15). + \param[in] handle wdt handle to operate. + \param[in] value the timeout value(ms) \ref:timeout_ms[] + \return \ref execution_status +*/ +int32_t csi_wdt_set_timeout(wdt_handle_t handle, uint32_t value) +{ + WDT_NULL_PARAM_CHK(handle); + uint32_t i = 0u; + + for (i = 0; i <= 15 ; i++) { + if (timeout_ms[i] == value) { + break; + } + + if (i == 15) { + return ERR_WDT(EDRV_PARAMETER); + } + } + + dw_wdt_priv_t *wdt_priv = handle; + dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base); + + uint32_t config = addr->WDT_CR; + uint32_t en_stat = 0; /*origin wdt enable status*/ + + if ((config & 0x1) != 0) { + en_stat = 1; + } + + config = 0; + addr->WDT_CR = config; + + /*before configuration, must disable wdt first*/ + dw_wdt_disable(addr); + i += i << 4; + addr->WDT_TORR = i; + + if (en_stat == 1) { + dw_wdt_enable(addr); + csi_wdt_restart(handle); + } + + return 0; +} + +/** + \brief Start the WDT. + \param[in] handle wdt handle to operate. + \return \ref execution_status +*/ +int32_t csi_wdt_start(wdt_handle_t handle) +{ + WDT_NULL_PARAM_CHK(handle); + + dw_wdt_priv_t *wdt_priv = handle; + dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base); + + dw_wdt_enable(addr); + csi_wdt_restart(handle); + return 0; +} + +/** + \brief Stop the WDT. + \param[in] handle wdt handle to operate. + \return \ref execution_status +*/ +int32_t csi_wdt_stop(wdt_handle_t handle) +{ + WDT_NULL_PARAM_CHK(handle); + + return ERR_WDT(EDRV_UNSUPPORTED); +} + +/** + \brief Restart the WDT. + \param[in] handle wdt handle to operate. + \return \ref execution_status +*/ +int32_t csi_wdt_restart(wdt_handle_t handle) +{ + WDT_NULL_PARAM_CHK(handle); + + dw_wdt_priv_t *wdt_priv = handle; + dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base); + + addr->WDT_CRR = DW_WDT_CRR_RESET; + + return 0; +} + +/** + \brief Read the WDT Current value. + \param[in] handle wdt handle to operate. + \param[in] value Pointer to the Value. + \return \ref execution_status +*/ +int32_t csi_wdt_read_current_value(wdt_handle_t handle, uint32_t *value) +{ + WDT_NULL_PARAM_CHK(handle); + + dw_wdt_priv_t *wdt_priv = handle; + dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base); + + *value = addr->WDT_CCVR; + return 0; +} + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/wdt/dw_wdt.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/wdt/dw_wdt.h new file mode 100644 index 000000000..47cd9bea6 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/wdt/dw_wdt.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file dw_wdt.h + * @brief header file for wdt driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef __DW_WDT_H +#define __DW_WDT_H + +#include +#include "soc.h" + +#define DW_WDT_CRR_RESET 0x76 +typedef struct { + __IOM uint8_t WDT_CR:5; /* Offset: 0x000 (R/W) WDT control register */ + uint8_t RESERVED0[3]; + __IOM uint8_t WDT_TORR; /* Offset: 0x004 (R/W) WDT timeout range register */ + uint8_t RESERVED1[3]; + __IM uint32_t WDT_CCVR; /* Offset: 0x008 (R/ ) WDT current counter value register */ + __OM uint8_t WDT_CRR:8; /* Offset: 0x00C ( /W) WDT count restart register */ + uint8_t RESERVED2[3]; + __IM uint8_t WDT_STAT:1; /* Offset: 0x010 (R/ ) WDT interrupt status register */ + uint8_t RESERVED3[3]; + __IM uint8_t WDT_EOI:1; /* Offset: 0x014 (R/ ) WDT interrupt clear register */ + uint8_t RESERVED4[3]; +} dw_wdt_reg_t; + +#endif /* __DW_WDT_H */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/csi.mk b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/csi.mk new file mode 100644 index 000000000..68d1a4699 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/csi.mk @@ -0,0 +1,14 @@ +ifeq ($(CONFIG_PLATFORM_PHOBOS), y) +include $(CSI_DIR)/csi_driver/csky/phobos/csi.mk +endif + +ifeq ($(CONFIG_PLATFORM_HOBBIT1_2), y) +include $(CSI_DIR)/csi_driver/csky/hobbit1_2/csi.mk +endif + +ifeq ($(CONFIG_PLATFORM_HOBBIT3), y) +include $(CSI_DIR)/csi_driver/csky/hobbit3/csi.mk +endif + +include $(CSI_DIR)/csi_driver/csky/common/csi.mk + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/Kconfig b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/Kconfig new file mode 100644 index 000000000..e69de29bb diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/csi.mk b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/csi.mk new file mode 100644 index 000000000..4371596fe --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/csi.mk @@ -0,0 +1,5 @@ +TEE_INC += -I$(CSI_DIR)/csi_driver/csky/hobbit1_2/include +TEE_SRC += \ + $(CSI_DIR)/csi_driver/csky/hobbit1_2/devices.c \ + $(CSI_DIR)/csi_driver/csky/hobbit1_2/isr.c \ + $(CSI_DIR)/csi_driver/csky/hobbit1_2/pinmux.c diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/devices.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/devices.c new file mode 100644 index 000000000..fe5969c93 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/devices.c @@ -0,0 +1,829 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file devices.c + * @brief source file for the devices + * @version V1.0 + * @date 24. August 2017 + ******************************************************************************/ +#include "soc.h" +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "pin_name.h" +#include "pinmux.h" + +#define readl(addr) \ + ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) + +#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) + + +#if CONFIG_GPIO +struct { + uint32_t base; + uint32_t irq; + uint32_t pin_num; + port_name_t port; +} +const sg_gpio_config[CONFIG_GPIO_NUM] = { + {CSKY_GPIO0_BASE, GPIOA_IRQn, 28, PORTA}, + {CSKY_GPIO1_BASE, GPIOB_IRQn, 4, PORTB}, +}; + +typedef struct { + pin_t gpio_pin; + uint32_t cfg_idx; //idx of sg_gpio_config[] +} gpio_pin_map_t; +const static gpio_pin_map_t s_gpio_pin_map[] = { + {PA0_TRIG0_ACMP1P_TCK, 0}, + {PA1_TRIG1_ACMP1N_TMS, 0}, + {PA2_TXD0_SPI0MISO, 0}, + {PA3_RXD0_SPI0MOSI, 0}, + {PA4_CTS0_PWM0_SPI0SCK_TRIG0, 0}, + {PA5_RTS0_PWM1_SPI0SSN_TRIG1, 0}, + + {PB0_SCL0_PWM2_I2SMCLK, 1}, + {PB1_SDA0_PWM3_I2SSCK, 1}, + {PB2_SPI0SCK_PWM4_I2SWS, 1}, + {PB3_SPI0MISO_PWM5_I2SSD, 1}, + + {PA6_SPI0MOSI_PWM6_SCL0, 0}, + {PA7_SPI0SSN_PWM7_SDA0, 0}, + {PA8_WKUP_ADC0_ACMP0P, 0}, + {PA9_BOOT_ADC1_PWMFAULT, 0}, + {PA10_ADC2_TXD0, 0}, + {PA11_ACMP0N_ADC3_RXD0, 0}, + {PA12_PWM8_TCK_ADC4, 0}, + {PA13_PWM9_TMS_ADC5, 0}, + {PA14_PWM10_ADC6, 0}, + {PA15_PWM11_ADC7, 0}, + {PA16_RXD1_ADC8, 0}, + {PA17_TXD1_ADC9, 0}, + {PA18_SPI1SSN0_ACMP0O, 0}, + {PA19_SPI1SSN1_ACMP1O, 0}, + {PA20_SPI1SSN2_TRIG0_RXD1, 0}, + {PA21_SPI1SCK_TRIG1_TXD1, 0}, + {PA22_SPI1MISO_PWM0_ADC10, 0}, + {PA23_SPI1MOSI_PWM1_ADC11, 0}, + {PA24_TXD2_I2SMCLK_SPI1SSN0, 0}, + {PA25_RXD2_I2SSCK_SPI1SSN1, 0}, + {PA26_CTS2_I2SWS_ADC12, 0}, + {PA27_RTS2_I2SSD_ADC13, 0} +}; + +int32_t target_gpio_port_init(port_name_t port, uint32_t *base, uint32_t *irq, uint32_t *pin_num) +{ + int i; + + for (i = 0; i < CONFIG_GPIO_NUM; i++) { + if (sg_gpio_config[i].port == port) { + *base = sg_gpio_config[i].base; + *irq = sg_gpio_config[i].irq; + *pin_num = sg_gpio_config[i].pin_num; + return i; + } + } + + return -1; +} +/** + \param[in] instance idx, must not exceed return value of target_get_gpio_count() + \brief get gpio instance. + \return pointer to gpio instance +*/ +int32_t target_gpio_pin_init(pin_t gpio_pin, uint32_t *port_idx) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_gpio_pin_map) / sizeof(gpio_pin_map_t); idx++) { + if (s_gpio_pin_map[idx].gpio_pin == gpio_pin) { + *port_idx = s_gpio_pin_map[idx].cfg_idx; + /*pinmux*/ + pin_mux(s_gpio_pin_map[idx].gpio_pin, 0xff); + if (idx >= 10) { + return idx - 4; + } else if (idx >= 6) { + return idx - 6; + } else { + return idx; + } + } + } + + return -1; +} + +#endif + +#if CONFIG_TIMER +struct { + uint32_t base; + uint32_t irq; +} +const sg_timer_config[CONFIG_TIMER_NUM] = { + {CSKY_TIM0_BASE, TIMA0_IRQn}, + {CSKY_TIM0_BASE + 0x14, TIMA1_IRQn}, + {CSKY_TIM1_BASE, TIMB0_IRQn}, + {CSKY_TIM1_BASE + 0x14, TIMB1_IRQn} + +}; + +int32_t target_get_timer_count(void) +{ + return CONFIG_TIMER_NUM; +} + +int32_t target_get_timer(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_timer_count()) { + return NULL; + } + + *base = sg_timer_config[idx].base; + *irq = sg_timer_config[idx].irq; + return idx; +} + +#endif + +#if CONFIG_PMU +struct { + uint32_t base; + uint32_t irq; +} +const sg_pmu_config[CONFIG_PMU_NUM] = { + {CSKY_CLKGEN_BASE, POWM_IRQn} +}; + +int32_t target_get_pmu(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx > CONFIG_PMU_NUM) { + return -1; + } + *base = sg_pmu_config[idx].base; + *irq = sg_pmu_config[idx].irq; + return idx; +} +#endif + +#if CONFIG_RTC +#undef CSKY_PMU_BASE +#define CSKY_PMU_BASE 0x40002000 +#define BIT1 (0x1) +struct { + uint32_t base; + uint32_t irq; +} +const sg_rtc_config[CONFIG_RTC_NUM] = { + {CSKY_RTC0_BASE, RTC_IRQn}, + {CSKY_RTC1_BASE, RTC1_IRQn} + +}; + +int32_t target_get_rtc_count(void) +{ + return CONFIG_RTC_NUM; +} + +int32_t target_get_rtc(int32_t idx, uint32_t *base, uint32_t *irq) +{ + unsigned int value; + + if (idx >= target_get_rtc_count()) { + return NULL; + } + + value = readl(CSKY_PMU_BASE); + value &= ~BIT1; + writel(value, CSKY_PMU_BASE); + + *base = sg_rtc_config[idx].base; + *irq = sg_rtc_config[idx].irq; + return idx; +} + +#endif + +#if CONFIG_TRNG +struct { + uint32_t base; +} +const sg_trng_config[CONFIG_TRNG_NUM] = { + {CSKY_TRNG_BASE} +}; + +/** + \brief get trng instance count. + \return trng instance count +*/ +int32_t target_get_trng_count(void) +{ + return CONFIG_TRNG_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_trng_count() + \brief get trng instance. + \return pointer to trng instance +*/ +int32_t target_get_trng(int32_t idx, uint32_t *base) +{ + if (idx >= target_get_trng_count()) { + return NULL; + } + + *base = sg_trng_config[idx].base; + return idx; +} + +#endif + +#if CONFIG_CRC +struct { + uint32_t base; +} +const sg_crc_config[CONFIG_CRC_NUM] = { + {CSKY_CRC_BASE} +}; + +/** + \brief get crc instance count. + \return crc instance count +*/ +int32_t target_get_crc_count(void) +{ + return CONFIG_CRC_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_crc_count() + \brief get crc instance. + \return pointer to crc instance +*/ +int32_t target_get_crc(int32_t idx, uint32_t *base) +{ + if (idx >= target_get_crc_count()) { + return NULL; + } + + *base = sg_crc_config[idx].base; + return idx; +} + +#endif + +#if CONFIG_USART +struct { + uint32_t base; + uint32_t irq; +} +const sg_usart_config[CONFIG_USART_NUM] = { + {CSKY_UART0_BASE, UART0_IRQn}, + {CSKY_UART1_BASE, UART1_IRQn}, + {CSKY_UART2_BASE, UART2_IRQn}, +}; +typedef struct { + pin_t tx; + pin_t rx; + pin_t cts; + pin_t rts; + uint16_t cfg_idx; //idx of sg_usart_config[] + uint16_t function; +} usart_pin_map_t; +const static usart_pin_map_t s_usart_pin_map[] = { + { + PA2_TXD0_SPI0MISO, + PA3_RXD0_SPI0MOSI, + -1, + -1, + 0, + 0 + }, + { + PA10_ADC2_TXD0, + PA11_ACMP0N_ADC3_RXD0, + -1, + -1, + 0, + 2 + }, + { + PA17_TXD1_ADC9, + PA16_RXD1_ADC8, + -1, + -1, + 1, + 0 + }, + { + PA21_SPI1SCK_TRIG1_TXD1, + PA20_SPI1SSN2_TRIG0_RXD1, + -1, + -1, + 1, + 2, + }, + { + PA24_TXD2_I2SMCLK_SPI1SSN0, + PA25_RXD2_I2SSCK_SPI1SSN1, + PA26_CTS2_I2SWS_ADC12, + PA27_RTS2_I2SSD_ADC13, + 2, + 0 + }, +}; + +/** + \param[in] instance idx, must not exceed return value of target_get_usart_count() + \brief get usart instance. + \return pointer to usart instance +*/ +int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) { + if (s_usart_pin_map[idx].tx == tx && s_usart_pin_map[idx].rx == rx) { + *base = sg_usart_config[s_usart_pin_map[idx].cfg_idx].base; + *irq = sg_usart_config[s_usart_pin_map[idx].cfg_idx].irq; + /*pinmux*/ + pin_mux(s_usart_pin_map[idx].tx, s_usart_pin_map[idx].function); + pin_mux(s_usart_pin_map[idx].rx, s_usart_pin_map[idx].function); + return s_usart_pin_map[idx].cfg_idx; + } + } + + return -1; + +} +/** + \brief control usart flow. + \param[in] tx_flow The TX flow pin name + \param[in] rx_flow The RX flow pin name + \param[in] flag 0-disable, 1-enable. + \return 0 if setting ready ,negative for error code +*/ +int32_t target_usart_flowctrl_init(pin_t tx_flow, pin_t rx_flow, uint32_t flag) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) { + if ((s_usart_pin_map[idx].cts == tx_flow) &&(s_usart_pin_map[idx].rts == rx_flow)) + break; + } + + if (idx >= sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t)) { + return -1; + } + + if ((s_usart_pin_map[idx].cts == tx_flow) && flag) { + pin_mux(s_usart_pin_map[idx].cts, s_usart_pin_map[idx].function); + } else if ((s_usart_pin_map[idx].cts == tx_flow) && (flag == 0)) { + pin_mux(s_usart_pin_map[idx].cts, 0xff); + } else { + return -1; + } + + if ((s_usart_pin_map[idx].rts == rx_flow) && flag) { + pin_mux(s_usart_pin_map[idx].rts, s_usart_pin_map[idx].function); + } else if ((s_usart_pin_map[idx].rts == rx_flow) && (flag == 0)) { + pin_mux(s_usart_pin_map[idx].rts, 0xff); + } else { + return -1; + } + + return 0; +} + +#endif + +#if CONFIG_SPI +struct { + uint32_t base; + uint32_t irq; +} + +const sg_spi_config[CONFIG_SPI_NUM] = { + {CSKY_SPI0_BASE, SPI0_IRQn}, + {CSKY_SPI1_BASE, SPI1_IRQn} +}; +typedef struct { + pin_t mosi; + pin_t miso; + pin_t sclk; + pin_t ssel; + uint32_t cfg_idx; //idx of sg_iic_config[] + uint16_t function; +} spi_pin_map_t; +const static spi_pin_map_t s_spi_pin_map[] = { + { + PA2_TXD0_SPI0MISO, + PA3_RXD0_SPI0MOSI, + PA4_CTS0_PWM0_SPI0SCK_TRIG0, + PA5_RTS0_PWM1_SPI0SSN_TRIG1, + 0, + 2 + }, + { + PB3_SPI0MISO_PWM5_I2SSD, + PA6_SPI0MOSI_PWM6_SCL0, + PB2_SPI0SCK_PWM4_I2SWS, + PA7_SPI0SSN_PWM7_SDA0, + 0, + 0 + }, + { + PA22_SPI1MISO_PWM0_ADC10, + PA23_SPI1MOSI_PWM1_ADC11, + PA21_SPI1SCK_TRIG1_TXD1, + PA18_SPI1SSN0_ACMP0O, + 1, + 0 + } +}; + +/** + \param[in] instance idx, must not exceed return value of target_get_spi_count() + \brief get spi instance. + \return pointer to spi instance +*/ +int32_t target_spi_init(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel, uint32_t *base, uint32_t *irq) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_spi_pin_map) / sizeof(spi_pin_map_t); idx++) { + if (s_spi_pin_map[idx].mosi == mosi && s_spi_pin_map[idx].miso == miso + && s_spi_pin_map[idx].sclk == sclk && s_spi_pin_map[idx].ssel == ssel) { + *base = sg_spi_config[s_spi_pin_map[idx].cfg_idx].base; + *irq = sg_spi_config[s_spi_pin_map[idx].cfg_idx].irq; + /*pinmux*/ + pin_mux(s_spi_pin_map[idx].mosi, s_spi_pin_map[idx].function); + pin_mux(s_spi_pin_map[idx].miso, s_spi_pin_map[idx].function); + pin_mux(s_spi_pin_map[idx].sclk, s_spi_pin_map[idx].function); + pin_mux(s_spi_pin_map[idx].ssel, s_spi_pin_map[idx].function); + + return s_spi_pin_map[idx].cfg_idx; + } + } + + return -1; + +} + +#endif + +#if CONFIG_AES +struct { + uint32_t base; + uint32_t irq; +} +const sg_aes_config[CONFIG_AES_NUM] = { + {CSKY_AES_BASE, AES_IRQn} +}; + +/** + \brief get aes instance count. + \return aes instance count +*/ +int32_t target_get_aes_count(void) +{ + return CONFIG_AES_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_aes_count() + \brief get aes instance. + \return pointer to aes instance +*/ +int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_aes_count()) { + return NULL; + } + + *base = sg_aes_config[idx].base; + *irq = sg_aes_config[idx].irq; + return idx; +} + +#endif + +#if CONFIG_RSA +struct { + uint32_t base; + uint32_t irq; +} +const sg_rsa_config[CONFIG_RSA_NUM] = { + {CSKY_RSA_BASE, RSA_IRQn} +}; + +/** + \brief get rsa instance count. + \return rsa instance count +*/ +int32_t target_get_rsa_count(void) +{ + return CONFIG_RSA_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_rsa_count() + \brief get rsa instance. + \return pointer to rsa instance +*/ +int32_t target_get_rsa(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_rsa_count()) { + return NULL; + } + + *base = sg_rsa_config[idx].base; + *irq = sg_rsa_config[idx].irq; + return idx; +} + +#endif + +#if CONFIG_EFLASH +struct { + uint32_t base; + eflash_info_t info; +} +const sg_eflash_config[CONFIG_EFLASH_NUM] = { + {CSKY_EFLASH_CONTROL_BASE, {0x10000000, 0x1003f800, 0x1fc}} +}; + +/** + \brief get eflash instance count. + \return eflash instance count +*/ +int32_t target_get_eflash_count(void) +{ + return CONFIG_EFLASH_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_eflash_count() + \brief get eflash instance. + \return pointer to eflash instance +*/ +int32_t target_get_eflash(int32_t idx, uint32_t *base, eflash_info_t *info) +{ + if (idx >= target_get_eflash_count()) { + return NULL; + } + + *base = sg_eflash_config[idx].base; + info->start = sg_eflash_config[idx].info.start; + info->end = sg_eflash_config[idx].info.end; + info->sector_count = sg_eflash_config[idx].info.sector_count; + return idx; +} + +#endif + +#if CONFIG_WDT +struct { + uint32_t base; + uint32_t irq; +} +const sg_wdt_config[CONFIG_WDT_NUM] = { + {CSKY_WDT_BASE, WDT_IRQn} +}; + +int32_t target_get_wdt_count(void) +{ + return CONFIG_WDT_NUM; +} + +int32_t target_get_wdt(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_wdt_count()) { + return NULL; + } + + *base = sg_wdt_config[idx].base; + *irq = sg_wdt_config[idx].irq; + return idx; +} +#endif + +#if CONFIG_DMAC +struct { + uint32_t base; + uint32_t irq; +} +const sg_dmac_config[CONFIG_DMAC_NUM] = { + {CSKY_DMAC0_BASE, SEU_DMAC_IRQn}, + {CSKY_DMAC1_BASE, NONSEU_DMAC_IRQn} +}; + +int32_t target_get_dmac_count(void) +{ + return CONFIG_DMAC_NUM; +} + +int32_t target_get_dmac(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_dmac_count()) { + return NULL; + } + + *base = sg_dmac_config[idx].base; + *irq = sg_dmac_config[idx].irq; + return idx; +} +#endif + +#if CONFIG_IIC + + +struct { + uint32_t base; + uint32_t irq; +} +const sg_iic_config[CONFIG_IIC_NUM] = { + {CSKY_I2C0_BASE, I2C0_IRQn}, + {CSKY_I2C1_BASE, I2C1_IRQn} +}; + + +typedef struct { + pin_t scl; + pin_t sda; + uint16_t cfg_idx; //idx of sg_iic_config[] + uint16_t function; +} iic_pin_map_t; +const static iic_pin_map_t s_iic_pin_map[] = { + { + PB0_SCL0_PWM2_I2SMCLK, + PB1_SDA0_PWM3_I2SSCK, + 0, + 0 + }, + { + PA6_SPI0MOSI_PWM6_SCL0, + PA7_SPI0SSN_PWM7_SDA0, + 0, + 2 + }, + { + PC0_SCL1_CTS1_PWM10_ADC14, + PC1_SDA1_RTS1_PWM11_ADC15, + 1, + 0 + } +}; + + +/** + \param[in] instance idx, must not exceed return value of target_get_iic_count() + \brief get iic instance. + \return pointer to iic instance +*/ +int32_t target_iic_init(pin_t scl, pin_t sda, uint32_t *base, uint32_t *irq) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_iic_pin_map) / sizeof(iic_pin_map_t); idx++) { + if (s_iic_pin_map[idx].scl == scl && s_iic_pin_map[idx].sda == sda) { + *base = sg_iic_config[s_iic_pin_map[idx].cfg_idx].base; + *irq = sg_iic_config[s_iic_pin_map[idx].cfg_idx].irq; + /*pinmux*/ + if (s_iic_pin_map[idx].cfg_idx == 0) { + pin_mux(s_iic_pin_map[idx].scl, s_iic_pin_map[idx].function); + pin_mux(s_iic_pin_map[idx].sda, s_iic_pin_map[idx].function); + } + return s_iic_pin_map[idx].cfg_idx; + } + } + + return -1; +} + +#endif + +#if CONFIG_PWM +struct { + uint32_t base; + uint32_t irq; +} +const sg_pwm_config[CONFIG_PWM_NUM] = { + {CSKY_PWM_BASE, PWM_IRQn}, +}; + +typedef struct { + pin_t pwm_pin; + uint32_t cfg_idx; //idx of sg_pwm_config[] + uint32_t ch_num; + uint16_t function; +} pwm_pin_map_t; +const static pwm_pin_map_t s_pwm_pin_map[] = { + {PA4_CTS0_PWM0_SPI0SCK_TRIG0, 0, 0, 1}, + {PA5_RTS0_PWM1_SPI0SSN_TRIG1, 0, 0, 1}, + {PB0_SCL0_PWM2_I2SMCLK, 0, 1, 1}, + {PB1_SDA0_PWM3_I2SSCK, 0, 1, 1}, + + {PB2_SPI0SCK_PWM4_I2SWS, 0, 2, 1}, + {PB3_SPI0MISO_PWM5_I2SSD, 0, 2, 1}, + {PA6_SPI0MOSI_PWM6_SCL0, 0, 3, 1}, + {PA7_SPI0SSN_PWM7_SDA0, 0, 3, 1}, + + {PA12_PWM8_TCK_ADC4, 0, 4, 0}, + {PA13_PWM9_TMS_ADC5, 0, 4, 0}, + {PA14_PWM10_ADC6, 0, 5, 0}, + {PA15_PWM11_ADC7, 0, 5, 0}, + + {PA22_SPI1MISO_PWM0_ADC10, 0, 0, 1}, + {PA23_SPI1MOSI_PWM1_ADC11, 0, 0, 1}, + {PC0_SCL1_CTS1_PWM10_ADC14, 0, 5, 2}, + {PC1_SDA1_RTS1_PWM11_ADC15, 0, 5, 2} + +}; + +/** + \param[in] instance idx, must not exceed return value of target_get_pwm_count() + \brief get pwm instance. + \return pointer to pwm instance +*/ +int32_t target_pwm_init(pin_t pwm_pin, uint32_t *ch_num, uint32_t *base, uint32_t *irq) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_pwm_pin_map) / sizeof(pwm_pin_map_t); idx++) { + if (s_pwm_pin_map[idx].pwm_pin == pwm_pin) { + *base = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].base; + *irq = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].irq; + *ch_num = s_pwm_pin_map[idx].ch_num; + /*pinmux*/ + pin_mux(s_pwm_pin_map[idx].pwm_pin, s_pwm_pin_map[idx].function); + return s_pwm_pin_map[idx].cfg_idx; + } + } + + return -1; +} + +#endif + +#if CONFIG_SHA +struct { + uint32_t base; + uint32_t irq; +} +const sg_sha_config[CONFIG_SHA_NUM] = { + {CSKY_SHA_BASE, SHA_IRQn} +}; + +/** + \brief get sha instance count. + \return sha instance count +*/ +int32_t target_get_sha_count(void) +{ + return CONFIG_SHA_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_sha_count() + \brief get sha instance. + \return pointer to sha instance +*/ +int32_t target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_sha_count()) { + return NULL; + } + + *base = sg_sha_config[idx].base; + *irq = sg_sha_config[idx].irq; + return idx; +} + +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/ck_sys_freq.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/ck_sys_freq.h new file mode 100644 index 000000000..551ccd3d3 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/ck_sys_freq.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file ck_sys_freq.h + * @brief header file for setting system frequency. + * @version V1.0 + * @date 18. July 2017 + ******************************************************************************/ +#ifndef _CK_SYS_FREQ_H_ +#define _CK_SYS_FREQ_H_ + +#include +#include "soc.h" + +#define PMU_MCLK_SEL (CSKY_CLKGEN_BASE + 0x4) +#define MCLK_REG_VAL 0x8UL + +#define PMU_CLK_STABLE (CSKY_CLKGEN_BASE + 0x18) +#define PMU_PLL_CTRL (CSKY_CLKGEN_BASE + 0x2c) + +#define TRC_ADDR (CSKY_OTP_BASE + 0x20) +#define TRC_REG_VAL 0x1UL + +#define EXTERNAL_CLK_SOURCE 0x8UL +#define EXTERNAL_CLK_16M (EXTERNAL_CLK_SOURCE * 2) +#define EXTERNAL_CLK_24M (EXTERNAL_CLK_SOURCE * 3) +#define EXTERNAL_CLK_32M (EXTERNAL_CLK_SOURCE * 4) +#define EXTERNAL_CLK_40M (EXTERNAL_CLK_SOURCE * 5) +#define EXTERNAL_CLK_48M (EXTERNAL_CLK_SOURCE * 6) + +#define CLK_8M_REG_VAL 0xc0202UL +#define CLK_16M_REG_VAL 0xc0204UL +#define CLK_24M_REG_VAL 0xc0206UL +#define CLK_32M_REG_VAL 0xc0208UL +#define CLK_40M_REG_VAL 0xc020aUL +#define CLK_48M_REG_VAL 0xc020cUL + +typedef enum { + IHS_CLK = 0, //internal high speed clock + EHS_CLK = 1 //external high speed clock +} clk_gen_t; + +typedef enum { + CLK_8M = 0, + CLK_16M = 1, + CLK_24M = 2, + CLK_32M = 3, + CLK_40M = 4, + CLK_48M = 5 +} clk_val_t; + +void ck_set_sys_freq (clk_gen_t source, clk_val_t val); + +#endif /* _CK_SYS_FREQ_H_ */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/pin_name.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/pin_name.h new file mode 100644 index 000000000..6a7b0ba8c --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/pin_name.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file pin_name.h + * @brief header file for the pin_name + * @version V1.0 + * @date 23. August 2017 + ******************************************************************************/ +#ifndef _PINNAMES_H +#define _PINNAMES_H + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PA0_TRIG0_ACMP1P_TCK = 0, + PA1_TRIG1_ACMP1N_TMS, + PA2_TXD0_SPI0MISO, + PA3_RXD0_SPI0MOSI, + PA4_CTS0_PWM0_SPI0SCK_TRIG0, + PA5_RTS0_PWM1_SPI0SSN_TRIG1, + + PB0_SCL0_PWM2_I2SMCLK, + PB1_SDA0_PWM3_I2SSCK, + PB2_SPI0SCK_PWM4_I2SWS, + PB3_SPI0MISO_PWM5_I2SSD, + + PA6_SPI0MOSI_PWM6_SCL0, + PA7_SPI0SSN_PWM7_SDA0, + PA8_WKUP_ADC0_ACMP0P, + PA9_BOOT_ADC1_PWMFAULT, + PA10_ADC2_TXD0, + PA11_ACMP0N_ADC3_RXD0, + + PA12_PWM8_TCK_ADC4, + PA13_PWM9_TMS_ADC5, + PA14_PWM10_ADC6, + PA15_PWM11_ADC7, + PA16_RXD1_ADC8, + PA17_TXD1_ADC9, + PA18_SPI1SSN0_ACMP0O, + PA19_SPI1SSN1_ACMP1O, + PA20_SPI1SSN2_TRIG0_RXD1, + PA21_SPI1SCK_TRIG1_TXD1, + PA22_SPI1MISO_PWM0_ADC10, + PA23_SPI1MOSI_PWM1_ADC11, + PA24_TXD2_I2SMCLK_SPI1SSN0, + PA25_RXD2_I2SSCK_SPI1SSN1, + PA26_CTS2_I2SWS_ADC12, + PA27_RTS2_I2SSD_ADC13, + + PC0_SCL1_CTS1_PWM10_ADC14, + PC1_SDA1_RTS1_PWM11_ADC15, + +} +pin_name_t; + +typedef enum { + PORTA = 0, + PORTB = 1, +} port_name_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/pinmux.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/pinmux.h new file mode 100644 index 000000000..d937cb34b --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/pinmux.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file pinmux.h + * @brief Header file for the pinmux + * @version V1.0 + * @date 23. August 2017 + ******************************************************************************/ +#ifndef HOBBIT1_2_PINMUX_H +#define HOBBIT1_2_PINMUX_H + +#include +#include "pin_name.h" + +void hobbit_ioreuse_initial(void); +int32_t pin_mux(pin_name_t pin, uint16_t function); + +/*IOMUX0L function definition */ + + +/* IOMUX0H function definition */ + +#define PA16_UART1_RX 0x00010000 +#define PA17_UART1_TX 0x00020000 + + +#define PA20_UART1_RX 0x00020000 +#define PA21_UART1_TX 0x00080000 + +//use for spi eth +#define PA3_SPI0MOSI 0x00000080 +#define PA2_SPI0MISO 0x00000020 +#define PA4_SPI0SCK 0x00000200 +#define PA5_SPI0SSN 0x00000800 + +#define PA23_SPI1MOSI 0x00800000 +#define PA22_SPI1MISO 0x00400000 +#define PA21_SPI1SCK 0x00200000 +#define PA18_SPI1SSN0 0x00040000 + + + + +/* IOMUX1L function definition */ + +/* flag as identification */ +#define GPIO_SET_BIT0 0x00000001 +#define GPIO_SET_BIT1 0x00000002 +#define GPIO_SET_BIT2 0x00000004 +#define GPIO_SET_BIT3 0x00000008 +#define GPIO_SET_BIT4 0x00000010 +#define GPIO_SET_BIT5 0x00000020 +#define GPIO_SET_BIT6 0x00000040 +#define GPIO_SET_BIT7 0x00000080 +#define GPIO_SET_BIT8 0x00000100 +#define GPIO_SET_BIT9 0x00000200 +#define GPIO_SET_BIT10 0x00000400 +#define GPIO_SET_BIT11 0x00000800 +#define GPIO_SET_BIT12 0x00001000 +#define GPIO_SET_BIT13 0x00002000 +#define GPIO_SET_BIT14 0x00004000 +#define GPIO_SET_BIT15 0x00008000 +#define GPIO_SET_BIT16 0x00010000 +#define GPIO_SET_BIT17 0x00020000 +#define GPIO_SET_BIT18 0x00040000 +#define GPIO_SET_BIT19 0x00080000 +#define GPIO_SET_BIT20 0x00100000 +#define GPIO_SET_BIT21 0x00200000 +#define GPIO_SET_BIT22 0x00400000 +#define GPIO_SET_BIT23 0x00800000 +#define GPIO_SET_BIT24 0x01000000 +#define GPIO_SET_BIT25 0x02000000 +#define GPIO_SET_BIT26 0x04000000 +#define GPIO_SET_BIT27 0x08000000 +#define GPIO_SET_BIT28 0x10000000 +#define GPIO_SET_BIT29 0x20000000 +#define GPIO_SET_BIT30 0x40000000 +#define GPIO_SET_BIT31 0x80000000 + + + + +/****************************************************************************** + * hobbit1_2 gpio control and gpio reuse function + * selecting regester adddress + ******************************************************************************/ + +#define HOBBIT1_2_GIPO0_PORTCTL_REG 0x50006008 +#define HOBBIT1_2_GIPO1_PORTCTL_REG 0x50009008 +#define HOBBIT1_2_IOMUX0L_REG 0x50006100 +#define HOBBIT1_2_IOMUX0H_REG 0x50006104 +#define HOBBIT1_2_IOMUX1L_REG 0x50006108 + + +/*************basic gpio reuse v1.0******************************************** + * UART1(PA16,PA17) for bootrom + * UART1(PA20,PA21) for console + ******************************************************************************/ +#define GPIO0_REUSE_EN (0x00000000) +#define GPIO0_REUSE_DIS (GPIO_SET_BIT16 | GPIO_SET_BIT17) + +#define GPIO1_REUSE_EN (0x00000000) +#define IOMUX0L_FUNCTION_SEL (0x00000000) +#define IOMUX0H_FUNCTION_SEL (0x00000000) +#define IOMUX1L_FUNCTION_SEL (0x00000000) + +#endif /* HOBBIT_PINMUX_H */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/soc.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/soc.h new file mode 100644 index 000000000..a63d9820e --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/include/soc.h @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/**************************************************************************//** + * @file soc.h + * @brief CSI Core Peripheral Access Layer Header File for + * CSKYSOC Device Series + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + + +#ifndef SOC_H +#define SOC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SYSTEM_CLOCK +#define SYSTEM_CLOCK (24000000) +#endif + +#ifndef IHS_VALUE +#define IHS_VALUE (8000000) +#endif + +#ifndef EHS_VALUE +#define EHS_VALUE (8000000) +#endif +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ + /* ---------------------- CSKYCK801 Specific Interrupt Numbers --------------------- */ + GPIOA_IRQn = 0, /* gpio Interrupt */ + CORET_IRQn = 1, /* core Timer Interrupt */ + TIMA0_IRQn = 2, /* timerA0 Interrupt */ + TIMA1_IRQn = 3, /* timerA1 Interrupt */ + I2S_IRQn = 4, /* i2s Interrupt */ + WDT_IRQn = 5, /* wdt Interrupt */ + UART0_IRQn = 6, /* uart0 Interrupt */ + UART1_IRQn = 7, /* uart1 Interrupt */ + UART2_IRQn = 8, /* uart2 Interrupt */ + I2C0_IRQn = 9, /* i2c0 Interrupt */ + I2C1_IRQn = 10, /* i2c1 Interrupt */ + SPI1_IRQn = 11, /* spi0 Interrupt */ + SPI0_IRQn = 12, /* spi1 Interrupt */ + RTC_IRQn = 13, /* rtc Interrupt */ + EXTWAK_IRQn = 14, /* extwakeup Interrupt */ + ADC_IRQn = 15, /* adc interrupt */ + CMP_IRQn = 16, /* cmp interrupt */ + SEU_DMAC_IRQn = 17, /* seu dmac Interrupt */ + POWM_IRQn = 18, /* powm Interrupt */ + PWM_IRQn = 19, /* pwm Interrupt */ + SYS_RESET_IRQn = 20, /* system reset Interrupt */ + REV_IRQn = 21, /* rev Interrupt */ + NONSEU_DMAC_IRQn = 22, /* nonuseu dmac Interrupt */ + TIMB0_IRQn = 23, /* timerB0 Interrupt */ + TIMB1_IRQn = 24, /* timerB1 Interrupt */ + RTC1_IRQn = 25, /* rtc1 Interrupt */ + AES_IRQn = 26, /* aes Interrupt */ + GPIOB_IRQn = 27, /* trng Interrupt */ + RSA_IRQn = 28, /* rsa Interrupt */ + SHA_IRQn = 29, /* sha Interrupt */ +} +IRQn_Type; + + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of the CK801 Processor and Core Peripherals ------- */ +#define __CK802_REV 0x0000U /* Core revision r0p0 */ +#define __MGU_PRESENT 0 /* MGU present or not */ +#define __NVIC_PRIO_BITS 2 /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ + +#include "core_ck802.h" /* Processor and core peripherals */ +#include "stdint.h" + +typedef enum { + CKENUM_DMA_UART0_RX, + CKENUM_DMA_UART0_TX, + CKENUM_DMA_UART1_RX, + CKENUM_DMA_UART1_TX, + CKENUM_DMA_ADC_RX, + CKENUM_DMA_ADC_TX, + CKENUM_DMA_SPI1_RX, + CKENUM_DMA_SPI1_TX, + CKENUM_DMA_SPI0_RX, + CKENUM_DMA_SPI0_TX, + CKENUM_DMA_IIC_RX, + CKENUM_DMA_IIC_TX, + CKENUM_DMA_IIC1_RX, + CKENUM_DMA_IIC1_TX, + CKENUM_DMA_IIS_RX, + CKENUM_DMA_IIS_TX, + CKENUM_DMA_MEMORY +} ckenum_dma_device_e; + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ +#if 0 + +/* ================================================================================ */ +/* ============== Universal Asyncronous Receiver / Transmitter (UART) ============= */ +/* ================================================================================ */ +typedef struct { + union { + __IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */ + __OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */ + __IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */ + }; + union { + __IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */ + __IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */ + }; + __IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */ + __IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */ + __IOM uint32_t MCR; /* Offset: 0x010 (R/W) Modem control register */ + __IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */ + __IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */ + uint32_t RESERVED1[24]; + __IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */ +} CSKY_UART_TypeDef; + + +/* ================================================================================ */ +/* ============== Inter-Integrated Circuit (IIC) ============= */ +/* ================================================================================ */ +typedef struct { + __IOM uint32_t IC_CON; /* Offset: 0x000 (R/W) Receive buffer register */ + __IOM uint32_t IC_TAR; /* Offset: 0x004 (R/W) Transmission hold register */ + __IOM uint32_t IC_SAR; /* Offset: 0x008 (R/W) Clock frequency division low section register */ + __IOM uint32_t IC_HS_MADDR; /* Offset: 0x00c (R/W) Clock frequency division high section register */ + __IOM uint32_t IC_DATA_CMD; /* Offset: 0x010 (R/W) Interrupt enable register */ + __IOM uint32_t IC_SS_SCL_HCNT; /* Offset: 0x014 (R/W) Interrupt indicia register */ + __IOM uint32_t IC_SS_SCL_LCNT; /* Offset: 0x018 (R/W) Transmission control register */ + __IOM uint32_t IC_FS_SCL_HCNT; /* Offset: 0x01c (R/W) Modem control register */ + __IOM uint32_t IC_FS_SCL_LCNT; /* Offset: 0x020 (R/W) Transmission state register */ + __IOM uint32_t IC_HS_SCL_HCNT; /* Offset: 0x024 (R/W) Transmission state register */ + __IOM uint32_t IC_HS_SCL_LCNT; /* Offset: 0x028 (R/W) Transmission state register */ + __IOM uint32_t IC_INTR_STAT; /* Offset: 0x02c (R) Transmission state register */ + __IOM uint32_t IC_INTR_MASK; /* Offset: 0x030 (R/W) Transmission state register */ + __IOM uint32_t IC_RAW_INTR_STAT; /* Offset: 0x034 (R) Transmission state register */ + __IOM uint32_t IC_RX_TL; /* Offset: 0x038 (R/W) Transmission state register */ + __IOM uint32_t IC_TX_TL; /* Offset: 0x03c (R/W) Transmission state register */ + __IOM uint32_t IC_CLR_INTR; /* Offset: 0x040 (R) Transmission state register */ + __IOM uint32_t IC_CLR_RX_UNDER; /* Offset: 0x044 (R) Transmission state register */ + __IOM uint32_t IC_CLR_RX_OVER; /* Offset: 0x048 (R) Transmission state register */ + __IOM uint32_t IC_CLR_TX_OVER; /* Offset: 0x04c (R) Transmission state register */ + __IOM uint32_t IC_CLR_RD_REQ; /* Offset: 0x050 (R) Transmission state register */ + __IOM uint32_t IC_CLR_TX_ABRT; /* Offset: 0x054 (R) Transmission state register */ + __IOM uint32_t IC_CLR_RX_DONE; /* Offset: 0x058 (R) Transmission state register */ + __IOM uint32_t IC_CLR_ACTIVITY; /* Offset: 0x05c (R) Transmission state register */ + __IOM uint32_t IC_CLR_STOP_DET; /* Offset: 0x060 (R) Transmission state register */ + __IOM uint32_t IC_CLR_START_DET; /* Offset: 0x064 (R) Transmission state register */ + __IOM uint32_t IC_CLR_GEN_CALL; /* Offset: 0x068 (R) Transmission state register */ + __IOM uint32_t IC_ENABLE; /* Offset: 0x06c (R/W) Transmission state register */ + __IOM uint32_t IC_STATUS; /* Offset: 0x070 (R) Transmission state register */ + __IOM uint32_t IC_TXFLR; /* Offset: 0x074 (R) Transmission state register */ + __IOM uint32_t IC_RXFLR; /* Offset: 0x078 (R) Transmission state register */ + uint32_t RESERVED; /* Offset: 0x014 (R/ ) Transmission state register */ + __IOM uint32_t IC_TX_ABRT_SOURCE; /* Offset: 0x080 (R/W) Transmission state register */ + __IOM uint32_t IC_SAR1; /* Offset: 0x084 (R/W) Transmission state register */ + __IOM uint32_t IC_DMA_CR; /* Offset: 0x088 (R/W) Transmission state register */ + __IOM uint32_t IC_DMA_TDLR; /* Offset: 0x08c (R/W) Transmission state register */ + __IOM uint32_t IC_DMA_RDLR; /* Offset: 0x090 (R/W) Transmission state register */ + __IOM uint32_t IC_SAR2; /* Offset: 0x094 (R/W) Transmission state register */ + __IOM uint32_t IC_SAR3; /* Offset: 0x098 (R/W) Transmission state register */ + __IOM uint32_t IC_MULTI_SLAVE; /* Offset: 0x09c (R/W) Transmission state register */ + __IOM uint32_t IC_GEN_CALL_EN; /* Offset: 0x0a0 (R/W) Transmission state register */ + +} CSKY_IIC_TypeDef; + + +/* ================================================================================ */ +/* ============== TIMER ============= */ +/* ================================================================================ */ +typedef struct { + __IOM uint32_t TxLoadCount; /* Offset: 0x000 (R/W) Receive buffer register */ + __IOM uint32_t TxCurrentValue; /* Offset: 0x004 (R) Transmission hold register */ + __IOM uint32_t TxControl; /* Offset: 0x008 (R/W) Clock frequency division low section register */ + __IOM uint32_t TxEOI; /* Offset: 0x00c (R) Clock frequency division high section register */ + __IOM uint32_t TxIntStatus; /* Offset: 0x010 (R) Interrupt enable register */ + +} CSKY_TIMER_TypeDef; + +/* ================================================================================ */ +/* ============== TIMER Control ============= */ +/* ================================================================================ */ +typedef struct { + __IOM uint32_t TimersIntStatus; /* Offset: 0x000 (R) Interrupt indicia register */ + __IOM uint32_t TimerEOI; /* Offset: 0x004 (R) Transmission control register */ + __IOM uint32_t TimerRawIntStatus; /* Offset: 0x008 (R) Modem control register */ + +} CSKY_TIMER_Control_TypeDef; + + +/* ================================================================================ */ +/* ============== GPIO ============= */ +/* ================================================================================ */ +typedef struct { + __IOM uint32_t SWPORT_DR; /* Offset: 0x000 (R/W) Interrupt indicia register */ + __IOM uint32_t SWPORT_DDR; /* Offset: 0x004 (R/W) Interrupt indicia register */ + __IOM uint32_t PORT_CTL; /* Offset: 0x008 (R/W) Interrupt indicia register */ +} CKStruct_GPIO, *PCKStruct_GPIO; + +typedef struct { + __IOM uint32_t SHA_CON; /* Offset: 0x000 (R/W) Control register */ + __IOM uint32_t SHA_INTSTATE; /* Offset: 0x004 (R/W) Instatus register */ + __IOM uint32_t SHA_H0L; /* Offset: 0x008 (R/W) H0L register */ + __IOM uint32_t SHA_H1L; /* Offset: 0x00c (R/W) H1L register */ + __IOM uint32_t SHA_H2L; /* Offset: 0x010 (R/W) H2L register */ + __IOM uint32_t SHA_H3L; /* Offset: 0x014 (R/W) H3L register */ + __IOM uint32_t SHA_H4L; /* Offset: 0x018 (R/W) H4L register */ + __IOM uint32_t SHA_H5L; /* Offset: 0x01c (R/W) H5L register */ + __IOM uint32_t SHA_H6L; /* Offset: 0x020 (R/W) H6L register */ + __IOM uint32_t SHA_H7L; /* Offset: 0x024 (R/W) H7L register */ + __IOM uint32_t SHA_H0H; /* Offset: 0x028 (R/W) H0H register */ + __IOM uint32_t SHA_H1H; /* Offset: 0x02c (R/W) H1H register */ + __IOM uint32_t SHA_H2H; /* Offset: 0x030 (R/W) H2H register */ + __IOM uint32_t SHA_H3H; /* Offset: 0x034 (R/W) H3H register */ + __IOM uint32_t SHA_H4H; /* Offset: 0x038 (R/W) H4H register */ + __IOM uint32_t SHA_H5H; /* Offset: 0x03c (R/W) H5H register */ + __IOM uint32_t SHA_H6H; /* Offset: 0x040 (R/W) H6H register */ + __IOM uint32_t SHA_H7H; /* Offset: 0x044 (R/W) H7H register */ + __IOM uint32_t SHA_DATA1; /* Offset: 0x048 (R/W) DATA1 register */ + uint32_t REV[15]; + __IOM uint32_t SHA_DATA2; /* Offset: 0x088 (R/W) DATA2 register */ +} CSKY_SHA_TypeDef; + + +#endif + +#define CONFIG_PMU_NUM 1 +#define CONFIG_CRC_NUM 1 +#define CONFIG_EFLASH_NUM 1 +#define CONFIG_IIC_NUM 2 +#define CONFIG_TRNG_NUM 1 +#define CONFIG_AES_NUM 1 +#define CONFIG_RSA_NUM 1 +#define CONFIG_SHA_NUM 1 +#define CONFIG_SPI_NUM 2 +#define CONFIG_PWM_NUM 6 +#define CONFIG_TIMER_NUM 4 +#define CONFIG_RTC_NUM 2 +#define CONFIG_WDT_NUM 1 +#define CONFIG_DMAC_NUM 2 +#define CONFIG_GPIO_NUM 2 +#define CONFIG_GPIO_PIN_NUM 32 +#define CONFIG_USART_NUM 3 +#define CONFIG_ETH_NUM 2 + +/* ================================================================================ */ +/* ================ Peripheral memory map ================ */ +/* ================================================================================ */ +/* -------------------------- CHIP memory map ------------------------------- */ +#define CSKY_EFLASH_BASE (0x10000000UL) +#define CSKY_SRAM_BASE (0x60000000UL) + +/* AHB */ +#define CSKY_AHB_ARB_BASE (0x40000000UL) +#define CSKY_DMAC0_BASE (0x40001000UL) +#define CSKY_CLKGEN_BASE (0x40002000UL) +#define CSKY_CRC_BASE (0x40003000UL) +#define CSKY_DMAC1_BASE (0x40004000UL) +#define CSKY_OTP_BASE (0x4003F000UL) +#define CSKY_AES_BASE (0x40006000UL) +#define CSKY_SRAM_SASC_BASE (0x40007000UL) +#define CSKY_SHA_BASE (0x40008000UL) +#define CSKY_TRNG_BASE (0x40009000UL) +#define CSKY_RSA_BASE (0x4000a000UL) +#define CSKY_EFLASH_CONTROL_BASE (0x4003f000UL) +#define CSKY_APB0_BRIDGE_BASE (0x50000000UL) +#define CSKY_APB1_BRIDGE_BASE (0x50010000UL) + +/* APB0 */ +#define CSKY_WDT_BASE (0x50001000UL) +#define CSKY_SPI0_BASE (0x50002000UL) +#define CSKY_RTC0_BASE (0x50003000UL) +#define CSKY_UART0_BASE (0x50004000UL) +#define CSKY_UART1_BASE (0x50005000UL) +#define CSKY_GPIO0_BASE (0x50006000UL) +#define CSKY_I2C0_BASE (0x50007000UL) +#define CSKY_I2S_BASE (0x50008000UL) +#define CSKY_GPIO1_BASE (0x50009000UL) +#define CSKY_SIPC_BASE (0x5000a000UL) + +/* APB1 */ +#define CSKY_TIM0_BASE (0x50011000UL) +#define CSKY_SPI1_BASE (0x50012000UL) +#define CSKY_I2C1_BASE (0x50013000UL) +#define CSKY_PWM_BASE (0x50014000UL) +#define CSKY_UART2_BASE (0x50015000UL) +#define CSKY_ADC_CTL_BASE (0x50016000UL) +#define CSKY_CMP_CTL_BASE (0x50017000UL) +#define CSKY_ETB_BASE (0x50018000UL) +#define CSKY_TIM1_BASE (0x50019000UL) +#define CSKY_RTC1_BASE (0x5001a000UL) + +#define SHA_CONTEXT_SIZE 224 + +/* ================================================================================ */ +/* ================ Peripheral declaration ================ */ +/* ================================================================================ */ +#define CSKY_UART1 (( CSKY_UART_TypeDef *) CSKY_UART1_BASE) +#define CSKY_SHA (( CSKY_SHA_TypeDef *) CSKY_SHA_BASE) + +#include + + +#ifdef __cplusplus +} +#endif + +#endif /* SOC_H */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/isr.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/isr.c new file mode 100644 index 000000000..757ede829 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/isr.c @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file isr.c + * @brief source file for the interrupt server route + * @version V1.0 + * @date 25. August 2017 + ******************************************************************************/ +#include +#include "config.h" +#include "soc.h" +#ifndef CONFIG_KERNEL_NONE +#include +#endif + +extern void dw_usart_irqhandler(int32_t idx); +extern void dw_timer_irqhandler(int32_t idx); +extern void dw_gpio_irqhandler(int32_t idx); +extern void dw_iic_irqhandler(int32_t idx); +extern void ck_rtc_irqhandler(int32_t idx); +extern void dw_spi_irqhandler(int32_t idx); +extern void dw_wdt_irqhandler(int32_t idx); +extern void ck_dma_irqhandler(int32_t idx); +extern void ck_aes_irqhandler(int32_t idx); +extern void ck_sha_irqhandler(int32_t idx); +extern void xPortSysTickHandler( void ); + +#define readl(addr) \ + ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) + +#define ATTRIBUTE_ISR + +#ifndef CONFIG_KERNEL_NONE +#define CSI_INTRPT_ENTER() csi_kernel_intrpt_enter() +#define CSI_INTRPT_EXIT() csi_kernel_intrpt_exit() +#else +#define CSI_INTRPT_ENTER() +#define CSI_INTRPT_EXIT() +#endif + + + +ATTRIBUTE_ISR void CORET_IRQHandler(void) +{ + readl(0xE000E010); + + xPortSysTickHandler(); +} + +#if defined(CONFIG_USART) +ATTRIBUTE_ISR void USART0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void USART1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(1); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void USART2_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(2); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void USART3_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(3); + CSI_INTRPT_EXIT(); +} + +#endif + +#if defined(CONFIG_TIMER) +ATTRIBUTE_ISR void TIMA0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void TIMA1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(1); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void TIMB0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(2); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void TIMB1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(3); + CSI_INTRPT_EXIT(); +} + +#endif + +#if defined(CONFIG_GPIO) + +ATTRIBUTE_ISR void GPIO0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_gpio_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void GPIO1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_gpio_irqhandler(1); + CSI_INTRPT_EXIT(); +} + +#endif + +#if defined(CONFIG_IIC) +ATTRIBUTE_ISR void I2C0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_iic_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void I2C1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_iic_irqhandler(1); + CSI_INTRPT_EXIT(); +} +#endif + +#if defined(CONFIG_RTC) + +ATTRIBUTE_ISR void RTC_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_rtc_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void RTC1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_rtc_irqhandler(1); + CSI_INTRPT_EXIT(); +} +#endif + +#if defined(CONFIG_AES) + +ATTRIBUTE_ISR void AES_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_aes_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +#endif + +#if defined(CONFIG_TRNG) +ATTRIBUTE_ISR void TRNG_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + + CSI_INTRPT_EXIT(); +} +#endif + +#if defined(CONFIG_RSA) +ATTRIBUTE_ISR void RSA_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + + CSI_INTRPT_EXIT(); +} +#endif + +#if defined(CONFIG_SPI) && defined(CONFIG_GPIO) +ATTRIBUTE_ISR void SPI0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_spi_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void SPI1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_spi_irqhandler(1); + CSI_INTRPT_EXIT(); +} +#endif + +#if defined(CONFIG_WDT) +ATTRIBUTE_ISR void WDT_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_wdt_irqhandler(0); + CSI_INTRPT_EXIT(); +} +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/pinmux.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/pinmux.c new file mode 100644 index 000000000..e488cf4eb --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit1_2/pinmux.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file pinmux.c + * @brief source file for the pinmux + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include "pinmux.h" +#include "pin_name.h" + +#define readl(addr) \ + ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) + +#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) + +/******************************************************************************* + * function: hobbit_ioreuse_inital + * + * description: + * initial hobbit_pinmux + *******************************************************************************/ + +void hobbit_ioreuse_initial(void) +{ + unsigned int value; + + value = readl(HOBBIT1_2_GIPO0_PORTCTL_REG); + value &= ~(GPIO0_REUSE_DIS); + writel(value, HOBBIT1_2_GIPO0_PORTCTL_REG); +} + +int32_t pin_mux(pin_name_t pin, uint16_t function) +{ + unsigned int val = 0; + unsigned int reg_val = 0; + + uint8_t offset; + + if (function > 3) { + if (pin <= PB3_SPI0MISO_PWM5_I2SSD) { + if (pin <= PA5_RTS0_PWM1_SPI0SSN_TRIG1) { + offset = pin; + /* gpio data source select */ + val = readl(HOBBIT1_2_GIPO0_PORTCTL_REG); + val &= ~(1 << offset); + writel(val, HOBBIT1_2_GIPO0_PORTCTL_REG); + return 0; + } else if (pin >= PB0_SCL0_PWM2_I2SMCLK) { + offset = pin - 6; + /* gpio data source select */ + val = readl(HOBBIT1_2_GIPO1_PORTCTL_REG); + val &= ~(1 << offset); + writel(val, HOBBIT1_2_GIPO1_PORTCTL_REG); + return 0; + } + } + if ((pin >= PA6_SPI0MOSI_PWM6_SCL0) && (pin <= PA27_RTS2_I2SSD_ADC13)) { + offset = pin - 4; + /* gpio data source select */ + val = readl(HOBBIT1_2_GIPO0_PORTCTL_REG); + val &= ~(1 << offset); + writel(val, HOBBIT1_2_GIPO0_PORTCTL_REG); + return 0; + } + return -1; + } + + if ((pin >= PA6_SPI0MOSI_PWM6_SCL0) && (pin <= PA27_RTS2_I2SSD_ADC13)) { + offset = pin - 4; + + /* gpio data source select */ + val = readl(HOBBIT1_2_GIPO0_PORTCTL_REG); + val |= (1 << offset); + writel(val, HOBBIT1_2_GIPO0_PORTCTL_REG); + + if (pin <= PA11_ACMP0N_ADC3_RXD0) { + offset = pin; + reg_val = (0x3 << (offset * 2)); + /* reuse function select */ + val = readl(HOBBIT1_2_IOMUX0L_REG); + val &= ~(reg_val); + val |= (function << (2 * offset)); + writel(val, HOBBIT1_2_IOMUX0L_REG); + return 0; + } else { + offset = pin - 16; + reg_val = (0x3 << (offset * 2)); + /* reuse function select */ + val = readl(HOBBIT1_2_IOMUX0H_REG); + val &= ~(reg_val); + val |= (function << (2 * offset)); + writel(val, HOBBIT1_2_IOMUX0H_REG); + return 0; + } + } + + if ((pin >= PA0_TRIG0_ACMP1P_TCK) && (pin <= PB3_SPI0MISO_PWM5_I2SSD)) { + if (pin >= PB0_SCL0_PWM2_I2SMCLK) { + offset = pin - 6; + val = readl(HOBBIT1_2_GIPO1_PORTCTL_REG); + val |= (1 << offset); + writel(val, HOBBIT1_2_GIPO1_PORTCTL_REG); + + offset = pin; + reg_val = (0x3 << (offset * 2)); + /* reuse function select */ + val = readl(HOBBIT1_2_IOMUX0L_REG); + val &= ~(reg_val); + val |= (function << (2 * offset)); + writel(val, HOBBIT1_2_IOMUX0L_REG); + return 0; + } + + if (pin <= PA5_RTS0_PWM1_SPI0SSN_TRIG1) { + offset = pin; + /* gpio data source select */ + val = readl(HOBBIT1_2_GIPO0_PORTCTL_REG); + val |= (1 << offset); + writel(val, HOBBIT1_2_GIPO0_PORTCTL_REG); + + reg_val = (0x3 << (offset * 2)); + /* reuse function select */ + val = readl(HOBBIT1_2_IOMUX0L_REG); + val &= ~(reg_val); + val |= (function << (2 * offset)); + writel(val, HOBBIT1_2_IOMUX0L_REG); + return 0; + } + } + + if (pin > PA27_RTS2_I2SSD_ADC13) { + offset = pin - PC0_SCL1_CTS1_PWM10_ADC14; + reg_val = (0x3 << (offset *2)); + val = readl(HOBBIT1_2_IOMUX1L_REG); + val &= ~(reg_val); + val |= (function << (2 * offset)); + writel(val, HOBBIT1_2_IOMUX1L_REG); + } + + return -1; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/Kconfig b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/Kconfig new file mode 100644 index 000000000..e69de29bb diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/csi.mk b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/csi.mk new file mode 100644 index 000000000..55c64f7c1 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/csi.mk @@ -0,0 +1,5 @@ +TEE_INC += -I$(CSI_DIR)/csi_driver/csky/hobbit3/include +TEE_SRC += \ + $(CSI_DIR)/csi_driver/csky/hobbit3/devices.c \ + $(CSI_DIR)/csi_driver/csky/hobbit3/isr.c \ + $(CSI_DIR)/csi_driver/csky/hobbit3/pinmux.c diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/devices.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/devices.c new file mode 100644 index 000000000..a2b303513 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/devices.c @@ -0,0 +1,804 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file devices.c + * @brief source file for the devices + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pin_name.h" +#include "pinmux.h" + +//typedef int32_t int32_t; + +#define readl(addr) \ + ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) + +#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) + +#if 0 +struct { + uint32_t base; + uint32_t irq; +} +const sg_usi_config[CONFIG_USI_NUM] = { + {CSKY_USI0_BASE, USI0_IRQn}, + {CSKY_USI1_BASE, USI1_IRQn}, +}; +typedef struct { + int32_t sclk; + int32_t sd0; + int32_t sd1; + int32_t nss; + uint16_t cfg_idx; //idx of sg_usi_config[] + uint16_t function; +} usi_pin_map_t; +const static usi_pin_map_t s_usi_pin_map[] = { + { + PA10_UART0CTS_USI0SCLK_SPU4_I2C0SCL, + PA11_UART0RTS_USI0SD0_SPU5_I2C0SDA, + PA12_XX_USI0SD1_XX_UART2RX, + PA13_XX_USI0NSS_XX_UART2TX, + 0, + 1 + }, + { + PA16_SPI0CS0_PWMTRIG0_XX_USI1SCLK, + PA17_SPI0MOSI_PWMTRIG1_XX_USI1SD0, + PA18_SPI0MISO_XX_SPU6_USI1SD1, + PA19_SPI0SCK_FAULT_SPU7_USI1NSS, + 1, + 3 + }, +}; + +#endif + +struct { + uint32_t base; + uint32_t irq; +} +const static sg_usart_config[CONFIG_USART_NUM] = { + {CSKY_UART0_BASE, UART0_IRQn}, + {CSKY_UART1_BASE, UART1_IRQn}, + {CSKY_UART2_BASE, UART2_IRQn}, + {CSKY_UART3_BASE, UART3_IRQn} +}; +typedef struct { + int32_t tx; + int32_t rx; +#if 0 + int32_t cts; + int32_t rts; +#endif + uint16_t cfg_idx; //idx of sg_usart_config[] + uint16_t function; +} usart_pin_map_t; +const static usart_pin_map_t s_usart_pin_map[] = { + { + PA8_UART0TX_XX_SPU2_SIROUT0, + PA9_UART0RX_XX_SPU3_SIRIN0, + 0, + 0 + }, + { + PA21_UART1TX_PWM1_SPU9_SIROUT1, + PA20_UART1RX_PWM0_SPU8_SIRIN1, + 1, + 0 + }, + { + PA0_I2C0SCL_SPI1CS1_SPU0_UART1TX, + PA1_I2C0SDA_SPI1CS2_SPU1_UART1RX, + 1, + 4, + }, + { + PB0_UART2TX_XX_XX_SIROUT2, + PB1_UART2RX_XX_XX_SIRIN2, + 2, + 0 + }, + { + PB13_UART3TX_SPI1MISO_SPU29_SIROUT3, + PB12_UART3RX_SPI1CS0_SPU28_SIRIN3, + 3, + 0 + } +}; + +/** + \param[in] instance idx, must not exceed return value of target_get_usart_count() + \brief get usart instance. + \return pointer to usart instance +*/ + +int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) { + if (s_usart_pin_map[idx].tx == tx && s_usart_pin_map[idx].rx == rx) { + *base = sg_usart_config[s_usart_pin_map[idx].cfg_idx].base; + *irq = sg_usart_config[s_usart_pin_map[idx].cfg_idx].irq; + /*pinmux*/ + pin_mux(s_usart_pin_map[idx].tx, s_usart_pin_map[idx].function); + pin_mux(s_usart_pin_map[idx].rx, s_usart_pin_map[idx].function); + return s_usart_pin_map[idx].cfg_idx; + } + } + return -1; +} + +/** + \brief control usart flow. + \param[in] tx_flow The TX flow pin name + \param[in] rx_flow The RX flow pin name + \param[in] flag 0-disable, 1-enable. + \return 0 if setting ready ,negative for error code +*/ +int32_t target_usart_flowctrl_init(int32_t tx_flow, int32_t rx_flow, uint32_t flag) +{ +#if 0 + uint32_t idx; + + for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) { + if ((s_usart_pin_map[idx].cts == tx_flow) &&(s_usart_pin_map[idx].rts == rx_flow)) + break; + } + + if (idx >= sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t)) { + return -1; + } + + if ((s_usart_pin_map[idx].cts == tx_flow) && flag) { + pin_mux(s_usart_pin_map[idx].cts, s_usart_pin_map[idx].function); + } else if ((s_usart_pin_map[idx].cts == tx_flow) && (flag == 0)) { + pin_mux(s_usart_pin_map[idx].cts, 0xff); + } else { + return -1; + } + + if ((s_usart_pin_map[idx].rts == rx_flow) && flag) { + pin_mux(s_usart_pin_map[idx].rts, s_usart_pin_map[idx].function); + } else if ((s_usart_pin_map[idx].rts == rx_flow) && (flag == 0)) { + pin_mux(s_usart_pin_map[idx].rts, 0xff); + } else { + return -1; + } + return 0; +#endif + return 0; +} + + + +struct { + uint32_t base; + uint32_t irq; + uint32_t pin_num; + port_name_t port; +} +const sg_gpio_config[CONFIG_GPIO_NUM] = { + {CSKY_GPIO0_BASE, GPIOA_IRQn, 32, PORTA}, + {CSKY_GPIO1_BASE, GPIOB_IRQn, 16, PORTB} +}; + +typedef struct { + int32_t gpio_pin; + uint32_t cfg_idx; //idx of sg_gpio_config[] +} gpio_pin_map_t; +const static gpio_pin_map_t s_gpio_pin_map[] = { + {PA0_I2C0SCL_SPI1CS1_SPU0_UART1TX ,0}, + {PA1_I2C0SDA_SPI1CS2_SPU1_UART1RX,0}, + {PA2_QSPI0CLK_XX_XX_XX,0}, + {PA3_QSPI0MISO_XX_XX_XX,0}, + {PA4_QSPI0MOSI_XX_XX_XX,0}, + {PA5_QSPI0HOLD_XX_XX_XX,0}, + {PA6_QSPI0WP_XX_XX_XX,0}, + {PA7_QSPI0CS0_XX_XX_XX,0}, + {PA8_UART0TX_XX_SPU2_SIROUT0,0}, + {PA9_UART0RX_XX_SPU3_SIRIN0,0}, + {PA10_UART0CTS_USI0SCLK_SPU4_I2C0SCL,0}, + {PA11_UART0RTS_USI0SD0_SPU5_I2C0SDA,0}, + {PA12_XX_USI0SD1_XX_UART2RX,0}, + {PA13_XX_USI0NSS_XX_UART2TX,0}, + {PA14_SPI0CS2_FAULT_I2C1SDA_XX,0}, + {PA15_SPI0CS1_XX_I2C1SCL_XX,0}, + {PA16_SPI0CS0_PWMTRIG0_XX_USI1SCLK,0}, + {PA17_SPI0MOSI_PWMTRIG1_XX_USI1SD0,0}, + {PA18_SPI0MISO_XX_SPU6_USI1SD1,0}, + {PA19_SPI0SCK_FAULT_SPU7_USI1NSS,0}, + {PA20_UART1RX_PWM0_SPU8_SIRIN1,0}, + {PA21_UART1TX_PWM1_SPU9_SIROUT1,0}, + {PA22_UART1CTS_PWM2_SPU10_XX,0}, + {PA23_UART1RTS_PWM3_SPU11_XX,0}, + {PA24_USI1NSS_PWM4_SPU12_XX,0}, + {PA25_USI1SD1_PWM5_SPU13_XX,0}, + {PA26_USI1SD0_PWM6_SPU14_XX,0}, + {PA27_USI1SCLK_PWM7_SPU15_XX,0}, + {PA28_I2C1SCL_PWM8_SPU16_XX,0}, + {PA29_I2C1SDA_PWM9_SPU17_XX,0}, + {PA30_I2C0SDA_PWM10_SPU18_XX,0}, + {PA31_I2C0SCL_PWM11_SPU19_XX,0}, + {PB0_UART2TX_XX_XX_SIROUT2,1}, + {PB1_UART2RX_XX_XX_SIRIN2,1}, + {PB2_UART2RTS_XX_XX_XX,1}, + {PB3_UART2CTS_XX_XX_XX,1}, + {PB4_XX_XX_SPU20_UART3TX,1}, + {PB5_QSPI1CS1_XX_SPU21_UART3RX,1}, + {PB6_QSPI1WP_XX_SPU22_XX,1}, + {PB7_QSPI1HOLD_XX_SPU23_XX,1}, + {PB8_QSPI1CS0_PWMTRIG0_SPU24_XX,1}, + {PB9_QSPI1MOSI_PWMTRIG1_SPU25_XX,1}, + {PB10_QSPI1MISO_XX_SPU26_I2C1SDA,1}, + {PB11_QSPI1CLK_XX_SPU27_I2C1SCL,1}, + {PB12_UART3RX_SPI1CS0_SPU28_SIRIN3,1}, + {PB13_UART3TX_SPI1MISO_SPU29_SIROUT3,1}, + {PB14_UART3RTS_SPI1MOSI_SPU30_XX,1}, + {PB15_UART3CTS_SPI1SCK_SPU31_XX,1} +}; + +int32_t target_gpio_port_init(port_name_t port, uint32_t *base, uint32_t *irq, uint32_t *pin_num) +{ + int i; + + for (i = 0; i < CONFIG_GPIO_NUM; i++) { + if (sg_gpio_config[i].port == port) { + *base = sg_gpio_config[i].base; + *irq = sg_gpio_config[i].irq; + *pin_num = sg_gpio_config[i].pin_num; + return i; + } + } + + return -1; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_gpio_count() + \brief get gpio instance. + \return pointer to gpio instance +*/ +int32_t target_gpio_pin_init(int32_t gpio_pin, uint32_t *port_idx) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_gpio_pin_map) / sizeof(gpio_pin_map_t); idx++) { + if (s_gpio_pin_map[idx].gpio_pin == gpio_pin) { + *port_idx = s_gpio_pin_map[idx].cfg_idx; + /*pinmux*/ + pin_mux(s_gpio_pin_map[idx].gpio_pin, 0xff); + return idx; + } + } + + return -1; +} + +struct { + uint32_t base; + uint32_t irq; +} +const sg_timer_config[CONFIG_TIMER_NUM] = { + {CSKY_TIM0_BASE, TIMA0_IRQn}, + {CSKY_TIM0_BASE + 0x14, TIMA1_IRQn}, + {CSKY_TIM1_BASE, TIMB0_IRQn}, + {CSKY_TIM1_BASE + 0x14, TIMB1_IRQn}, + {CSKY_TIM2_BASE, TIM34567_IRQn}, + {CSKY_TIM2_BASE + 0x14, TIM34567_IRQn}, + {CSKY_TIM3_BASE, TIM34567_IRQn}, + {CSKY_TIM3_BASE + 0x14, TIM34567_IRQn}, + {CSKY_TIM4_BASE, TIM34567_IRQn}, + {CSKY_TIM4_BASE + 0x14, TIM34567_IRQn}, + {CSKY_TIM5_BASE, TIM34567_IRQn}, + {CSKY_TIM5_BASE + 0x14, TIM34567_IRQn}, + {CSKY_TIM6_BASE, TIM34567_IRQn}, + {CSKY_TIM6_BASE + 0x14, TIM34567_IRQn}, +}; + +int32_t target_get_timer_count(void) +{ + return CONFIG_TIMER_NUM; +} + +int32_t target_get_timer(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_timer_count()) { + return NULL; + } + + *base = sg_timer_config[idx].base; + *irq = sg_timer_config[idx].irq; + return idx; +} + +struct { + uint32_t base; + uint32_t irq; +} +const sg_sha_config[CONFIG_SHA_NUM] = { + {CSKY_SHA_BASE, SHA_IRQn} +}; + +/** + \brief get sha instance count. + \return sha instance count +*/ +int32_t target_get_sha_count(void) +{ + return CONFIG_SHA_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_sha_count() + \brief get sha instance. + \return pointer to sha instance +*/ +int32_t target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_sha_count()) { + return NULL; + } + + *base = sg_sha_config[idx].base; + *irq = sg_sha_config[idx].irq; + return idx; +} + +struct { + uint32_t base; + uint32_t irq; +} +const sg_rsa_config[CONFIG_RSA_NUM] = { + {CSKY_RSA_BASE, RSA_IRQn} +}; + +/** + \brief get rsa instance count. + \return rsa instance count +*/ +int32_t target_get_rsa_count(void) +{ + return CONFIG_RSA_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_rsa_count() + \brief get rsa instance. + \return pointer to rsa instance +*/ +int32_t target_get_rsa(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_rsa_count()) { + return NULL; + } + + *base = sg_rsa_config[idx].base; + *irq = sg_rsa_config[idx].irq; + return idx; +} + +struct { + uint32_t base; + uint32_t irq; +} +const sg_aes_config[CONFIG_AES_NUM] = { + {CSKY_AES_BASE, AES_IRQn} +}; + +/** + \brief get aes instance count. + \return aes instance count +*/ +int32_t target_get_aes_count(void) +{ + return CONFIG_AES_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_aes_count() + \brief get aes instance. + \return pointer to aes instance +*/ +int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_aes_count()) { + return NULL; + } + + *base = sg_aes_config[idx].base; + *irq = sg_aes_config[idx].irq; + return idx; +} + +struct { + uint32_t base; + uint32_t irq; +} +const sg_trng_config[CONFIG_TRNG_NUM] = { + {CSKY_TRNG_BASE, TRNG_IRQn} +}; + +/** + \param[in] instance idx + \brief get trng instance. + \return pointer to trng instance +*/ +int32_t target_get_trng(int32_t idx, uint32_t *base) +{ + *base = sg_trng_config[idx].base; + + return idx; +} + +struct { + uint32_t base; +} +const sg_crc_config[CONFIG_CRC_NUM] = { + {CSKY_CRC_BASE} +}; + +/** + \param[in] instance idx + \brief get crc instance. + \return pointer to crc instance +*/ +int32_t target_get_crc(int32_t idx, uint32_t *base) +{ + *base = sg_crc_config[idx].base; + return idx; +} + + +struct { + uint32_t base; + uint32_t irq; +} +const sg_iic_config[CONFIG_IIC_NUM] = { + {CSKY_I2C0_BASE, I2C0_IRQn}, + {CSKY_I2C1_BASE, I2C1_IRQn} +}; + +typedef struct { + int32_t scl; + int32_t sda; + uint16_t cfg_idx; //idx of sg_iic_config[] + uint16_t function; +} iic_pin_map_t; +const static iic_pin_map_t s_iic_pin_map[] = { + { + PA31_I2C0SCL_PWM11_SPU19_XX, + PA30_I2C0SDA_PWM10_SPU18_XX, + 0, + 0 + }, + { + PA28_I2C1SCL_PWM8_SPU16_XX, + PA29_I2C1SDA_PWM9_SPU17_XX, + 1, + 0 + } +}; + +/** + \param[in] instance idx, must not exceed return value of target_get_iic_count() + \brief get iic instance. + \return pointer to iic instance +*/ +int32_t target_iic_init(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= sizeof(s_iic_pin_map) / sizeof(iic_pin_map_t)) { + return -1; + } + + *base = sg_iic_config[s_iic_pin_map[idx].cfg_idx].base; + *irq = sg_iic_config[s_iic_pin_map[idx].cfg_idx].irq; + /*pinmux*/ + pin_mux(s_iic_pin_map[idx].scl, s_iic_pin_map[idx].function); + pin_mux(s_iic_pin_map[idx].sda, s_iic_pin_map[idx].function); + return s_iic_pin_map[idx].cfg_idx; +} + +#define BIT1 (0x1) +struct { + uint32_t base; + uint32_t irq; +} +const sg_rtc_config[CONFIG_RTC_NUM] = { + {CSKY_RTC0_BASE, RTC_IRQn}, + +}; + +int32_t target_get_rtc_count(void) +{ + return CONFIG_RTC_NUM; +} + +int32_t target_get_rtc(int32_t idx, uint32_t *base, uint32_t *irq) +{ + unsigned int value; + + if (idx >= target_get_rtc_count()) { + return NULL; + } + + value = readl(CSKY_PMU_BASE); + value &= ~BIT1; + writel(value, CSKY_PMU_BASE); + + *base = sg_rtc_config[idx].base; + *irq = sg_rtc_config[idx].irq; + return idx; +} + +struct { + uint32_t base; + uint32_t irq; +} + +const sg_spi_config[CONFIG_SPI_NUM] = { + {CSKY_SPI0_BASE, SPI0_IRQn}, + {CSKY_SPI1_BASE, SPI1_IRQn} +}; +typedef struct { + int32_t mosi; + int32_t miso; + int32_t sclk; + int32_t ssel; + uint32_t cfg_idx; //idx of sg_iic_config[] + uint16_t function; +} spi_pin_map_t; +const static spi_pin_map_t s_spi_pin_map[] = { + { + PA18_SPI0MISO_XX_SPU6_USI1SD1, + PA17_SPI0MOSI_PWMTRIG1_XX_USI1SD0, + PA19_SPI0SCK_FAULT_SPU7_USI1NSS, + PA16_SPI0CS0_PWMTRIG0_XX_USI1SCLK, + 0, + 0 + }, + { + PB13_UART3TX_SPI1MISO_SPU29_SIROUT3, + PB14_UART3RTS_SPI1MOSI_SPU30_XX, + PB15_UART3CTS_SPI1SCK_SPU31_XX, + PB12_UART3RX_SPI1CS0_SPU28_SIRIN3, + 1, + 1 + } +}; + +/** + \param[in] instance idx, must not exceed return value of target_get_spi_count() + \brief get spi instance. + \return pointer to spi instance +*/ +int32_t target_spi_init(int32_t idx, uint32_t *base, uint32_t *irq, uint32_t *ssel) +{ + if (idx >= sizeof(s_spi_pin_map) / sizeof(spi_pin_map_t)) { + return -1; + } + + *base = sg_spi_config[s_spi_pin_map[idx].cfg_idx].base; + *irq = sg_spi_config[s_spi_pin_map[idx].cfg_idx].irq; + *ssel = s_spi_pin_map[idx].ssel; + /*pinmux*/ + pin_mux(s_spi_pin_map[idx].mosi, s_spi_pin_map[idx].function); + pin_mux(s_spi_pin_map[idx].miso, s_spi_pin_map[idx].function); + pin_mux(s_spi_pin_map[idx].sclk, s_spi_pin_map[idx].function); + pin_mux(s_spi_pin_map[idx].ssel, s_spi_pin_map[idx].function); + + return s_spi_pin_map[idx].cfg_idx; + +} + +struct { + uint32_t base; + uint32_t irq; +} +const sg_dmac_config[CONFIG_DMAC_NUM] = { + {CSKY_DMAC0_BASE, DMAC_IRQn}, +}; + +int32_t target_get_dmac_count(void) +{ + return CONFIG_DMAC_NUM; +} + +int32_t target_get_dmac(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_dmac_count()) { + return NULL; + } + + *base = sg_dmac_config[idx].base; + *irq = sg_dmac_config[idx].irq; + return idx; +} + +struct { + uint32_t base; + uint32_t irq; +} +const sg_pwm_config[CONFIG_PWM_NUM] = { + {CSKY_PWM_BASE, PWM_IRQn}, +}; + +typedef struct { + int32_t pwm_pin; + uint32_t cfg_idx; //idx of sg_pwm_config[] + uint32_t ch_num; + uint16_t function; +} pwm_pin_map_t; +const static pwm_pin_map_t s_pwm_pin_map[] = { + {PA20_UART1RX_PWM0_SPU8_SIRIN1, 0, 0, 1}, + {PA21_UART1TX_PWM1_SPU9_SIROUT1, 0, 1, 1}, + {PA22_UART1CTS_PWM2_SPU10_XX, 0, 2, 1}, + {PA23_UART1RTS_PWM3_SPU11_XX, 0, 3, 1}, + {PA24_USI1NSS_PWM4_SPU12_XX, 0, 4, 1}, + {PA25_USI1SD1_PWM5_SPU13_XX, 0, 5, 1}, + {PA26_USI1SD0_PWM6_SPU14_XX, 0, 6, 1}, + {PA27_USI1SCLK_PWM7_SPU15_XX, 0, 7, 1}, + {PA28_I2C1SCL_PWM8_SPU16_XX, 0, 8, 1}, + {PA29_I2C1SDA_PWM9_SPU17_XX, 0, 9, 1}, + {PA30_I2C0SDA_PWM10_SPU18_XX, 0, 10, 1}, + {PA31_I2C0SCL_PWM11_SPU19_XX, 0, 11, 1} +}; + +/** + \param[in] instance idx, must not exceed return value of target_get_pwm_count() + \brief get pwm instance. + \return pointer to pwm instance +*/ +int32_t target_pwm_init(int32_t pwm_pin, uint32_t *ch_num, uint32_t *base, uint32_t *irq) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_pwm_pin_map) / sizeof(pwm_pin_map_t); idx++) { + if (s_pwm_pin_map[idx].pwm_pin == pwm_pin) { + *base = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].base; + *irq = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].irq; + *ch_num = s_pwm_pin_map[idx].ch_num; + /*pinmux*/ + pin_mux(s_pwm_pin_map[idx].pwm_pin, s_pwm_pin_map[idx].function); + return s_pwm_pin_map[idx].cfg_idx; + } + } + + return -1; +} + +struct { + uint32_t base; + uint32_t irq; +} +const sg_wdt_config[CONFIG_WDT_NUM] = { + {CSKY_WDT_BASE, WDT_IRQn} +}; + +int32_t target_get_wdt_count(void) +{ + return CONFIG_WDT_NUM; +} + +int32_t target_get_wdt(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_wdt_count()) { + return NULL; + } + + *base = sg_wdt_config[idx].base; + *irq = sg_wdt_config[idx].irq; + return idx; +} + +int32_t target_get_etb_count(void) +{ + return CONFIG_ETB_NUM; +} + +int32_t target_get_etb(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_etb_count()) { + return NULL; + } + +// *base = sg_etb_config[idx].base; +// *irq = sg_etb_config[idx].irq; + return 0; +} + +struct { + uint32_t base; + uint32_t irq; +} +const sg_qspi_config[CONFIG_QSPI_NUM] = { + {CSKY_QSPIC0_BASE, QSPIC1_IRQn}, + {CSKY_QSPIC1_BASE, QSPIC1_IRQn} +}; +typedef struct { + pin_name_t sclk; + pin_name_t miso; + pin_name_t mosi; + pin_name_t hold; + pin_name_t wp; + pin_name_t ssel; + uint32_t cfg_idx; + uint16_t function; +} qspi_pin_map_t; +const static qspi_pin_map_t s_qspi_pin_map[] = { + { + PA2_QSPI0CLK_XX_XX_XX, + PA3_QSPI0MISO_XX_XX_XX, + PA4_QSPI0MOSI_XX_XX_XX, + PA5_QSPI0HOLD_XX_XX_XX, + PA6_QSPI0WP_XX_XX_XX, + PA7_QSPI0CS0_XX_XX_XX, + 0, + 0 + }, + { + PB11_QSPI1CLK_XX_SPU27_I2C1SCL, + PB10_QSPI1MISO_XX_SPU26_I2C1SDA, + PB9_QSPI1MOSI_PWMTRIG1_SPU25_XX, + PB7_QSPI1HOLD_XX_SPU23_XX, + PB6_QSPI1WP_XX_SPU22_XX, + PB8_QSPI1CS0_PWMTRIG0_SPU24_XX, + 1, + 0 + } +}; + +/** + \param[in] instance idx, must not exceed return value of target_get_qspi_count() + \brief get qspi instance. + \return pointer to qspi instance +*/ +int32_t target_qspi_init(pin_name_t mosi, pin_name_t miso, pin_name_t sclk, pin_name_t ssel, pin_name_t wp, pin_name_t hold, uint32_t *base, uint32_t *irq) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_qspi_pin_map) / sizeof(qspi_pin_map_t); idx++) { + if (s_qspi_pin_map[idx].mosi == mosi && s_qspi_pin_map[idx].miso == miso + && s_qspi_pin_map[idx].sclk == sclk && s_qspi_pin_map[idx].ssel == ssel + && s_qspi_pin_map[idx].hold == hold && s_qspi_pin_map[idx].wp == wp) { + + pin_mux(s_qspi_pin_map[idx].mosi, s_qspi_pin_map[idx].function); + pin_mux(s_qspi_pin_map[idx].miso, s_qspi_pin_map[idx].function); + pin_mux(s_qspi_pin_map[idx].sclk, s_qspi_pin_map[idx].function); + pin_mux(s_qspi_pin_map[idx].hold, s_qspi_pin_map[idx].function); + pin_mux(s_qspi_pin_map[idx].wp, s_qspi_pin_map[idx].function); + pin_mux(s_qspi_pin_map[idx].ssel, s_qspi_pin_map[idx].function); + return s_qspi_pin_map[idx].cfg_idx; + } + } + return -1; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/include/pin_name.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/include/pin_name.h new file mode 100644 index 000000000..a06771328 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/include/pin_name.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file pin_name.h + * @brief header file for the pin_name + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _PINNAMES_H +#define _PINNAMES_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef enum { + PA0_I2C0SCL_SPI1CS1_SPU0_UART1TX = 0, + PA1_I2C0SDA_SPI1CS2_SPU1_UART1RX, + PA2_QSPI0CLK_XX_XX_XX, + PA3_QSPI0MISO_XX_XX_XX, + PA4_QSPI0MOSI_XX_XX_XX, + PA5_QSPI0HOLD_XX_XX_XX, + PA6_QSPI0WP_XX_XX_XX, + PA7_QSPI0CS0_XX_XX_XX, + PA8_UART0TX_XX_SPU2_SIROUT0, + PA9_UART0RX_XX_SPU3_SIRIN0, + PA10_UART0CTS_USI0SCLK_SPU4_I2C0SCL, + PA11_UART0RTS_USI0SD0_SPU5_I2C0SDA, + PA12_XX_USI0SD1_XX_UART2RX, + PA13_XX_USI0NSS_XX_UART2TX, + PA14_SPI0CS2_FAULT_I2C1SDA_XX, + PA15_SPI0CS1_XX_I2C1SCL_XX, + PA16_SPI0CS0_PWMTRIG0_XX_USI1SCLK, + PA17_SPI0MOSI_PWMTRIG1_XX_USI1SD0, + PA18_SPI0MISO_XX_SPU6_USI1SD1, + PA19_SPI0SCK_FAULT_SPU7_USI1NSS, + PA20_UART1RX_PWM0_SPU8_SIRIN1, + PA21_UART1TX_PWM1_SPU9_SIROUT1, + PA22_UART1CTS_PWM2_SPU10_XX, + PA23_UART1RTS_PWM3_SPU11_XX, + PA24_USI1NSS_PWM4_SPU12_XX, + PA25_USI1SD1_PWM5_SPU13_XX, + PA26_USI1SD0_PWM6_SPU14_XX, + PA27_USI1SCLK_PWM7_SPU15_XX, + PA28_I2C1SCL_PWM8_SPU16_XX, + PA29_I2C1SDA_PWM9_SPU17_XX, + PA30_I2C0SDA_PWM10_SPU18_XX, + PA31_I2C0SCL_PWM11_SPU19_XX, + PB0_UART2TX_XX_XX_SIROUT2, + PB1_UART2RX_XX_XX_SIRIN2, + PB2_UART2RTS_XX_XX_XX, + PB3_UART2CTS_XX_XX_XX, + PB4_XX_XX_SPU20_UART3TX, + PB5_QSPI1CS1_XX_SPU21_UART3RX, + PB6_QSPI1WP_XX_SPU22_XX, + PB7_QSPI1HOLD_XX_SPU23_XX, + PB8_QSPI1CS0_PWMTRIG0_SPU24_XX, + PB9_QSPI1MOSI_PWMTRIG1_SPU25_XX, + PB10_QSPI1MISO_XX_SPU26_I2C1SDA, + PB11_QSPI1CLK_XX_SPU27_I2C1SCL, + PB12_UART3RX_SPI1CS0_SPU28_SIRIN3, + PB13_UART3TX_SPI1MISO_SPU29_SIROUT3, + PB14_UART3RTS_SPI1MOSI_SPU30_XX, + PB15_UART3CTS_SPI1SCK_SPU31_XX, +} +pin_name_t; + +typedef enum { + PORTA = 0, + PORTB = 1 +} port_name_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/include/pinmux.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/include/pinmux.h new file mode 100644 index 000000000..ae7140d05 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/include/pinmux.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file pinmux.h + * @brief Header file for the pinmux + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef HOBBIT_PINMUX_H +#define HOBBIT_PINMUX_H + +#include +#include "pin_name.h" + +void hobbit_ioreuse_initial(void); +int32_t pin_mux(pin_name_t pin, uint16_t function); + +/*IOMUX0L function definition */ + + +/* IOMUX0H function definition */ +#define PA20_UART1_RX 0x00000000 +#define PA21_UART1_TX 0x00000000 + + +/* IOMUX1L function definition */ + +/* flag as identification */ +#define GPIO_SET_BIT0 0x00000001 +#define GPIO_SET_BIT1 0x00000002 +#define GPIO_SET_BIT2 0x00000004 +#define GPIO_SET_BIT3 0x00000008 +#define GPIO_SET_BIT4 0x00000010 +#define GPIO_SET_BIT5 0x00000020 +#define GPIO_SET_BIT6 0x00000040 +#define GPIO_SET_BIT7 0x00000080 +#define GPIO_SET_BIT8 0x00000100 +#define GPIO_SET_BIT9 0x00000200 +#define GPIO_SET_BIT10 0x00000400 +#define GPIO_SET_BIT11 0x00000800 +#define GPIO_SET_BIT12 0x00001000 +#define GPIO_SET_BIT13 0x00002000 +#define GPIO_SET_BIT14 0x00004000 +#define GPIO_SET_BIT15 0x00008000 +#define GPIO_SET_BIT16 0x00010000 +#define GPIO_SET_BIT17 0x00020000 +#define GPIO_SET_BIT18 0x00040000 +#define GPIO_SET_BIT19 0x00080000 +#define GPIO_SET_BIT20 0x00100000 +#define GPIO_SET_BIT21 0x00200000 +#define GPIO_SET_BIT22 0x00400000 +#define GPIO_SET_BIT23 0x00800000 +#define GPIO_SET_BIT24 0x01000000 +#define GPIO_SET_BIT25 0x02000000 +#define GPIO_SET_BIT26 0x04000000 +#define GPIO_SET_BIT27 0x08000000 +#define GPIO_SET_BIT28 0x10000000 +#define GPIO_SET_BIT29 0x20000000 +#define GPIO_SET_BIT30 0x40000000 +#define GPIO_SET_BIT31 0x80000000 + +/****************************************************************************** + * hobbit gpio control and gpio reuse function + * selecting regester adddress + ******************************************************************************/ + +#define HOBBIT_GIPO0_PORTCTL_REG 0x60030000 +#define HOBBIT_GIPO1_PORTCTL_REG 0x60030004 +#define HOBBIT_IOMUX0L_REG 0x60030008 +#define HOBBIT_IOMUX0H_REG 0x6003000C +#define HOBBIT_IOMUX1L_REG 0x60030010 + + +/*************basic gpio reuse v1.0******************************************** + * UART1(PA20,PA21) + ******************************************************************************/ +#define GPIO0_REUSE_EN (GPIO_SET_BIT20|GPIO_SET_BIT21) +#define GPIO1_REUSE_EN (0x00000000) +#define IOMUX0L_FUNCTION_SEL (0x00000000) +#define IOMUX0H_FUNCTION_SEL (PA20_UART1_RX|PA21_UART1_TX) +#define IOMUX1L_FUNCTION_SEL (0x00000000) + + +#endif /* HOBBIT_PINMUX_H */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/include/soc.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/include/soc.h new file mode 100644 index 000000000..ec99e14c0 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/include/soc.h @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/**************************************************************************//** + * @file soc.h + * @brief CSI Core Peripheral Access Layer Header File for + * CSKYSOC Device Series + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + + +#ifndef SOC_H +#define SOC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SYSTEM_CLOCK +#define SYSTEM_CLOCK (20000000) +#endif + +#ifndef LSP_DEFAULT_FREQ +#define LSP_DEFAULT_FREQ (20000000) +#endif + +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ + /* ---------------------- CSKYCK801 Specific Interrupt Numbers --------------------- */ + GPIOA_IRQn = 0, + CORET_IRQn = 1, /* core Timer Interrupt */ + TIMA0_IRQn = 2, /* timerA0 Interrupt */ + TIMA1_IRQn = 3, /* timerA1 Interrupt */ + TIM34567_IRQn = 4, /* timerC ~ timerH Interrupt */ + WDT_IRQn = 5, /* wdt Interrupt */ + UART0_IRQn = 6, /* uart0 Interrupt */ + UART1_IRQn = 7, /* uart1 Interrupt */ + UART2_IRQn = 8, /* uart2 Interrupt */ + I2C0_IRQn = 9, /* i2c0 Interrupt */ + I2C1_IRQn = 10, /* i2c1 Interrupt */ + SPI1_IRQn = 11, /* spi1 Interrupt */ + SPI0_IRQn = 12, /* spi0 Interrupt */ + RTC_IRQn = 13, /* rtc Interrupt */ + UART3_IRQn = 14, /* uart3 Interrupt */ + ADC_IRQn = 15, /* adc Interrupt */ + QSPIC1_IRQn = 16, /* qspic1 interrupt */ + DMAC_IRQn = 17, /* dmac Interrupt */ + PMU_IRQn = 18, /* pmu Interrupt */ + PWM_IRQn = 19, /* pwm Interrupt */ + USI0_IRQn = 20, /* usi0 Interrupt */ + USI1_IRQn = 21, /* usi1 Interrupt */ + SPU_IRQn = 22, /* spu Interrupt */ + TIMB0_IRQn = 23, /* timerB0 Interrupt */ + TIMB1_IRQn = 24, /* timerB1 Interrupt */ + GPIOB_IRQn = 27, /* GPIOB Interrupt */ + AES_IRQn = 26, /* aes Interrupt */ + RSA_IRQn = 28, /* rsa Interrupt */ + SHA_IRQn = 29, /* sha Interrupt */ + TRNG_IRQn = 30, /* trng Interrupt */ +} IRQn_Type; + + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of the CK801 Processor and Core Peripherals ------- */ +#define __CK803_REV 0x0000U /* Core revision r0p0 */ +#define __MPU_PRESENT 0 /* MGU present or not */ +#define __VIC_PRIO_BITS 2 /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ + +#include "core_ck802.h" /* Processor and core peripherals */ +#include "stdint.h" + +typedef enum { + CKENUM_DMA_UART0_RX, + CKENUM_DMA_UART0_TX, + CKENUM_DMA_UART1_RX, + CKENUM_DMA_UART1_TX, + CKENUM_DMA_ADC_RX, + CKENUM_DMA_ADC_TX, + CKENUM_DMA_SPI1_RX, + CKENUM_DMA_SPI1_TX, + CKENUM_DMA_SPI0_RX, + CKENUM_DMA_SPI0_TX, + CKENUM_DMA_IIC_RX, + CKENUM_DMA_IIC_TX, + CKENUM_DMA_IIC1_RX, + CKENUM_DMA_IIC1_TX, + CKENUM_DMA_IIS_RX, + CKENUM_DMA_IIS_TX, + CKENUM_DMA_MEMORY +} ckenum_dma_device_e; + +#define CONFIG_CRC_NUM 1 +#define CONFIG_IIC_NUM 2 +#define CONFIG_TRNG_NUM 1 +#define CONFIG_AES_NUM 1 +#define CONFIG_RSA_NUM 1 +#define CONFIG_SHA_NUM 1 +#define CONFIG_SPI_NUM 2 +#define CONFIG_QSPI_NUM 2 +#define CONFIG_PWM_NUM 1 +#define CONFIG_TIMER_NUM 14 +#define CONFIG_RTC_NUM 1 +#define CONFIG_WDT_NUM 1 +#define CONFIG_DMAC_NUM 1 +#define CONFIG_GPIO_NUM 2 +#define CONFIG_GPIO_PIN_NUM 43 +#define CONFIG_USART_NUM 4 +#define CONFIG_SPU_NUM 1 +#define CONFIG_EFLASH_NUM 1 +#define CONFIG_ETB_NUM 1 +#define CONFIG_USI_NUM 2 + +/* ================================================================================ */ +/* ================ Peripheral memory map ================ */ +/* ================================================================================ */ +/* -------------------------- CPU FPGA memory map ------------------------------- */ +#define CSKY_EFLASH_BASE (0x10000000UL) +#define CSKY_QSPIMEM_BASE (0x18000000UL) +#define CSKY_SRAM_BASE (0x20000000UL) +#define CSKY_PMU_BASE (0x40000000UL) +#define CSKY_DMAC0_BASE (0x40001000UL) +#define CSKY_OTP_BASE (0x40006000UL) +#define CSKY_SASC_BASE (0x40009000UL) +#define CSKY_SPU_BASE (0x40020000UL) +#define CSKY_QSPIC1_BASE (0x40030000UL) +#define CSKY_EFLASH_CONTROL_BASE (0x40005000UL) +#define CSKY_SASC_BASE (0x40009000UL) + +/* SUB0*/ +#define CSKY_AES_BASE (0x4000D000UL) +#define CSKY_SHA_BASE (0x4000E000UL) +#define CSKY_RSA_BASE (0x4000F000UL) +#define CSKY_CRC_BASE (0x40010000UL) +#define CSKY_TRNG_BASE (0x40011000UL) +/* APB0 */ +#define CSKY_TIM0_BASE (0x50000000UL) +#define CSKY_TIM1_BASE (0x50000400UL) +#define CSKY_TIM2_BASE (0x50000800UL) +#define CSKY_TIM3_BASE (0x50000C00UL) +#define CSKY_RTC0_BASE (0x50004000UL) +#define CSKY_WDT_BASE (0x50008000UL) +#define CSKY_SPI0_BASE (0x5000C000UL) +#define CSKY_UART0_BASE (0x50010000UL) +#define CSKY_UART1_BASE (0x50010400UL) +#define CSKY_I2C0_BASE (0x50014000UL) +#define CSKY_GPIO0_BASE (0x50018000UL) +#define CSKY_PWM_BASE (0x5001C000UL) +#define CSKY_ADC_BASE (0x50020000UL) +#define CSKY_USI0_BASE (0x50028000UL) +#define CSKY_QSPIC0_BASE (0x5002C000UL) +/* APB1*/ +#define CSKY_TIM4_BASE (0x60000000UL) +#define CSKY_TIM5_BASE (0x60000400UL) +#define CSKY_TIM6_BASE (0x60000800UL) +#define CSKY_TIM7_BASE (0x60000C00UL) +#define CSKY_LPWDT_BASE (0x60008000UL) +#define CSKY_SPI1_BASE (0x6000C000UL) +#define CSKY_UART2_BASE (0x60010000UL) +#define CSKY_UART3_BASE (0x60010400UL) +#define CSKY_I2C1_BASE (0x60014000UL) +#define CSKY_GPIO1_BASE (0x60018000UL) +#define CSKY_TIPC_BASE (0x6001c000UL) +#define CSKY_ETB_BASE (0x60024000UL) +#define CSKY_USI1_BASE (0x60028000UL) +#define CSKY_DAC_BASE (0x6002C000UL) +#define CSKY_IOC_BASE (0x60030000UL) + +#define SHA_CONTEXT_SIZE 224 + +/* ================================================================================ */ +/* ================ Peripheral declaration ================ */ +/* ================================================================================ */ +#define CSKY_UART1 (( CSKY_UART_TypeDef *) CSKY_UART1_BASE) +#define CSKY_SHA (( CSKY_SHA_TypeDef *) CSKY_SHA_BASE) + +#ifdef CONFIG_HAVE_VIC +#define ATTRIBUTE_ISR __attribute__((isr)) +#else +#define ATTRIBUTE_ISR +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SOC_H */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/isr.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/isr.c new file mode 100644 index 000000000..ea35573f2 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/isr.c @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file isr.c + * @brief source file for the interrupt server route + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include +#include "soc.h" +#ifndef CONFIG_KERNEL_NONE +#include +#endif + +#ifndef CONFIG_USI +extern void dw_spi_irqhandler(int32_t idx); +extern void dw_usart_irqhandler(int32_t idx); +extern void dw_iic_irqhandler(int32_t idx); +#else +extern void ck_usi_irqhandler(int idx); +#endif +extern void ck_spu_irqhandler(int32_t idx); +extern void dw_timer_irqhandler(int32_t idx); +extern void dw_gpio_irqhandler(int32_t idx); +extern void ck_rtc_irqhandler(int32_t idx); +extern void dw_wdt_irqhandler(int32_t idx); +extern void ck_dma_irqhandler(int32_t idx); +extern void ck_aes_irqhandler(int32_t idx); +extern void ck_sha_irqhandler(int32_t idx); +#ifdef CONFIG_KERNEL_FREERTOS +extern void CoretimeIsr(void); +extern void CKPendSVIsr(void); +#endif +extern void systick_handler(void); +extern void xPortSysTickHandler(void); +extern void OSTimeTick(void); + +#define readl(addr) \ + ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) + +#ifndef CONFIG_KERNEL_NONE +#define CSI_INTRPT_ENTER() csi_kernel_intrpt_enter() +#define CSI_INTRPT_EXIT() csi_kernel_intrpt_exit() +#else +#define CSI_INTRPT_ENTER() +#define CSI_INTRPT_EXIT() +#endif + +ATTRIBUTE_ISR void CORET_IRQHandler(void) +{ +#ifndef CONFIG_KERNEL_FREERTOS + CSI_INTRPT_ENTER(); +#endif + + readl(0xE000E010); + +#if defined(CONFIG_KERNEL_RHINO) + systick_handler(); +#elif defined(CONFIG_KERNEL_FREERTOS) + xPortSysTickHandler(); +#elif defined(CONFIG_KERNEL_UCOS) + OSTimeTick(); +#endif + +#ifndef CONFIG_KERNEL_FREERTOS + CSI_INTRPT_EXIT(); +#endif +} + +#ifdef CONFIG_SPU +ATTRIBUTE_ISR void SPU_IRQHandler(void) +{ + ck_spu_irqhandler(0); +} +#endif + +#ifndef CONFIG_USI +ATTRIBUTE_ISR void SPI0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_spi_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void SPI1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_spi_irqhandler(1); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void I2C0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_iic_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void I2C1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_iic_irqhandler(1); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void USART0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void USART1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(1); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void USART2_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(2); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void USART3_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(3); + CSI_INTRPT_EXIT(); +} +#else +ATTRIBUTE_ISR void USI0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_usi_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void USI1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_usi_irqhandler(1); + CSI_INTRPT_EXIT(); +} +#endif +ATTRIBUTE_ISR void TIMA0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void TIMA1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(1); + CSI_INTRPT_EXIT(); +} +ATTRIBUTE_ISR void TIMB0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(2); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void TIMB1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(3); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void TIM34567_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(4); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void GPIOA_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_gpio_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void GPIOB_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_gpio_irqhandler(1); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void RTC_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_rtc_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void AES_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_aes_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void SHA_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_sha_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void WDT_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_wdt_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void DMAC_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_dma_irqhandler(0); + CSI_INTRPT_EXIT(); +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/pinmux.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/pinmux.c new file mode 100644 index 000000000..de87cd7c6 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/hobbit3/pinmux.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file pinmux.c + * @brief source file for the pinmux + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include "pinmux.h" +#include "pin_name.h" + +#define readl(addr) \ + ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) + +#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) + +/******************************************************************************* + * function: hobbit_ioreuse_inital + * + * description: + * initial hobbit_pinmux + *******************************************************************************/ + +extern int32_t target_qspi_init(pin_name_t mosi, pin_name_t miso, pin_name_t sclk, pin_name_t ssel, pin_name_t wp, pin_name_t hold, uint32_t *base, uint32_t *irq); + +void hobbit_ioreuse_initial(void) +{ + unsigned int value; + + /* gpio data source select */ + value = readl(HOBBIT_GIPO0_PORTCTL_REG); + value |= GPIO0_REUSE_EN; + writel(value, HOBBIT_GIPO0_PORTCTL_REG); + + value = readl(HOBBIT_GIPO1_PORTCTL_REG); + value |= GPIO1_REUSE_EN; + writel(value, HOBBIT_GIPO1_PORTCTL_REG); + + /* reuse function select */ + value = readl(HOBBIT_IOMUX0L_REG); + value |= IOMUX0L_FUNCTION_SEL; + writel(value, HOBBIT_IOMUX0H_REG); + + value = readl(HOBBIT_IOMUX0H_REG); + value |= IOMUX1L_FUNCTION_SEL; + writel(value, HOBBIT_IOMUX0H_REG); + + value = readl(HOBBIT_IOMUX1L_REG); + value |= IOMUX1L_FUNCTION_SEL; + writel(value, HOBBIT_IOMUX1L_REG); + + target_qspi_init(PA4_QSPI0MOSI_XX_XX_XX, PA3_QSPI0MISO_XX_XX_XX, PA2_QSPI0CLK_XX_XX_XX, PA7_QSPI0CS0_XX_XX_XX, PA6_QSPI0WP_XX_XX_XX, PA5_QSPI0HOLD_XX_XX_XX, 0, 0); +} + +int32_t pin_mux(pin_name_t pin, uint16_t function) +{ + unsigned int val = 0; + unsigned int reg_val = 0; + + uint8_t offset; + + if (function > 3) { + if (pin < PB0_UART2TX_XX_XX_SIROUT2) { + offset = pin; + /* gpio data source select */ + val = readl(HOBBIT_GIPO0_PORTCTL_REG); + val &= ~(1 << offset); + writel(val, HOBBIT_GIPO0_PORTCTL_REG); + return 0; + } else if (pin >= PB0_UART2TX_XX_XX_SIROUT2) { + offset = pin - 32; + /* gpio data source select */ + val = readl(HOBBIT_GIPO1_PORTCTL_REG); + val &= ~(1 << offset); + writel(val, HOBBIT_GIPO1_PORTCTL_REG); + return 0; + } else { + return -1; + } + } + + if (pin >= PB0_UART2TX_XX_XX_SIROUT2) { + offset = pin - 32; + + /* gpio data source select */ + val = readl(HOBBIT_GIPO1_PORTCTL_REG); + val |= (1 << offset); + writel(val, HOBBIT_GIPO1_PORTCTL_REG); + + reg_val = (0x3 << (offset * 2)); + /* reuse function select */ + val = readl(HOBBIT_IOMUX1L_REG); + val &= ~(reg_val); + val |= (function << (2 * offset)); + writel(val, HOBBIT_IOMUX1L_REG); + return 0; + } + + offset = pin; + /* gpio data source select */ + val = readl(HOBBIT_GIPO0_PORTCTL_REG); + val |= (1 << offset); + writel(val, HOBBIT_GIPO0_PORTCTL_REG); + + if (pin >= PA16_SPI0CS0_PWMTRIG0_XX_USI1SCLK) { + offset = pin - 16; + reg_val = (0x3 << (offset * 2)); + /* reuse function select */ + val = readl(HOBBIT_IOMUX0H_REG); + val &= ~(reg_val); + val |= (function << (2 * offset)); + writel(val, HOBBIT_IOMUX0H_REG); + return 0; + } + + reg_val = (0x3 << (offset * 2)); + /* reuse function select */ + val = readl(HOBBIT_IOMUX0L_REG); + val &= ~(reg_val); + val |= (function << (2 * offset)); + writel(val, HOBBIT_IOMUX0L_REG); + return 0; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/Kconfig b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/Kconfig new file mode 100644 index 000000000..e69de29bb diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/csi.mk b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/csi.mk new file mode 100644 index 000000000..2c703a04e --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/csi.mk @@ -0,0 +1,5 @@ +TEE_INC += -I$(CSI_DIR)/csi_driver/csky/phobos/include +TEE_SRC += \ + $(CSI_DIR)/csi_driver/csky/phobos/devices.c \ + $(CSI_DIR)/csi_driver/csky/phobos/isr.c \ + $(CSI_DIR)/csi_driver/csky/phobos/pinmux.c \ No newline at end of file diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/devices.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/devices.c new file mode 100644 index 000000000..5e91547b9 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/devices.c @@ -0,0 +1,843 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file devices.c + * @brief source file for the devices + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include "soc.h" +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "pin_name.h" +#include "pinmux.h" + +//typedef int32_t pin_t; + + +#if CONFIG_IIC + + +struct { + uint32_t base; + uint32_t irq; +} +const sg_iic_config[CONFIG_IIC_NUM] = { + {CSKY_I2C0_BASE, I2C0_IRQn}, + {CSKY_I2C1_BASE, I2C1_IRQn} +}; + + +typedef struct { + pin_t scl; + pin_t sda; + uint16_t cfg_idx; //idx of sg_iic_config[] + uint16_t function; + //uint32_t scl_reg; + //uint32_t scl_cfg; + //uint32_t sda_reg; + //uint32_t sda_cfg; +} iic_pin_map_t; +const static iic_pin_map_t s_iic_pin_map[] = { + { + PA4_SCL0_PWM4_SPI0RX_XX, + PA5_SDA0_PWM5_SPI0CS_XX, + 0, + 0 + }, + { + PA6_SPI0CLK_PWMTRIG0_SCL0_XX, + PA7_SPI0TX_PWMTRIG1_SDA0_XX, + 0, + 2 + }, + { + PA31_I2SSDA__SCL0_PWM4_XX, + PB0_ADC0_SDA0_PWM5_XX, + 0, + 1 + }, + { + PA8_SPI0RX_TRIGFAULT_SCL1_XX, + PA9_SPI0CS_PWM0_SDA1_XX, + 1, + 2 + }, + { + PA14_SCL1_PWM5_SPI1RX_XX, + PA15_SDA1_PWMTRIG0_SPI1CS0_XX, + 1, + 0 + }, + { + PB1_ADC1_SCL1_USISCLK_XX, + PB2_ADC2_SDA1_USISD0_XX, + 1, + 1 + } +}; + + +/** + \param[in] instance idx, must not exceed return value of target_get_iic_count() + \brief get iic instance. + \return pointer to iic instance +*/ +int32_t target_iic_init(pin_t scl, pin_t sda, uint32_t *base, uint32_t *irq) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_iic_pin_map) / sizeof(iic_pin_map_t); idx++) { + if (s_iic_pin_map[idx].scl == scl && s_iic_pin_map[idx].sda == sda) { + *base = sg_iic_config[s_iic_pin_map[idx].cfg_idx].base; + *irq = sg_iic_config[s_iic_pin_map[idx].cfg_idx].irq; + /*pinmux*/ + pin_mux(s_iic_pin_map[idx].scl, s_iic_pin_map[idx].function); + pin_mux(s_iic_pin_map[idx].sda, s_iic_pin_map[idx].function); + return s_iic_pin_map[idx].cfg_idx; + } + } + + return -1; +} + + +#endif + +#if CONFIG_USART +struct { + uint32_t base; + uint32_t irq; +} +const sg_usart_config[CONFIG_USART_NUM] = { + {CSKY_UART0_BASE, UART0_IRQn}, + {CSKY_UART1_BASE, UART1_IRQn}, + {CSKY_UART2_BASE, UART2_IRQn}, + {CSKY_UART3_BASE, UART3_IRQn} +}; +typedef struct { + pin_t tx; + pin_t rx; + pin_t cts; + pin_t rts; + uint16_t cfg_idx; //idx of sg_usart_config[] + uint16_t function; +} usart_pin_map_t; +const static usart_pin_map_t s_usart_pin_map[] = { + { + PA0_TXD0_PWM0_XX_SIROUT0, + PA1_RXD0_PWM1_XX_SIRIN0, + -1, + -1, + 0, + 0 + }, + { + PA10_TXD1_PWM1_XX_SIROUT1, + PA11_RXD1_PWM2_XX_SIRIN1, + -1, + -1, + 1, + 0 + }, + { + PA23_TXD2_PWM5_XX_SIROUT2, + PA22_RXD2_PWM4_XX_SIRIN2, + PA24_CTS2_PWMTRIG0_SPI1CS1_XX, + PA25_XX_PWMTRIG1_SPI1CS2_XX, + 2, + 0 + }, + { + PA26_TXD3_PWMFAULT_XX_SIROUT3, + PA27_RXD3_PWM0_XX_SIRIN3, + -1, + -1, + 3, + 0 + } +}; + +/** + \param[in] instance idx, must not exceed return value of target_get_usart_count() + \brief get usart instance. + \return pointer to usart instance +*/ +int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) { + if (s_usart_pin_map[idx].tx == tx && s_usart_pin_map[idx].rx == rx) { + *base = sg_usart_config[s_usart_pin_map[idx].cfg_idx].base; + *irq = sg_usart_config[s_usart_pin_map[idx].cfg_idx].irq; + /*pinmux*/ + pin_mux(s_usart_pin_map[idx].tx, s_usart_pin_map[idx].function); + pin_mux(s_usart_pin_map[idx].rx, s_usart_pin_map[idx].function); + return s_usart_pin_map[idx].cfg_idx; + } + } + + return -1; + +} +/** + \brief control usart flow. + \param[in] tx_flow The TX flow pin name + \param[in] rx_flow The RX flow pin name + \param[in] flag 0-disable, 1-enable. + \return 0 if setting ready ,negative for error code +*/ +int32_t target_usart_flowctrl_init(pin_t tx_flow, pin_t rx_flow, uint32_t flag) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) { + if ((s_usart_pin_map[idx].cts == tx_flow) &&(s_usart_pin_map[idx].rts == rx_flow)) + break; + } + + if (idx >= sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t)) { + return -1; + } + + if ((s_usart_pin_map[idx].cts == tx_flow) && flag) { + pin_mux(s_usart_pin_map[idx].cts, s_usart_pin_map[idx].function); + } else if ((s_usart_pin_map[idx].cts == tx_flow) && (flag == 0)) { + pin_mux(s_usart_pin_map[idx].cts, 0xff); + } else { + return -1; + } + + if ((s_usart_pin_map[idx].rts == rx_flow) && flag) { + pin_mux(s_usart_pin_map[idx].rts, s_usart_pin_map[idx].function); + } else if ((s_usart_pin_map[idx].rts == rx_flow) && (flag == 0)) { + pin_mux(s_usart_pin_map[idx].rts, 0xff); + } else { + return -1; + } + + return 0; +} + +#endif + +#if CONFIG_TRNG +struct { + uint32_t base; +} +const sg_trng_config[CONFIG_TRNG_NUM] = { + {CSKY_TRNG_BASE} +}; + +/** + \brief get trng instance count. + \return trng instance count +*/ +int32_t target_get_trng_count(void) +{ + return CONFIG_TRNG_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_trng_count() + \brief get trng instance. + \return pointer to trng instance +*/ +int32_t target_get_trng(int32_t idx, uint32_t *base) +{ + if (idx >= target_get_trng_count()) { + return NULL; + } + + *base = sg_trng_config[idx].base; + return idx; +} + +#endif + +#if CONFIG_CRC +struct { + uint32_t base; +} +const sg_crc_config[CONFIG_CRC_NUM] = { + {CSKY_CRC_BASE} +}; + +/** + \brief get crc instance count. + \return crc instance count +*/ +int32_t target_get_crc_count(void) +{ + return CONFIG_CRC_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_crc_count() + \brief get crc instance. + \return pointer to crc instance +*/ +int32_t target_get_crc(int32_t idx, uint32_t *base) +{ + if (idx >= target_get_crc_count()) { + return NULL; + } + + *base = sg_crc_config[idx].base; + return idx; +} + +#endif + + +#if CONFIG_EFLASH +struct { + uint32_t base; + eflash_info info; +} +const sg_eflash_config[CONFIG_EFLASH_NUM] = { + {CSKY_EFLASH_CONTROL_BASE, {0x10000000, 0x1003f800, 0x1fc}} +}; + +/** + \brief get eflash instance count. + \return eflash instance count +*/ +int32_t target_get_eflash_count(void) +{ + return CONFIG_EFLASH_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_eflash_count() + \brief get eflash instance. + \return pointer to eflash instance +*/ +int32_t target_get_eflash(int32_t idx, uint32_t *base, eflash_info *info) +{ + if (idx >= target_get_eflash_count()) { + return NULL; + } + + *base = sg_eflash_config[idx].base; + info->start = sg_eflash_config[idx].info.start; + info->end = sg_eflash_config[idx].info.end; + info->sector_count = sg_eflash_config[idx].info.sector_count; + return idx; +} + +#endif + +#if CONFIG_TIMER +struct { + uint32_t base; + uint32_t irq; +} +const sg_timer_config[CONFIG_TIMER_NUM] = { + {CSKY_TIMERA0_BASE, TIMA0_IRQn}, + {CSKY_TIMERA1_BASE, TIMA1_IRQn}, + {CSKY_TIMERB0_BASE, TIMB0_IRQn}, + {CSKY_TIMERB1_BASE, TIMB1_IRQn} +}; + +int32_t target_get_timer_count(void) +{ + return CONFIG_TIMER_NUM; +} + +int32_t target_get_timer(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_timer_count()) { + return NULL; + } + + *base = sg_timer_config[idx].base; + *irq = sg_timer_config[idx].irq; + return idx; +} + +#endif + +#if CONFIG_GPIO +struct { + uint32_t base; + uint32_t irq; + uint32_t pin_num; + port_name_t port; +} +const sg_gpio_config[CONFIG_GPIO_NUM] = { + {CSKY_GPIOA_BASE, GPIOA_IRQn, 32, PORTA}, + {CSKY_GPIOB_BASE, GPIOB_IRQn, 11, PORTB} +}; + +typedef struct { + pin_t gpio_pin; + uint32_t cfg_idx; //idx of sg_gpio_config[] +} gpio_pin_map_t; +const static gpio_pin_map_t s_gpio_pin_map[] = { + {PA0_TXD0_PWM0_XX_SIROUT0, 0}, + {PA1_RXD0_PWM1_XX_SIRIN0, 0}, + {PA2_CTS0_PWM2_SPI0CLK_XX, 0}, + {PA3_RTS0_PWM3_SPI0TX_XX, 0}, + {PA4_SCL0_PWM4_SPI0RX_XX, 0}, + {PA5_SDA0_PWM5_SPI0CS_XX, 0}, + {PA6_SPI0CLK_PWMTRIG0_SCL0_XX, 0}, + {PA7_SPI0TX_PWMTRIG1_SDA0_XX, 0}, + {PA8_SPI0RX_TRIGFAULT_SCL1_XX, 0}, + {PA9_SPI0CS_PWM0_SDA1_XX, 0}, + {PA10_TXD1_PWM1_XX_SIROUT1, 0}, + {PA11_RXD1_PWM2_XX_SIRIN1, 0}, + {PA12_CTS1_PWM3_SPI1CLK_XX, 0}, + {PA13_RTS1_PWM4_SPI1TX_XX, 0}, + {PA14_SCL1_PWM5_SPI1RX_XX, 0}, + {PA15_SDA1_PWMTRIG0_SPI1CS0_XX, 0}, + {PA16_SPI1CLK_PWMTRIG1_XX_XX, 0}, + {PA17_SPI1TX_PWMFAULT_XX_XX, 0}, + {PA18_SPI1RX_PWM0_XX_XX, 0}, + {PA19_SPI1CS0_PWM1_XX_XX, 0}, + {PA20_SPI1CS1_PWM2_XX_XX, 0}, + {PA21_SPI1CS2_PWM3_XX_XX, 0}, + {PA22_RXD2_PWM4_XX_SIRIN2, 0}, + {PA23_TXD2_PWM5_XX_SIROUT2, 0}, + {PA24_CTS2_PWMTRIG0_SPI1CS1_XX, 0}, + {PA25_XX_PWMTRIG1_SPI1CS2_XX, 0}, + {PA26_TXD3_PWMFAULT_XX_SIROUT3, 0}, + {PA27_RXD3_PWM0_XX_SIRIN3, 0}, + {PA28_I2SMCLK_PWM1_XX_XX, 0}, + {PA29_I2SSCLK_PWM2_XX_XX, 0}, + {PA30_I2SWSCLK_PWM3_XX_XX, 0}, + {PA31_I2SSDA__SCL0_PWM4_XX, 0}, + {PB0_ADC0_SDA0_PWM5_XX, 1}, + {PB1_ADC1_SCL1_USISCLK_XX, 1}, + {PB2_ADC2_SDA1_USISD0_XX, 1}, + {PB3_ADC3_SPI1CLK_USISD1_XX, 1}, + {PB4_ADC4_SPI1TX_USINSS_XX, 1}, + {PB5_ADC5_SPI1RX_USISCLK_XX, 1}, + {PB6_ADC6_SPI1CS0_USISD0_XX, 1}, + {PB7_ADC7_SPI1CS1_USISD1_XX, 1}, + {PB8_PWMTRIG0_SPI1CS2_USINSS_XX, 1}, + {PB9_PWMTRIG1_CTS3_XX_XX, 1}, + {PB10_PWMFAULT_RTS3_XX_XX, 1} +}; + +int32_t target_gpio_port_init(port_name_t port, uint32_t *base, uint32_t *irq, uint32_t *pin_num) +{ + int i; + + for (i = 0; i < CONFIG_GPIO_NUM; i++) { + if (sg_gpio_config[i].port == port) { + *base = sg_gpio_config[i].base; + *irq = sg_gpio_config[i].irq; + *pin_num = sg_gpio_config[i].pin_num; + return i; + } + } + + return -1; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_gpio_count() + \brief get gpio instance. + \return pointer to gpio instance +*/ +int32_t target_gpio_pin_init(pin_t gpio_pin, uint32_t *port_idx) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_gpio_pin_map) / sizeof(gpio_pin_map_t); idx++) { + if (s_gpio_pin_map[idx].gpio_pin == gpio_pin) { + *port_idx = s_gpio_pin_map[idx].cfg_idx; + /*pinmux*/ + pin_mux(s_gpio_pin_map[idx].gpio_pin, 0xff); + if (idx >= 32) { + return idx-32; + } + return idx; + } + } + + return -1; +} + +#endif + +#if CONFIG_AES +struct { + uint32_t base; + uint32_t irq; +} +const sg_aes_config[CONFIG_AES_NUM] = { + {CSKY_AES_BASE, AES_IRQn} +}; + +/** + \brief get aes instance count. + \return aes instance count +*/ +int32_t target_get_aes_count(void) +{ + return CONFIG_AES_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_aes_count() + \brief get aes instance. + \return pointer to aes instance +*/ +int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_aes_count()) { + return NULL; + } + + *base = sg_aes_config[idx].base; + *irq = sg_aes_config[idx].irq; + return idx; +} + +#endif + + +#if CONFIG_RSA +struct { + uint32_t base; + uint32_t irq; +} +const sg_rsa_config[CONFIG_RSA_NUM] = { + {CSKY_RSA_BASE, RSA_IRQn} +}; + +/** + \brief get rsa instance count. + \return rsa instance count +*/ +int32_t target_get_rsa_count(void) +{ + return CONFIG_RSA_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_rsa_count() + \brief get rsa instance. + \return pointer to rsa instance +*/ +int32_t target_get_rsa(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_rsa_count()) { + return NULL; + } + + *base = sg_rsa_config[idx].base; + *irq = sg_rsa_config[idx].irq; + return idx; +} + +#endif + +#if CONFIG_RTC +struct { + uint32_t base; + uint32_t irq; +} +const sg_rtc_config[CONFIG_RTC_NUM] = { + {CSKY_RTC_BASE, RTC_IRQn} +}; + +int32_t target_get_rtc_count(void) +{ + return CONFIG_RTC_NUM; +} + +int32_t target_get_rtc(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_rtc_count()) { + return NULL; + } + + *base = sg_rtc_config[idx].base; + *irq = sg_rtc_config[idx].irq; + return idx; +} + +#endif + +#if CONFIG_SPI +struct { + uint32_t base; + uint32_t irq; +} + +const sg_spi_config[CONFIG_SPI_NUM] = { + {CSKY_SPI0_BASE, SPI0_IRQn}, + {CSKY_SPI1_BASE, SPI1_IRQn} +}; +typedef struct { + pin_t mosi; + pin_t miso; + pin_t sclk; + pin_t ssel; + uint32_t cfg_idx; //idx of sg_iic_config[] + uint16_t function; +} spi_pin_map_t; +const static spi_pin_map_t s_spi_pin_map[] = { + { + PA7_SPI0TX_PWMTRIG1_SDA0_XX, + PA8_SPI0RX_TRIGFAULT_SCL1_XX, + PA6_SPI0CLK_PWMTRIG0_SCL0_XX, + PA9_SPI0CS_PWM0_SDA1_XX, + 0, + 0 + }, + { + PA17_SPI1TX_PWMFAULT_XX_XX, + PA18_SPI1RX_PWM0_XX_XX, + PA16_SPI1CLK_PWMTRIG1_XX_XX, + PA19_SPI1CS0_PWM1_XX_XX, + 1, + 0 + }, + { + PA13_RTS1_PWM4_SPI1TX_XX, + PA14_SCL1_PWM5_SPI1RX_XX, + PA12_CTS1_PWM3_SPI1CLK_XX, + PA15_SDA1_PWMTRIG0_SPI1CS0_XX, + 1, + 2 + }, + { + PB4_ADC4_SPI1TX_USINSS_XX, + PB5_ADC5_SPI1RX_USISCLK_XX, + PB3_ADC3_SPI1CLK_USISD1_XX, + PB6_ADC6_SPI1CS0_USISD0_XX, + 1, + 1 + } +}; + +/** + \param[in] instance idx, must not exceed return value of target_get_spi_count() + \brief get spi instance. + \return pointer to spi instance +*/ +int32_t target_spi_init(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel, uint32_t *base, uint32_t *irq) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_spi_pin_map) / sizeof(spi_pin_map_t); idx++) { + if (s_spi_pin_map[idx].mosi == mosi && s_spi_pin_map[idx].miso == miso + && s_spi_pin_map[idx].sclk == sclk && s_spi_pin_map[idx].ssel == ssel) { + *base = sg_spi_config[s_spi_pin_map[idx].cfg_idx].base; + *irq = sg_spi_config[s_spi_pin_map[idx].cfg_idx].irq; + /*pinmux*/ + pin_mux(s_spi_pin_map[idx].mosi, s_spi_pin_map[idx].function); + pin_mux(s_spi_pin_map[idx].miso, s_spi_pin_map[idx].function); + pin_mux(s_spi_pin_map[idx].sclk, s_spi_pin_map[idx].function); + pin_mux(s_spi_pin_map[idx].ssel, s_spi_pin_map[idx].function); + + return s_spi_pin_map[idx].cfg_idx; + } + } + + return -1; + +} + +#endif + +#if CONFIG_WDT +struct { + uint32_t base; + uint32_t irq; +} +const sg_wdt_config[CONFIG_WDT_NUM] = { + {CSKY_WDT_BASE, WDT_IRQn} +}; + +int32_t target_get_wdt_count(void) +{ + return CONFIG_WDT_NUM; +} + +int32_t target_get_wdt(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_wdt_count()) { + return NULL; + } + + *base = sg_wdt_config[idx].base; + *irq = sg_wdt_config[idx].irq; + return idx; +} +#endif + + +#if CONFIG_SHA +struct { + uint32_t base; + uint32_t irq; +} +const sg_sha_config[CONFIG_SHA_NUM] = { + {CSKY_SHA_BASE, SHA_IRQn} +}; + +/** + \brief get sha instance count. + \return sha instance count +*/ +int32_t target_get_sha_count(void) +{ + return CONFIG_SHA_NUM; +} + +/** + \param[in] instance idx, must not exceed return value of target_get_sha_count() + \brief get sha instance. + \return pointer to sha instance +*/ +int32_t target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_sha_count()) { + return NULL; + } + + *base = sg_sha_config[idx].base; + *irq = sg_sha_config[idx].irq; + return idx; +} + +#endif + +#if CONFIG_PWM +struct { + uint32_t base; + uint32_t irq; +} +const sg_pwm_config[CONFIG_PWM_NUM] = { + {CSKY_PWM_BASE, PWM_IRQn}, +}; + +typedef struct { + pin_t pwm_pin; + uint32_t cfg_idx; //idx of sg_pwm_config[] + uint32_t ch_num; + uint16_t function; +} pwm_pin_map_t; +const static pwm_pin_map_t s_pwm_pin_map[] = { + {PA0_TXD0_PWM0_XX_SIROUT0, 0, 0, 1}, + {PA9_SPI0CS_PWM0_SDA1_XX, 0, 0, 1}, + {PA18_SPI1RX_PWM0_XX_XX, 0, 0, 1}, + {PA27_RXD3_PWM0_XX_SIRIN3, 0, 0, 1}, + + {PA1_RXD0_PWM1_XX_SIRIN0, 0, 1, 1}, + {PA10_TXD1_PWM1_XX_SIROUT1, 0, 1, 1}, + {PA19_SPI1CS0_PWM1_XX_XX, 0, 1, 1}, + {PA28_I2SMCLK_PWM1_XX_XX, 0, 1, 1}, + + {PA2_CTS0_PWM2_SPI0CLK_XX, 0, 2, 1}, + {PA11_RXD1_PWM2_XX_SIRIN1, 0, 2, 1}, + {PA20_SPI1CS1_PWM2_XX_XX, 0, 2, 1}, + {PA29_I2SSCLK_PWM2_XX_XX, 0, 2, 1}, + + {PA3_RTS0_PWM3_SPI0TX_XX, 0, 3, 1}, + {PA12_CTS1_PWM3_SPI1CLK_XX, 0, 3, 1}, + {PA21_SPI1CS2_PWM3_XX_XX, 0, 3, 1}, + {PA30_I2SWSCLK_PWM3_XX_XX, 0, 3, 1}, + + {PA4_SCL0_PWM4_SPI0RX_XX, 0, 4, 1}, + {PA13_RTS1_PWM4_SPI1TX_XX, 0, 4, 1}, + {PA22_RXD2_PWM4_XX_SIRIN2, 0, 4, 1}, + {PA31_I2SSDA__SCL0_PWM4_XX, 0, 4, 1}, + + {PA5_SDA0_PWM5_SPI0CS_XX, 0, 5, 1}, + {PA14_SCL1_PWM5_SPI1RX_XX, 0, 5, 1}, + {PA23_TXD2_PWM5_XX_SIROUT2, 0, 5, 1}, + {PB0_ADC0_SDA0_PWM5_XX, 0, 5, 1}, +}; + +/** + \param[in] instance idx, must not exceed return value of target_get_pwm_count() + \brief get pwm instance. + \return pointer to pwm instance +*/ +int32_t target_pwm_init(pin_t pwm_pin, uint32_t *ch_num, uint32_t *base, uint32_t *irq) +{ + uint32_t idx; + + for (idx = 0; idx < sizeof(s_pwm_pin_map) / sizeof(pwm_pin_map_t); idx++) { + if (s_pwm_pin_map[idx].pwm_pin == pwm_pin) { + *base = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].base; + *irq = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].irq; + *ch_num = s_pwm_pin_map[idx].ch_num; + /*pinmux*/ + pin_mux(s_pwm_pin_map[idx].pwm_pin, s_pwm_pin_map[idx].function); + return s_pwm_pin_map[idx].cfg_idx; + } + } + + return -1; + +} + + +#endif + + +#if CONFIG_DMAC +struct { + uint32_t base; + uint32_t irq; +} +const sg_dmac_config[CONFIG_DMAC_NUM] = { + {CSKY_DMA_BASE, DMAC_IRQn}, +}; + +int32_t target_get_dmac_count(void) +{ + return CONFIG_DMAC_NUM; +} + +int32_t target_get_dmac(int32_t idx, uint32_t *base, uint32_t *irq) +{ + if (idx >= target_get_dmac_count()) { + return NULL; + } + + *base = sg_dmac_config[idx].base; + *irq = sg_dmac_config[idx].irq; + return idx; +} +#endif + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/include/pin_name.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/include/pin_name.h new file mode 100644 index 000000000..4e29fdbbc --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/include/pin_name.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file pn_name.h + * @brief header file for the pin_name + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _PINNAMES_H +#define _PINNAMES_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef enum { + PA0_TXD0_PWM0_XX_SIROUT0 = 0, + PA1_RXD0_PWM1_XX_SIRIN0, + PA2_CTS0_PWM2_SPI0CLK_XX, + PA3_RTS0_PWM3_SPI0TX_XX, + PA4_SCL0_PWM4_SPI0RX_XX, + PA5_SDA0_PWM5_SPI0CS_XX, + PA6_SPI0CLK_PWMTRIG0_SCL0_XX, + PA7_SPI0TX_PWMTRIG1_SDA0_XX, + PA8_SPI0RX_TRIGFAULT_SCL1_XX, + PA9_SPI0CS_PWM0_SDA1_XX, + PA10_TXD1_PWM1_XX_SIROUT1, + PA11_RXD1_PWM2_XX_SIRIN1, + PA12_CTS1_PWM3_SPI1CLK_XX, + PA13_RTS1_PWM4_SPI1TX_XX, + PA14_SCL1_PWM5_SPI1RX_XX, + PA15_SDA1_PWMTRIG0_SPI1CS0_XX, + PA16_SPI1CLK_PWMTRIG1_XX_XX, + PA17_SPI1TX_PWMFAULT_XX_XX, + PA18_SPI1RX_PWM0_XX_XX, + PA19_SPI1CS0_PWM1_XX_XX, + PA20_SPI1CS1_PWM2_XX_XX, + PA21_SPI1CS2_PWM3_XX_XX, + PA22_RXD2_PWM4_XX_SIRIN2, + PA23_TXD2_PWM5_XX_SIROUT2, + PA24_CTS2_PWMTRIG0_SPI1CS1_XX, + PA25_XX_PWMTRIG1_SPI1CS2_XX, + PA26_TXD3_PWMFAULT_XX_SIROUT3, + PA27_RXD3_PWM0_XX_SIRIN3, + PA28_I2SMCLK_PWM1_XX_XX, + PA29_I2SSCLK_PWM2_XX_XX, + PA30_I2SWSCLK_PWM3_XX_XX, + PA31_I2SSDA__SCL0_PWM4_XX, + PB0_ADC0_SDA0_PWM5_XX, + PB1_ADC1_SCL1_USISCLK_XX, + PB2_ADC2_SDA1_USISD0_XX, + PB3_ADC3_SPI1CLK_USISD1_XX, + PB4_ADC4_SPI1TX_USINSS_XX, + PB5_ADC5_SPI1RX_USISCLK_XX, + PB6_ADC6_SPI1CS0_USISD0_XX, + PB7_ADC7_SPI1CS1_USISD1_XX, + PB8_PWMTRIG0_SPI1CS2_USINSS_XX, + PB9_PWMTRIG1_CTS3_XX_XX, + PB10_PWMFAULT_RTS3_XX_XX +} +pin_name_t; + +typedef enum { + PORTA = 0, + PORTB = 1 +} port_name_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/include/pinmux.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/include/pinmux.h new file mode 100644 index 000000000..9e3b48dfa --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/include/pinmux.h @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file pinmux.h + * @brief Header file for the pinmux + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef PHOBOS_PINMUX_H +#define PHOBOS_PINMUX_H + +#include +#include "pin_name.h" + +void phobos_ioreuse_initial(void); +int32_t pin_mux(pin_name_t pin, uint16_t function); + +/* IOMUX0L function definition */ +#define PA0_UART0_TX 0x00000000 +#define PA0_PWM_CH0 0x00000001 +#define PA0_UART0_SIROUT 0x00000003 +#define PA1_UART0_RX 0x00000000 +#define PA1_PWM_CH1 0x00000004 +#define PA1_UART0_SIRIN 0x0000000C +#define PA2_UART0_CTS 0x00000000 +#define PA2_PWM_CH2 0x00000010 +#define PA2_SPI0_CLK 0x00000020 +#define PA3_UART0_TRS 0x00000000 +#define PA3_PWM_CH3 0x00000040 +#define PA3_SPI0_TX 0x00000080 +#define PA4_I2C0_SCL 0x00000000 +#define PA4_PWM_CH4 0x00000100 +#define PA4_SPI0_RX 0x00000200 +#define PA5_I2C0_SDA 0x00000000 +#define PA5_PWM_CH5 0x00000400 +#define PA5_SPI0_CS 0x00000800 +#define PA6_SPI0_CLK 0x00000000 +#define PA6_ETB_TRIG0 0x00001000 +#define PA6_I2C0_SCL 0x00002000 +#define PA7_SPI_TX 0x00000000 +#define PA7_ETB_TRIG1 0x00004000 +#define PA7_I2C0_SDA 0x00008000 +#define PA8_SPI0_TX 0x00000000 +#define PA8_PWM_FAULT 0x00010000 +#define PA8_I2C1_SCL 0x00020000 +#define PA9_SPI0_CS 0x00000000 +#define PA9_PWM_CH0 0x00040000 +#define PA9_I2C1_SDA 0x00080000 +#define PA10_UART1_TX 0x00000000 +#define PA10_PWM_CH1 0x00100000 +#define PA10_UART1_SIROUT 0x00300000 +#define PA11_UART1_RX 0x00000000 +#define PA11_PWM_CH2 0x00400000 +#define PA11_UART1_SIRIN 0x00C00000 +#define PA12_UART1_CTS 0x00000000 +#define PA12_PWM_CH3 0x01000000 +#define PA12_SPI1_CLK 0x02000000 +#define PA13_UART1_RTS 0x00000000 +#define PA13_PWM_CH4 0x04000000 +#define PA13_SPI1_TX 0x08000000 +#define PA14_I2C1_SCL 0x00000000 +#define PA14_PWM_CH5 0x10000000 +#define PA14_SPI1_RX 0x20000000 +#define PA15_I2C1_SDA 0x00000000 +#define PA15_ETB_TRIG0 0x40000000 +#define PA15_SPI1_CS0 0x80000000 + +/* IOMUX0H function definition */ +#define PA16_SPI1_CLK 0x00000000 +#define PA16_ETB_TRIG1 0x00000001 +#define PA17_SPI1_TX 0x00000000 +#define PA17_PWM_FAULT 0x00000004 +#define PA18_SPI1_RX 0x00000000 +#define PA18_PWM_CH0 0x00000010 +#define PA19_SPI1_CS0 0x00000000 +#define PA19_PWM_CH1 0x00000040 +#define PA20_UART2_RX 0x00000000 +#define PA20_PWM_CH2 0x00000100 +#define PA21_SPI1_CS2 0x00000000 +#define PA21_PWM_CH3 0x00000400 +#define PA22_UART2_RX 0x00000000 +#define PA22_PWM_CH4 0x00001000 +#define PA22_UART2_SIRI 0x00003000 +#define PA23_UART2_TX 0x00000000 +#define PA23_PWM_CH5 0x00004000 +#define PA23_UART2_SIROUT 0x0000C000 +#define PA24_UART2_CTS 0x00000000 +#define PA24_ETB_TRIG0 0x00010000 +#define PA24_SPI1_CS1 0x00020000 +#define PA25_UART2_RTS 0x00000000 +#define PA25_ETB_TRIG1 0x00040000 +#define PA25_SPI1_CS2 0x00080000 +#define PA26_UART3_TX 0x00000000 +#define PA26_PWM_FAULT 0x00100000 +#define PA26_UART3_SIROUT 0x00300000 +#define PA27_UART3_RX 0x00000000 +#define PA27_PWM_CH0 0x00400000 +#define PA27_UART3_SIRIN 0x00C00000 +#define PA28_I2S_MCLK 0x00000000 +#define PA28_PWM_CH1 0x01000000 +#define PA29_I2S_SCLK 0x00000000 +#define PA29_PWM_CH2 0x04000000 +#define PA30_I2S_WSCLK 0x00000000 +#define PA30_PWM_CH3 0x10000000 +#define PA31_I2S_SDA 0x00000000 +#define PA31_I2C0_SCL 0x40000000 +#define PA31_PWM_CH4 0x80000000 + +/* IOMUX1L function definition */ +#define PB0_ADC0 0x00000000 +#define PB0_I2C0_SDA 0x00000001 +#define PB0_PWM_CH5 0x00000002 +#define PB1_ADC1 0x00000000 +#define PB1_I2C1_SCL 0x00000004 +#define PB1_USI_SCLK 0x00000008 +#define PB2_ADC2 0x00000000 +#define PB2_I2C1_SDA 0x00000010 +#define PB2_USI_SD0 0x00000020 +#define PB3_ADC3 0x00000000 +#define PB3_SPI1_CLK 0x00000040 +#define PB3_USI_SD1 0x00000080 +#define PB4_ADC4 0x00000000 +#define PB4_SPI1_TX 0x00000100 +#define PB4_USI_NSS 0x00000200 +#define PB5_ADC5 0x00000000 +#define PB5_SPI1_RX 0x00000400 +#define PB5_USI_SCLK 0x00000800 +#define PB6_ADC6 0x00000000 +#define PB6_SPI1_CS0 0x00001000 +#define PB6_USI_SD0 0x00002000 +#define PB7_ADC7 0x00000000 +#define PB7_SPI1_CS1 0x00004000 +#define PB7_USI_SD1 0x00008000 +#define PB8_ETB_TRIG0 0x00000000 +#define PB8_SPI1_CS2 0x00010000 +#define PB8_USI_NSS 0x00020000 +#define PB9_ETB_TRIG1 0x00000000 +#define PB9_UART3_CTS 0x00040000 +#define PB10_PWM_FAULT 0x00000000 +#define PB10_UART3_RTS 0x00100000 + + +/* flag as identification */ +#define GPIO_SET_BIT0 0x00000001 +#define GPIO_SET_BIT1 0x00000002 +#define GPIO_SET_BIT2 0x00000004 +#define GPIO_SET_BIT3 0x00000008 +#define GPIO_SET_BIT4 0x00000010 +#define GPIO_SET_BIT5 0x00000020 +#define GPIO_SET_BIT6 0x00000040 +#define GPIO_SET_BIT7 0x00000080 +#define GPIO_SET_BIT8 0x00000100 +#define GPIO_SET_BIT9 0x00000200 +#define GPIO_SET_BIT10 0x00000400 +#define GPIO_SET_BIT11 0x00000800 +#define GPIO_SET_BIT12 0x00001000 +#define GPIO_SET_BIT13 0x00002000 +#define GPIO_SET_BIT14 0x00004000 +#define GPIO_SET_BIT15 0x00008000 +#define GPIO_SET_BIT16 0x00010000 +#define GPIO_SET_BIT17 0x00020000 +#define GPIO_SET_BIT18 0x00040000 +#define GPIO_SET_BIT19 0x00080000 +#define GPIO_SET_BIT20 0x00100000 +#define GPIO_SET_BIT21 0x00200000 +#define GPIO_SET_BIT22 0x00400000 +#define GPIO_SET_BIT23 0x00800000 +#define GPIO_SET_BIT24 0x01000000 +#define GPIO_SET_BIT25 0x02000000 +#define GPIO_SET_BIT26 0x04000000 +#define GPIO_SET_BIT27 0x08000000 +#define GPIO_SET_BIT28 0x10000000 +#define GPIO_SET_BIT29 0x20000000 +#define GPIO_SET_BIT30 0x40000000 +#define GPIO_SET_BIT31 0x80000000 + +/****************************************************************************** + * phobos gpio control and gpio reuse function + * selecting regester adddress + ******************************************************************************/ + +#define PHOBOS_GIPO0_PORTCTL_REG 0x50018008 +#define PHOBOS_GIPO1_PORTCTL_REG 0x60018008 +#define PHOBOS_IOMUX0L_REG 0x50018100 +#define PHOBOS_IOMUX0H_REG 0x50018104 +#define PHOBOS_IOMUX1L_REG 0x50018108 + +/*************basic gpio reuse v1.0******************************************** + * UART0(PA0,PA1) + * UART1(PA10,PA11) + * UART2(PA22,PA23) + * UART3(PA26,PA27) + * IIS(PA24,PA25,PA26,PA27) + * SPI1(PA16,PA17,PA18) + * IIC0(PA4,PA5) + ******************************************************************************/ +#define GPIO0_REUSE_EN (GPIO_SET_BIT0|GPIO_SET_BIT1|GPIO_SET_BIT4|GPIO_SET_BIT5|GPIO_SET_BIT6|GPIO_SET_BIT9|GPIO_SET_BIT10|GPIO_SET_BIT11|GPIO_SET_BIT16|GPIO_SET_BIT17|GPIO_SET_BIT18|GPIO_SET_BIT22|GPIO_SET_BIT23|GPIO_SET_BIT26|GPIO_SET_BIT27) +#define GPIO1_REUSE_EN (GPIO_SET_BIT0) +#define IOMUX0L_FUNCTION_SEL (PA0_UART0_TX|PA1_UART0_RX|PA4_I2C0_SCL|PA5_I2C0_SDA|PA6_ETB_TRIG0|PA9_PWM_CH0|PA10_UART1_TX|PA11_UART1_RX) +#define IOMUX0H_FUNCTION_SEL (PA16_SPI1_CLK|PA17_SPI1_TX|PA18_SPI1_RX|PA22_UART2_RX|PA23_UART2_TX|PA26_UART3_TX|PA27_UART3_RX) +#define IOMUX1L_FUNCTION_SEL (PB0_ADC0) + +#define PWM_GPIO0_REUSE_EN (GPIO0_REUSE_EN|GPIO_SET_BIT0|GPIO_SET_BIT1|GPIO_SET_BIT2|GPIO_SET_BIT12|GPIO_SET_BIT13|GPIO_SET_BIT14) +#define PWM_IOMUX0L_FUNCTION_SEL (IOMUX0L_FUNCTION_SEL|PA0_PWM_CH0|PA1_PWM_CH1|PA2_PWM_CH2|PA12_PWM_CH3|PA13_PWM_CH4|PA14_PWM_CH5) + +#endif /* PHOBOS_PINMUX_H */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/include/soc.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/include/soc.h new file mode 100644 index 000000000..1c0023127 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/include/soc.h @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/**************************************************************************//** + * @file soc.h + * @brief CSI Core Peripheral Access Layer Header File for + * CSKYSOC Device Series + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + + +#ifndef SOC_H +#define SOC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SYSTEM_CLOCK +#define SYSTEM_CLOCK (20000000) +#endif +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ + /* ---------------------- CSKYCK801 Specific Interrupt Numbers --------------------- */ + GPIOA_IRQn = 0, + CORET_IRQn = 1, /* core Timer Interrupt */ + TIMA0_IRQn = 2, /* timerA0 Interrupt */ + TIMA1_IRQn = 3, /* timerA1 Interrupt */ + WDT_IRQn = 5, /* wdt Interrupt */ + UART0_IRQn = 6, /* uart0 Interrupt */ + UART1_IRQn = 7, /* uart1 Interrupt */ + UART2_IRQn = 8, /* uart2 Interrupt */ + I2C0_IRQn = 9, /* i2c0 Interrupt */ + I2C1_IRQn = 10, /* i2c1 Interrupt */ + SPI1_IRQn = 11, /* spi0 Interrupt */ + SPI0_IRQn = 12, /* spi1 Interrupt */ + RTC_IRQn = 13, /* rtc Interrupt */ + EXTWAK_IRQn = 14, /* extwakeup Interrupt */ + DMAC_IRQn = 17, /* dmac Interrupt */ + PMU_IRQn = 18, /* pmu Interrupt */ + PWM_IRQn = 19, /* pwm Interrupt */ + UART3_IRQn = 21, /* uart3 Interrupt */ + TIMB0_IRQn = 23, /* timerB0 Interrupt */ + TIMB1_IRQn = 24, /* timerB1 Interrupt */ + GPIOB_IRQn = 27, /* GPIOB Interrupt */ + AES_IRQn = 26, /* aes Interrupt */ + RSA_IRQn = 28, /* rsa Interrupt */ + SHA_IRQn = 29, /* sha Interrupt */ + +} +IRQn_Type; + + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of the CK801 Processor and Core Peripherals ------- */ +#define __CK802_REV 0x0000U /* Core revision r0p0 */ +#define __MGU_PRESENT 0 /* MGU present or not */ +#define __NVIC_PRIO_BITS 2 /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ + +#include "core_ck802.h" /* Processor and core peripherals */ +#include "stdint.h" + +typedef enum { + CKENUM_DMA_UART0_RX, + CKENUM_DMA_UART0_TX, + CKENUM_DMA_UART1_RX, + CKENUM_DMA_UART1_TX, + CKENUM_DMA_ADC_RX, + CKENUM_DMA_ADC_TX, + CKENUM_DMA_SPI1_RX, + CKENUM_DMA_SPI1_TX, + CKENUM_DMA_SPI0_RX, + CKENUM_DMA_SPI0_TX, + CKENUM_DMA_IIC_RX, + CKENUM_DMA_IIC_TX, + CKENUM_DMA_IIC1_RX, + CKENUM_DMA_IIC1_TX, + CKENUM_DMA_IIS_RX, + CKENUM_DMA_IIS_TX, + CKENUM_DMA_MEMORY +} ckenum_dma_device_e; + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ +#if 0 + +/* ================================================================================ */ +/* ============== Universal Asyncronous Receiver / Transmitter (UART) ============= */ +/* ================================================================================ */ +typedef struct { + union { + __IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */ + __OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */ + __IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */ + }; + union { + __IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */ + __IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */ + }; + __IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */ + __IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */ + __IOM uint32_t MCR; /* Offset: 0x010 (R/W) Modem control register */ + __IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */ + __IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */ + uint32_t RESERVED1[24]; + __IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */ +} CSKY_UART_TypeDef; + + +/* ================================================================================ */ +/* ============== Inter-Integrated Circuit (IIC) ============= */ +/* ================================================================================ */ +typedef struct { + __IOM uint32_t IC_CON; /* Offset: 0x000 (R/W) Receive buffer register */ + __IOM uint32_t IC_TAR; /* Offset: 0x004 (R/W) Transmission hold register */ + __IOM uint32_t IC_SAR; /* Offset: 0x008 (R/W) Clock frequency division low section register */ + __IOM uint32_t IC_HS_MADDR; /* Offset: 0x00c (R/W) Clock frequency division high section register */ + __IOM uint32_t IC_DATA_CMD; /* Offset: 0x010 (R/W) Interrupt enable register */ + __IOM uint32_t IC_SS_SCL_HCNT; /* Offset: 0x014 (R/W) Interrupt indicia register */ + __IOM uint32_t IC_SS_SCL_LCNT; /* Offset: 0x018 (R/W) Transmission control register */ + __IOM uint32_t IC_FS_SCL_HCNT; /* Offset: 0x01c (R/W) Modem control register */ + __IOM uint32_t IC_FS_SCL_LCNT; /* Offset: 0x020 (R/W) Transmission state register */ + __IOM uint32_t IC_HS_SCL_HCNT; /* Offset: 0x024 (R/W) Transmission state register */ + __IOM uint32_t IC_HS_SCL_LCNT; /* Offset: 0x028 (R/W) Transmission state register */ + __IOM uint32_t IC_INTR_STAT; /* Offset: 0x02c (R) Transmission state register */ + __IOM uint32_t IC_INTR_MASK; /* Offset: 0x030 (R/W) Transmission state register */ + __IOM uint32_t IC_RAW_INTR_STAT; /* Offset: 0x034 (R) Transmission state register */ + __IOM uint32_t IC_RX_TL; /* Offset: 0x038 (R/W) Transmission state register */ + __IOM uint32_t IC_TX_TL; /* Offset: 0x03c (R/W) Transmission state register */ + __IOM uint32_t IC_CLR_INTR; /* Offset: 0x040 (R) Transmission state register */ + __IOM uint32_t IC_CLR_RX_UNDER; /* Offset: 0x044 (R) Transmission state register */ + __IOM uint32_t IC_CLR_RX_OVER; /* Offset: 0x048 (R) Transmission state register */ + __IOM uint32_t IC_CLR_TX_OVER; /* Offset: 0x04c (R) Transmission state register */ + __IOM uint32_t IC_CLR_RD_REQ; /* Offset: 0x050 (R) Transmission state register */ + __IOM uint32_t IC_CLR_TX_ABRT; /* Offset: 0x054 (R) Transmission state register */ + __IOM uint32_t IC_CLR_RX_DONE; /* Offset: 0x058 (R) Transmission state register */ + __IOM uint32_t IC_CLR_ACTIVITY; /* Offset: 0x05c (R) Transmission state register */ + __IOM uint32_t IC_CLR_STOP_DET; /* Offset: 0x060 (R) Transmission state register */ + __IOM uint32_t IC_CLR_START_DET; /* Offset: 0x064 (R) Transmission state register */ + __IOM uint32_t IC_CLR_GEN_CALL; /* Offset: 0x068 (R) Transmission state register */ + __IOM uint32_t IC_ENABLE; /* Offset: 0x06c (R/W) Transmission state register */ + __IOM uint32_t IC_STATUS; /* Offset: 0x070 (R) Transmission state register */ + __IOM uint32_t IC_TXFLR; /* Offset: 0x074 (R) Transmission state register */ + __IOM uint32_t IC_RXFLR; /* Offset: 0x078 (R) Transmission state register */ + uint32_t RESERVED; /* Offset: 0x014 (R/ ) Transmission state register */ + __IOM uint32_t IC_TX_ABRT_SOURCE; /* Offset: 0x080 (R/W) Transmission state register */ + __IOM uint32_t IC_SAR1; /* Offset: 0x084 (R/W) Transmission state register */ + __IOM uint32_t IC_DMA_CR; /* Offset: 0x088 (R/W) Transmission state register */ + __IOM uint32_t IC_DMA_TDLR; /* Offset: 0x08c (R/W) Transmission state register */ + __IOM uint32_t IC_DMA_RDLR; /* Offset: 0x090 (R/W) Transmission state register */ + __IOM uint32_t IC_SAR2; /* Offset: 0x094 (R/W) Transmission state register */ + __IOM uint32_t IC_SAR3; /* Offset: 0x098 (R/W) Transmission state register */ + __IOM uint32_t IC_MULTI_SLAVE; /* Offset: 0x09c (R/W) Transmission state register */ + __IOM uint32_t IC_GEN_CALL_EN; /* Offset: 0x0a0 (R/W) Transmission state register */ + +} CSKY_IIC_TypeDef; + + +/* ================================================================================ */ +/* ============== TIMER ============= */ +/* ================================================================================ */ +typedef struct { + __IOM uint32_t TxLoadCount; /* Offset: 0x000 (R/W) Receive buffer register */ + __IOM uint32_t TxCurrentValue; /* Offset: 0x004 (R) Transmission hold register */ + __IOM uint32_t TxControl; /* Offset: 0x008 (R/W) Clock frequency division low section register */ + __IOM uint32_t TxEOI; /* Offset: 0x00c (R) Clock frequency division high section register */ + __IOM uint32_t TxIntStatus; /* Offset: 0x010 (R) Interrupt enable register */ + +} CSKY_TIMER_TypeDef; + +/* ================================================================================ */ +/* ============== TIMER Control ============= */ +/* ================================================================================ */ +typedef struct { + __IOM uint32_t TimersIntStatus; /* Offset: 0x000 (R) Interrupt indicia register */ + __IOM uint32_t TimerEOI; /* Offset: 0x004 (R) Transmission control register */ + __IOM uint32_t TimerRawIntStatus; /* Offset: 0x008 (R) Modem control register */ + +} CSKY_TIMER_Control_TypeDef; + + +/* ================================================================================ */ +/* ============== GPIO ============= */ +/* ================================================================================ */ +typedef struct { + __IOM uint32_t SWPORT_DR; /* Offset: 0x000 (R/W) Interrupt indicia register */ + __IOM uint32_t SWPORT_DDR; /* Offset: 0x004 (R/W) Interrupt indicia register */ + __IOM uint32_t PORT_CTL; /* Offset: 0x008 (R/W) Interrupt indicia register */ +} CKStruct_GPIO, *PCKStruct_GPIO; + +typedef struct { + __IOM uint32_t SHA_CON; /* Offset: 0x000 (R/W) Control register */ + __IOM uint32_t SHA_INTSTATE; /* Offset: 0x004 (R/W) Instatus register */ + __IOM uint32_t SHA_H0L; /* Offset: 0x008 (R/W) H0L register */ + __IOM uint32_t SHA_H1L; /* Offset: 0x00c (R/W) H1L register */ + __IOM uint32_t SHA_H2L; /* Offset: 0x010 (R/W) H2L register */ + __IOM uint32_t SHA_H3L; /* Offset: 0x014 (R/W) H3L register */ + __IOM uint32_t SHA_H4L; /* Offset: 0x018 (R/W) H4L register */ + __IOM uint32_t SHA_H5L; /* Offset: 0x01c (R/W) H5L register */ + __IOM uint32_t SHA_H6L; /* Offset: 0x020 (R/W) H6L register */ + __IOM uint32_t SHA_H7L; /* Offset: 0x024 (R/W) H7L register */ + __IOM uint32_t SHA_H0H; /* Offset: 0x028 (R/W) H0H register */ + __IOM uint32_t SHA_H1H; /* Offset: 0x02c (R/W) H1H register */ + __IOM uint32_t SHA_H2H; /* Offset: 0x030 (R/W) H2H register */ + __IOM uint32_t SHA_H3H; /* Offset: 0x034 (R/W) H3H register */ + __IOM uint32_t SHA_H4H; /* Offset: 0x038 (R/W) H4H register */ + __IOM uint32_t SHA_H5H; /* Offset: 0x03c (R/W) H5H register */ + __IOM uint32_t SHA_H6H; /* Offset: 0x040 (R/W) H6H register */ + __IOM uint32_t SHA_H7H; /* Offset: 0x044 (R/W) H7H register */ + __IOM uint32_t SHA_DATA1; /* Offset: 0x048 (R/W) DATA1 register */ + uint32_t REV[15]; + __IOM uint32_t SHA_DATA2; /* Offset: 0x088 (R/W) DATA2 register */ +} CSKY_SHA_TypeDef; + + +#endif + +#define CONFIG_CRC_NUM 1 +#define CONFIG_IIC_NUM 2 +#define CONFIG_TRNG_NUM 1 +#define CONFIG_EFLASH_NUM 1 +#define CONFIG_AES_NUM 1 +#define CONFIG_RSA_NUM 1 +#define CONFIG_SHA_NUM 1 +#define CONFIG_SPI_NUM 2 +#define CONFIG_PWM_NUM 1 +#define CONFIG_TIMER_NUM 4 +#define CONFIG_RTC_NUM 1 +#define CONFIG_WDT_NUM 1 +#define CONFIG_DMAC_NUM 1 +#define CONFIG_ETH_NUM 2 + +#define CSKY_I2C0_BASE (0x50014000UL) +#define CSKY_I2C1_BASE (0x60014000UL) + +#define CONFIG_USART_NUM 4 +#define CSKY_UART0_BASE (0x50010000UL) +#define CSKY_UART1_BASE (0x50010400UL) +#define CSKY_UART2_BASE (0x60010000UL) +#define CSKY_UART3_BASE (0x60010400UL) + +/* ================================================================================ */ +/* ================ Peripheral memory map ================ */ +/* ================================================================================ */ +/* -------------------------- CPU FPGA memory map ------------------------------- */ +#define CSKY_EFLASH_BASE (0x10000000UL) +#define CSKY_SRAM_BASE (0x20000000UL) + +#define CSKY_PMU_BASE (0x40000000UL) +#define CSKY_DMA_BASE (0x40001000UL) +#define CSKY_EFLASH_CONTROL_BASE (0x40005000UL) +#define CSKY_OTP_BASE (0x40006000UL) +#define CSKY_SRAM_CONTROL_BASE (0x40009000UL) +#define CSKY_AES_BASE (0x4000d000UL) +#define CSKY_SHA_BASE (0x4000e000UL) +#define CSKY_RSA_BASE (0x4000f000UL) +#define CSKY_CRC_BASE (0x40010000UL) +#define CSKY_TRNG_BASE (0x40015000UL) +#define CSKY_TIMERA0_BASE (0x50000000UL) +#define CSKY_TIMERA1_BASE (0x50000014UL) +#define CSKY_TIMERA_CONTROL_BASE (0x500000a0UL) +#define CSKY_RTC_BASE (0x50004000UL) +#define CSKY_WDT_BASE (0x50008000UL) +#define CSKY_SPI0_BASE (0x5000c000UL) + +#define SHA_CONTEXT_SIZE 224 + +#define CONFIG_GPIO_NUM 2 +#define CONFIG_GPIO_PIN_NUM 43 +#define CSKY_GPIOA_BASE (0x50018000UL) +#define CSKY_GPIOA_CONTROL_BASE (0x50018030UL) +#define CSKY_PWM_BASE (0x5001c000UL) +#define CSKY_ADC_BASE (0x50020000UL) +#define CSKY_I2S0_BASE (0x50030000UL) +#define CSKY_TIMERB0_BASE (0x60000000UL) +#define CSKY_TIMERB1_BASE (0x60000014UL) +#define CSKY_SPI1_BASE (0x6000c000UL) + +#define CSKY_GPIOB_BASE (0x60018000UL) +#define CSKY_GPIOB_CONTROL_BASE (0x60018030UL) +#define CSKY_TIMERB_CONTROL_BASE (0x600000a0UL) +#define CSKY_SIPC_BASE (0x6001c000UL) +#define CSKY_I2S1_BASE (0x60020000UL) +#define CSKY_ETB_BASE (0x60024000UL) +#define CSKY_USI_BASE (0x60028000UL) + + + +/* ================================================================================ */ +/* ================ Peripheral declaration ================ */ +/* ================================================================================ */ +#define CSKY_UART1 (( CSKY_UART_TypeDef *) CSKY_UART1_BASE) +#define CSKY_SHA (( CSKY_SHA_TypeDef *) CSKY_SHA_BASE) + +#include +#ifdef CONFIG_HAVE_VIC +#define ATTRIBUTE_ISR __attribute__((isr)) +#else +#define ATTRIBUTE_ISR +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SOC_H */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/isr.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/isr.c new file mode 100644 index 000000000..94804eeb8 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/isr.c @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file isr.c + * @brief source file for the interrupt server route + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include "config.h" +#include "soc.h" +#ifndef CONFIG_KERNEL_NONE +#include +#endif + +extern void dw_usart_irqhandler(int32_t idx); +extern void dw_timer_irqhandler(int32_t idx); +extern void dw_gpio_irqhandler(int32_t idx); +extern void dw_iic_irqhandler(int32_t idx); +extern void ck_rtc_irqhandler(int32_t idx); +extern void dw_spi_irqhandler(int32_t idx); +extern void dw_wdt_irqhandler(int32_t idx); +extern void ck_dma_irqhandler(int32_t idx); +extern void ck_aes_irqhandler(int32_t idx); +extern void ck_sha_irqhandler(int32_t idx); + +#define readl(addr) \ + ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) + +#ifndef CONFIG_KERNEL_NONE +#define CSI_INTRPT_ENTER() csi_kernel_intrpt_enter() +#define CSI_INTRPT_EXIT() csi_kernel_intrpt_exit() +#else +#define CSI_INTRPT_ENTER() +#define CSI_INTRPT_EXIT() +#endif + +ATTRIBUTE_ISR void CORET_IRQHandler(void) +{ + readl(0xE000E010); +} + +#if defined(CONFIG_USART) +ATTRIBUTE_ISR void USART0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void USART1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(1); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void USART2_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(2); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void USART3_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_usart_irqhandler(3); + CSI_INTRPT_EXIT(); +} + +#endif + +#if defined(CONFIG_TIMER) +ATTRIBUTE_ISR void TIMA0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void TIMA1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(1); + CSI_INTRPT_EXIT(); +} +ATTRIBUTE_ISR void TIMB0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(2); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void TIMB1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_timer_irqhandler(3); + CSI_INTRPT_EXIT(); +} + +#endif + +#if defined(CONFIG_GPIO) + +ATTRIBUTE_ISR void GPIOA_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_gpio_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void GPIOB_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_gpio_irqhandler(1); + CSI_INTRPT_EXIT(); +} +#endif + +#if defined(CONFIG_IIC) +ATTRIBUTE_ISR void I2C0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_iic_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void I2C1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_iic_irqhandler(1); + CSI_INTRPT_EXIT(); +} +#endif + +#if defined(CONFIG_RTC) + +ATTRIBUTE_ISR void RTC_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_rtc_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +#endif + +#if defined(CONFIG_AES) + +ATTRIBUTE_ISR void AES_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_aes_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +#endif + +#if defined(CONFIG_SHA) + +ATTRIBUTE_ISR void SHA_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_sha_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +#endif + +#if defined(CONFIG_SPI) && defined(CONFIG_GPIO) +ATTRIBUTE_ISR void SPI0_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_spi_irqhandler(0); + CSI_INTRPT_EXIT(); +} + +ATTRIBUTE_ISR void SPI1_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_spi_irqhandler(1); + CSI_INTRPT_EXIT(); +} +#endif + +#if defined(CONFIG_WDT) +ATTRIBUTE_ISR void WDT_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + dw_wdt_irqhandler(0); + CSI_INTRPT_EXIT(); +} +#endif + +#if defined(CONFIG_DMAC) +ATTRIBUTE_ISR void DMAC_IRQHandler(void) +{ + CSI_INTRPT_ENTER(); + ck_dma_irqhandler(0); + CSI_INTRPT_EXIT(); +} +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/pinmux.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/pinmux.c new file mode 100644 index 000000000..27cee1132 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/phobos/pinmux.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file pinmux.c + * @brief source file for the pinmux + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#include +#include "pinmux.h" +#include "pin_name.h" + +#define readl(addr) \ + ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) + +#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) + +/******************************************************************************* + * function: phobos_ioreuse_inital + * + * description: + * initial phobos_pinmux + *******************************************************************************/ + +void phobos_ioreuse_initial(void) +{ + unsigned int value; + + /* gpio data source select */ + value = readl(PHOBOS_GIPO0_PORTCTL_REG); + value |= GPIO0_REUSE_EN; + writel(value, PHOBOS_GIPO0_PORTCTL_REG); + + value = readl(PHOBOS_GIPO1_PORTCTL_REG); + value |= GPIO1_REUSE_EN; + writel(value, PHOBOS_GIPO1_PORTCTL_REG); + + /* reuse function select */ + value = readl(PHOBOS_IOMUX0L_REG); + value |= IOMUX0L_FUNCTION_SEL; + writel(value, PHOBOS_IOMUX0L_REG); + + value = readl(PHOBOS_IOMUX0H_REG); + value |= IOMUX1L_FUNCTION_SEL; + writel(value, PHOBOS_IOMUX0H_REG); + + value = readl(PHOBOS_IOMUX1L_REG); + value |= IOMUX1L_FUNCTION_SEL; + writel(value, PHOBOS_IOMUX1L_REG); +} + +void phobos_pwm_ioreuse(void) +{ + unsigned int value; + + /* gpio data source select */ + value = readl(PHOBOS_GIPO0_PORTCTL_REG); + value |= PWM_GPIO0_REUSE_EN; + writel(value, PHOBOS_GIPO0_PORTCTL_REG); + + /* reuse function select */ + value = readl(PHOBOS_IOMUX0L_REG); + value |= PWM_IOMUX0L_FUNCTION_SEL; + writel(value, PHOBOS_IOMUX0L_REG); +} + + +int32_t pin_mux(pin_name_t pin, uint16_t function) +{ + unsigned int val = 0; + unsigned int reg_val = 0; + + uint8_t offset; + + if (function > 3) { + if (pin < PB0_ADC0_SDA0_PWM5_XX) { + offset = pin; + /* gpio data source select */ + val = readl(PHOBOS_GIPO0_PORTCTL_REG); + val &= ~(1 << offset); + writel(val, PHOBOS_GIPO0_PORTCTL_REG); + return 0; + } else if (pin >= PB0_ADC0_SDA0_PWM5_XX) { + offset = pin - 32; + /* gpio data source select */ + val = readl(PHOBOS_GIPO1_PORTCTL_REG); + val &= ~(1 << offset); + writel(val, PHOBOS_GIPO1_PORTCTL_REG); + return 0; + } else { + return -1; + } + } + + if (pin >= PB0_ADC0_SDA0_PWM5_XX) { + offset = pin - 32; + + /* gpio data source select */ + val = readl(PHOBOS_GIPO1_PORTCTL_REG); + val |= (1 << offset); + writel(val, PHOBOS_GIPO1_PORTCTL_REG); + + reg_val = (0x3 << (offset * 2)); + /* reuse function select */ + val = readl(PHOBOS_IOMUX1L_REG); + val &= ~(reg_val); + val |= (function << (2 * offset)); + writel(val, PHOBOS_IOMUX1L_REG); + return 0; + } + + offset = pin; + /* gpio data source select */ + val = readl(PHOBOS_GIPO0_PORTCTL_REG); + val |= (1 << offset); + writel(val, PHOBOS_GIPO0_PORTCTL_REG); + + if (pin >= PA16_SPI1CLK_PWMTRIG1_XX_XX) { + offset = pin - 16; + reg_val = (0x3 << (offset * 2)); + /* reuse function select */ + val = readl(PHOBOS_IOMUX0H_REG); + val &= ~(reg_val); + val |= (function << (2 * offset)); + writel(val, PHOBOS_IOMUX0H_REG); + return 0; + } + + reg_val = (0x3 << (offset * 2)); + /* reuse function select */ + val = readl(PHOBOS_IOMUX0L_REG); + val &= ~(reg_val); + val |= (function << (2 * offset)); + writel(val, PHOBOS_IOMUX0L_REG); + return 0; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/config.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/config.h new file mode 100644 index 000000000..b7927eeaf --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/config.h @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2016 CSI Project. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +#define CONFIG_USART 1 + +#define CONFIG_SYSTEM_SECURE +#define CONFIG_HAVE_VIC +#define CONFIG_SHA_SUPPORT_MUL_THREAD 1 +#define CONFIG_KERNEL_NONE 1 +#define CONFIG_DISABLE_IRQ 1 + +#endif /* __CSI_WIFI_H__ */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_aes.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_aes.h new file mode 100644 index 000000000..c6fbc0cce --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_aes.h @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file drv_aes.h + * @brief Header File for AES Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CSI_AES_H_ +#define _CSI_AES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + + +/// definition for aes handle. +typedef void *aes_handle_t; + +/****** AES specific error codes *****/ +typedef enum { + AES_ERROR_MODE = (EDRV_SPECIFIC + 1) , ///< Specified Mode not supported + AES_ERROR_DATA_BITS , ///< Specified number of Data bits not supported + AES_ERROR_ENDIAN ///< Specified endian not supported +} drv_aes_error_e; + +/*----- AES Control Codes: Mode -----*/ +typedef enum { + AES_MODE_ECB = 0, ///< ECB Mode + AES_MODE_CBC , ///< CBC Mode + AES_MODE_CFB , ///< CFB Mode + AES_MODE_OFB , ///< OFB Mode + AES_MODE_CTR ///< CTR Mode +} aes_mode_e; + +/*----- AES Control Codes: Crypto Mode -----*/ +typedef enum { + AES_CRYPTO_MODE_ENCRYPT = 0, ///< encrypt Mode + AES_CRYPTO_MODE_DECRYPT , ///< decrypt Mode +} aes_crypto_mode_e; + +/*----- AES Control Codes: Padding Mode -----*/ +typedef enum { + AES_PADDING_MODE_NO = 0, ///< NO-PADDING + AES_PADDING_MODE_ZERO , ///< ZERO-PADDING + AES_PADDING_MODE_PKCS5 ///< PKCS5-PADDING +} aes_padding_mode_e; + +/*----- AES Control Codes: Mode Parameters: Key length -----*/ +typedef enum { + AES_KEY_LEN_BITS_128 = 0, ///< 128 Data bits + AES_KEY_LEN_BITS_192 , ///< 192 Data bits + AES_KEY_LEN_BITS_256 ///< 256 Data bits +} aes_key_len_bits_e; + +/*----- AES Control Codes: Mode Parameters: Endian -----*/ +typedef enum { + AES_ENDIAN_LITTLE = 0, ///< Little Endian + AES_ENDIAN_BIG ///< Big Endian +} aes_endian_mode_e; + +/** +\brief AES Status +*/ +typedef struct { + uint32_t busy : 1; ///< busy flag +} aes_status_t; + +/****** AES Event *****/ +typedef enum { + AES_EVENT_CRYPTO_COMPLETE = 0 ///< Encrypt completed +} aes_event_e; +typedef void (*aes_event_cb_t)(aes_event_e event); ///< Pointer to \ref aes_event_cb_t : AES Event call back. + + +/** +\brief AES Device Driver Capabilities. +*/ +typedef struct { + uint32_t ecb_mode : 1; ///< supports ECB mode + uint32_t cbc_mode : 1; ///< supports CBC mode + uint32_t cfb_mode : 1; ///< supports CFB mode + uint32_t ofb_mode : 1; ///< supports OFB mode + uint32_t ctr_mode : 1; ///< supports CTR mode + uint32_t bits_128 : 1; ///< supports 128bits key length + uint32_t bits_192 : 1; ///< supports 192bits key length + uint32_t bits_256 : 1; ///< supports 256bits key length +} aes_capabilities_t; + + +// Function documentation + +/** + \brief get aes instance count. + \return aes handle count +*/ +int32_t csi_aes_get_instance_count(void); + +/** + \brief Initialize AES Interface. 1. Initializes the resources needed for the AES interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_aes_get_instance_count(). + \param[in] cb_event Pointer to \ref aes_event_cb_t + \return return aes handle if success +*/ +aes_handle_t csi_aes_initialize(int32_t idx, aes_event_cb_t cb_event); + +/** + \brief De-initialize AES Interface. stops operation and releases the software resources used by the interface + \param[in] handle aes handle to operate. + \return error code +*/ +int32_t csi_aes_uninitialize(aes_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle aes handle to operate. + \return \ref aes_capabilities_t +*/ +aes_capabilities_t csi_aes_get_capabilities(aes_handle_t handle); + +/** + \brief config aes mode. + \param[in] handle aes handle to operate. + \param[in] mode \ref aes_mode_e + \param[in] keylen_bits \ref aes_key_len_bits_e + \param[in] endian \ref aes_endian_mode_e + \param[in] arg Pointer to the iv address when mode is cbc_mode + \return error code +*/ +int32_t csi_aes_config(aes_handle_t handle, + aes_mode_e mode, + aes_key_len_bits_e keylen_bits, + aes_endian_mode_e endian, + uint32_t arg + ); + +/** + \brief set crypto key. + \param[in] handle aes handle to operate. + \param[in] context aes information context(NULL when hardware implementation) + \param[in] key Pointer to the key buf + \param[in] key_len Pointer to \ref aes_key_len_bits_e + \param[in] enc \ref aes_crypto_mode_e + \return error code +*/ +int32_t csi_aes_set_key(aes_handle_t handle, void *context, void *key, aes_key_len_bits_e key_len, aes_crypto_mode_e enc); + +/** + \brief encrypt or decrypt + \param[in] handle aes handle to operate. + \param[in] context aes information context(NULL when hardware implementation) + \param[in] in Pointer to the Source data + \param[out] out Pointer to the Result data. + \param[in] len the Source data len. + \param[in] padding \ref aes_padding_mode_e. + \return error code +*/ +int32_t csi_aes_crypto(aes_handle_t handle, void *context, void *in, void *out, uint32_t len, aes_padding_mode_e padding); + +/** + \brief Get AES status. + \param[in] handle aes handle to operate. + \return AES status \ref aes_status_t +*/ +aes_status_t csi_aes_get_status(aes_handle_t handle); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_AES_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_common.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_common.h new file mode 100644 index 000000000..fef26479e --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_common.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file drv_common.h + * @brief Header File for Common Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _DRV_COMMON_H_ +#define _DRV_COMMON_H_ + +#include +#include +#include "config.h" + +/** pin definition */ +typedef int32_t pin_t; + +/// \details driver handle +typedef void *drv_handle_t; + +/** +\brief General power states +*/ +typedef enum { + DRV_POWER_OFF, ///< Power off: no operation possible + DRV_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events + DRV_POWER_FULL ///< Power on: full operation at maximum performance +} csi_power_stat_e; + +#endif /* _DRV_COMMON_H */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_crc.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_crc.h new file mode 100644 index 000000000..bde0e9ed1 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_crc.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file drv_crc.h + * @brief Header File for CRC Driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CSI_CRC_H_ +#define _CSI_CRC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + + +/****** CRC specific error codes *****/ +#define CRC_ERROR_MODE (EDRV_SPECIFIC + 1) ///< Specified Mode not supported + +/// definition for crc handle. +typedef void *crc_handle_t; + +/*----- CRC Control Codes: Mode -----*/ +typedef enum { + CRC_MODE_CRC8 = 0, ///< Mode CRC8 + CRC_MODE_CRC16 , ///< Mode CRC16 + CRC_MODE_CRC32 ///< Mode CRC32 +} crc_mode_e; + +/*----- CRC Control Codes: Mode Parameters: Key length -----*/ +typedef enum { + CRC_STANDARD_CRC_ROHC = 0, ///< Standard CRC RHOC + CRC_STANDARD_CRC_MAXIM , ///< Standard CRC MAXIAM + CRC_STANDARD_CRC_X25 , ///< Standard CRC X25 + CRC_STANDARD_CRC_CCITT , ///< Standard CRC CCITT + CRC_STANDARD_CRC_USB , ///< Standard CRC USB + CRC_STANDARD_CRC_IBM , ///< Standard CRC IBM + CRC_STANDARD_CRC_MODBUS ///< Standard CRC MODBUS +} crc_standard_crc_e; + +/** +\brief CRC Status +*/ +typedef struct { + uint32_t busy : 1; ///< busy flag +} crc_status_t; + +/****** CRC Event *****/ +typedef enum { + CRC_EVENT_CALCULATE_COMPLETE = 0, ///< Calculate completed +} crc_event_e; + +typedef void (*crc_event_cb_t)(crc_event_e event); ///< Pointer to \ref crc_event_cb_t : CRC Event call back. + +/** +\brief CRC Device Driver Capabilities. +*/ +typedef struct { + uint32_t ROHC : 1; ///< supports ROHC mode + uint32_t MAXIM : 1; ///< supports MAXIM mode + uint32_t X25 : 1; ///< supports X25 mode + uint32_t CCITT : 1; ///< supports CCITT mode + uint32_t USB : 1; ///< supports USB mode + uint32_t IBM : 1; ///< supports IBM mode + uint32_t MODBUS : 1; ///< supports MODBUS mode +} crc_capabilities_t; + +// Function documentation + +/** + \brief get crc handle count. + \return crc handle count +*/ +int32_t csi_crc_get_instance_count(void); + +/** + \brief Initialize CRC Interface. 1. Initializes the resources needed for the CRC interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_crc_get_handle_count() + \param[in] cb_event Pointer to \ref crc_event_cb_t + \return return crc handle if success +*/ +crc_handle_t csi_crc_initialize(int32_t idx, crc_event_cb_t cb_event); + +/** + \brief De-initialize CRC Interface. stops operation and releases the software resources used by the interface + \param[in] handle crc handle to operate. + \return error code +*/ +int32_t csi_crc_uninitialize(crc_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle crc handle to operate. + \return \ref crc_capabilities_t +*/ +crc_capabilities_t csi_crc_get_capabilities(crc_handle_t handle); + +/** + \brief config crc mode. + \param[in] handle crc handle to operate. + \param[in] mode \ref crc_mode_e + \param[in] standard \ref crc_standard_crc_e + \return error code +*/ +int32_t csi_crc_config(crc_handle_t handle, + crc_mode_e mode, + crc_standard_crc_e standard + ); + +/** + \brief calculate crc. + \param[in] handle crc handle to operate. + \param[in] in Pointer to the input data + \param[out] out Pointer to the result. + \param[in] len intpu data len. + \return error code +*/ +int32_t csi_crc_calculate(crc_handle_t handle, const void *in, void *out, uint32_t len); + +/** + \brief Get CRC status. + \param[in] handle crc handle to operate. + \return CRC status \ref crc_status_t +*/ +crc_status_t csi_crc_get_status(crc_handle_t handle); + + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_CRC_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_dmac.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_dmac.h new file mode 100644 index 000000000..633e06169 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_dmac.h @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_dmac.h + * @brief header file for dmac driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CSI_DMA_H_ +#define _CSI_DMA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/// definition for dmac handle. +typedef void *dmac_handle_t; + +/** +\brief DMA Driver Capabilities. +*/ +typedef struct { + uint32_t unalign_addr : 1; ///< support for unalign address transfer when memory is source +} dma_capabilities_t; + +typedef enum { + DMA_STATE_FREE = 0, ///< DMA not yet initialized or disabled + DMA_STATE_READY, ///< DMA process success and ready for use, but not start yet + DMA_STATE_BUSY, ///< DMA process is ongoing + DMA_STATE_ERROR, ///< DMA transfer error + DMA_STATE_DONE, ///< DMA transfer done +} dma_status_e; + +/****** DMA specific error codes *****/ +typedef enum { + EDRV_DMA_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported +} dma_error_e; + +/****** DMA Event *****/ +typedef enum { + DMA_EVENT_TRANSFER_DONE = 0, ///< transfer complete + DMA_EVENT_TRANSFER_ERROR = 1, ///< transfer error +} dma_event_e; + +typedef enum { + DMA_ADDR_INC = 0, + DMA_ADDR_DEC, + DMA_ADDR_CONSTANT +} dma_addr_inc_e; + +typedef enum { + DMA_MEM2MEM = 0, + DMA_MEM2PERH, + DMA_PERH2MEM, + DMA_PERH2PERH, +} dma_trans_type_e; + +typedef struct { + dma_addr_inc_e src_inc; ///< source address increment + dma_addr_inc_e dst_inc; ///< destination address increment + uint8_t src_tw; ///< source transfer width in byte + uint8_t dst_tw; ///< destination transfer width in byte + uint8_t hs_if; ///< a hardware handshaking interface + dma_trans_type_e type; ///< transfer type +} dma_config_t; + +typedef void (*dma_event_cb_t)(dma_event_e event, int32_t ch); ///< Pointer to \ref dma_event_cb_t : CRC Event call back. + +/** + \brief get dma instance count. + \return dma instance count +*/ +int32_t csi_dma_get_instance_count(void); + +/** + \brief Initialize DMA Interface. 1. Initializes the resources needed for the DMA interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_dma_get_instance_count() + \return pointer to dma instances +*/ +dmac_handle_t csi_dma_initialize(int32_t idx); + +/** + \brief De-initialize DMA Interface. stops operation and releases the software resources used by the interface + \param[in] handle damc handle to operate. + \return error code +*/ +int32_t csi_dma_uninitialize(dmac_handle_t handle); +/** + \brief Get driver capabilities. + \param[in] handle damc handle to operate. + \return \ref dma_capabilities_t +*/ +dma_capabilities_t csi_dma_get_capabilities(dmac_handle_t handle); + +/** + \brief get one free dma channel + \param[in] handle damc handle to operate. + \param[in] ch channel num. if -1 then allocate a free channal in this dma + \return -1 - no channel can be used, other - channel index + */ +int32_t csi_dma_alloc_channel(dmac_handle_t handle, int32_t ch); + +/** + \brief release dma channel and related resources + \param[in] handle damc handle to operate. + \param[in] ch channel num. + \return error code + */ +int32_t csi_dma_release_channel(dmac_handle_t handle, int32_t ch); + +/** + \brief + \param[in] handle damc handle to operate. + \param[in] ch channel num. if -1 then allocate a free channal in this dma + \param[in] psrcaddr dma transfer source address + \param[in] pstdaddr dma transfer source address + \param[in] length dma transfer length + \param[in] config dma transfer configure + \param[in] cb_event Pointer to \ref dma_event_cb_t + \return error code + */ +int32_t csi_dma_config(dmac_handle_t handle, int32_t ch, + void *psrcaddr, void *pstdaddr, + uint32_t length, dma_config_t *config, dma_event_cb_t cb_event); + +/** + \brief start generate dma signal. + \param[in] handle damc handle to operate. + \param[in] ch channel num. + \return error code +*/ +int32_t csi_dma_start(dmac_handle_t handle, int32_t ch); + +/** + \brief Stop generate dma signal. + \param[in] handle damc handle to operate. + \param[in] ch channel num. + \return error code +*/ +int32_t csi_dma_stop(dmac_handle_t handle, int32_t ch); + +/** + \brief Get DMA status. + \param[in] handle damc handle to operate. + \param[in] ch channel num. + \return DMA status \ref dma_status_e +*/ +dma_status_e csi_dma_get_status(dmac_handle_t handle, int32_t ch); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_DMA_H_ */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eflash.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eflash.h new file mode 100644 index 000000000..031a04e1c --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eflash.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_eflash.h + * @brief header file for eflash driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CSI_EFLASH_H_ +#define _CSI_EFLASH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + +/// definition for eflash handle. +typedef void *eflash_handle_t; + +/** +\brief Flash information +*/ +typedef struct { + uint32_t start; ///< Chip Start address + uint32_t end; ///< Chip End address (start+size-1) + uint32_t sector_count; ///< Number of sectors + uint32_t sector_size; ///< Uniform sector size in bytes (0=sector_info used) + uint32_t page_size; ///< Optimal programming page size in bytes + uint32_t program_unit; ///< Smallest programmable unit in bytes + uint8_t erased_value; ///< Contents of erased memory (usually 0xFF) +} eflash_info_t; + +/** +\brief Flash Status +*/ +typedef struct { + uint32_t busy : 1; ///< Flash busy flag + uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation) +} eflash_status_t; + +/****** EFLASH Event *****/ +typedef enum { + EFLASH_EVENT_READY = 0, ///< Flash Ready + EFLASH_EVENT_ERROR , ///< Read/Program/Erase Error +} eflash_event_e; + +typedef void (*eflash_event_cb_t)(eflash_event_e event); ///< Pointer to \ref eflash_event_cb_t : EFLASH Event call back. + +/** +\brief Flash Driver Capabilities. +*/ +typedef struct { + uint32_t event_ready : 1; ///< Signal Flash Ready event + uint32_t data_width : 2; ///< Data width: 0=8-bit, 1=16-bit, 2=32-bit + uint32_t erase_chip : 1; ///< Supports EraseChip operation +} eflash_capabilities_t; + +// Function documentation + +/** + \brief get eflash handle count. + \return eflash handle count +*/ +int32_t csi_eflash_get_instance_count(void); + +/** + \brief Initialize EFLASH Interface. 1. Initializes the resources needed for the EFLASH interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_eflash_get_instance_count() + \param[in] cb_event Pointer to \ref eflash_event_cb_t + \return pointer to eflash handle +*/ +eflash_handle_t csi_eflash_initialize(int32_t idx, eflash_event_cb_t cb_event); + +/** + \brief De-initialize EFLASH Interface. stops operation and releases the software resources used by the interface + \param[in] handle eflash handle to operate. + \return error code +*/ +int32_t csi_eflash_uninitialize(eflash_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle eflash handle to operate. + \return \ref eflash_capabilities_t +*/ +eflash_capabilities_t csi_eflash_get_capabilities(eflash_handle_t handle); + +/** + \brief Read data from Flash. + \param[in] handle eflash handle to operate. + \param[in] addr Data address. + \param[out] data Pointer to a buffer storing the data read from Flash. + \param[in] cnt Number of data items to read. + \return number of data items read or error code +*/ +int32_t csi_eflash_read(eflash_handle_t handle, uint32_t addr, void *data, uint32_t cnt); + +/** + \brief Program data to Flash. + \param[in] handle eflash handle to operate. + \param[in] addr Data address. + \param[in] data Pointer to a buffer containing the data to be programmed to Flash.. + \param[in] cnt Number of data items to program. + \return number of data items programmed or error code +*/ +int32_t csi_eflash_program(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt); + +/** + \brief Erase Flash Sector. + \param[in] handle eflash handle to operate. + \param[in] addr Sector address + \return error code +*/ +int32_t csi_eflash_erase_sector(eflash_handle_t handle, uint32_t addr); + +/** + \brief Erase complete Flash. + \param[in] handle eflash handle to operate. + \return error code +*/ +int32_t csi_eflash_erase_chip(eflash_handle_t handle); + +/** + \brief Get Flash information. + \param[in] handle eflash handle to operate. + \return Pointer to Flash information \ref eflash_info +*/ +eflash_info_t *csi_eflash_get_info(eflash_handle_t handle); + +/** + \brief Get EFLASH status. + \param[in] handle eflash handle to operate. + \return EFLASH status \ref eflash_status_t +*/ +eflash_status_t csi_eflash_get_status(eflash_handle_t handle); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_EFLASH_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_errno.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_errno.h new file mode 100644 index 000000000..fdc206d2c --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_errno.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_errno.h + * @brief header file for error num + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +/****************************************************************************** + * @file + * @details Error code field difination + * Error number is devided into 4 field: + * 0x8******* : 8 : means < 0 + * 0x*A****** : A : means type number: bsp(1), driver(2), hal(3), app(4)... + * 0x**AB**** : AB : means module number: timer(1), rtc(2), .... + * 0x****AB** : AB : means API number: module API's definition + * 0x******AB : AB : means sub error number + * 0 ~ 0x80 is common error such as EPERM, refer to errno.h + * 0x80 ~ 0xFF is specific error, can difine in module + * + * For example 0x81020113 means: + * 1. 0x8*******: value < 0, means error happened + * 2. 0x*1******: type number is 1, means bsp error + * 3. 0x**02****: module number is 02, means RTC error + * 4. 0x****01**: module API is 01, means RTC's init + * 5. 0x******13: specific error is 0x13=19=ENODEV, means no such device + * + * For special bsp module example, you can return: + * (BSP_ERRNO_TIMER_BASE | BSP_API_RTC_INIT | EPERM) for rtc init error + * (BSP_ERRNO_TIMER_BASE | BSP_API_RTC_SETTIME | ENXIO) for rtc settime error + * + * Here list the common sub error number (0x******AB) below(0~127 defined in errno.h as standard err code): + * Code Hex Deci Meaning + * ------------------------------------------------------- + * EPERM 0x01 1 Operation not permitted + * EIO 0x05 5 I/O error + * ENXIO 0x06 6 No such device or address + * ENOMEM 0x0C 12 Out of memory + * EACCES 0x0D 13 Permission denied + * EINVAL 0x16 22 Invalid argument + * ... + * SPEC_ERR_BASE 0x80 128 module special error number base + * ... + * ERRNO_MAX 0xFF -- Max sub error number + ******************************************************************************/ + +#ifndef _DRV_ERRNO_H_ +#define _DRV_ERRNO_H_ + + +#include + +#define ERRNO_DRV_START 0X80 + +/* drvier General return codes */ +typedef enum { + EDRV = ERRNO_DRV_START, ///< Unspecified error + EDRV_BUSY, ///< Driver is busy + EDRV_TIMEOUT, ///< Timeout occurred + EDRV_UNSUPPORTED, ///< Operation not supported + EDRV_PARAMETER, ///< Parameter error + EDRV_SPECIFIC ///< Start of driver specific errors +} drv_common_err_e; + + +/** Get error type */ +#define GET_ERROR_TYPE(errno) \ + (error & 0xFF000000 >> 24) +/** Get error module */ +#define GET_ERROR_MODULE(error) \ + (error & 0x00FF0000 >> 16) +/** Get error API */ +#define GET_ERROR_API(error) \ + (error & 0x0000FF00 >> 8) +/** Get errno */ +#define GET_ERROR_NUM(error) \ + (error & 0x000000FF) + +#ifndef CSI_DRV_ERRNO_BASE +/** means bsp errors */ +#define CSI_DRV_ERRNO_BASE 0x81000000 +#endif + +/** driver module id definition*/ +#define CSI_DRV_ERRNO_GPIO_BASE 0x81010000 +#define CSI_DRV_ERRNO_USART_BASE 0x81020000 +#define CSI_DRV_ERRNO_SPI_BASE 0x81030000 +#define CSI_DRV_ERRNO_I2C_BASE 0x81040000 +#define CSI_DRV_ERRNO_FLASH_BASE 0x81050000 +#define CSI_DRV_ERRNO_PWM_BASE 0x81060000 +#define CSI_DRV_ERRNO_RTC_BASE 0x81070000 +#define CSI_DRV_ERRNO_TIMER_BASE 0x81080000 +#define CSI_DRV_ERRNO_WDT_BASE 0x81090000 +#define CSI_DRV_ERRNO_AES_BASE 0x810A0000 +#define CSI_DRV_ERRNO_CRC_BASE 0x810B0000 +#define CSI_DRV_ERRNO_RSA_BASE 0x810C0000 +#define CSI_DRV_ERRNO_SHA_BASE 0x810D0000 +#define CSI_DRV_ERRNO_TRNG_BASE 0x810E0000 +#define CSI_DRV_ERRNO_EFLASH_BASE 0x810F0000 +#define CSI_DRV_ERRNO_DMA_BASE 0x81100000 +#define CSI_DRV_ERRNO_NORFLASH_BASE 0x81110000 +#define CSI_DRV_ERRNO_INTC_BASE 0x81120000 +#define CSI_DRV_ERRNO_SPU_BASE 0x81110000 +#define CSI_DRV_ERRNO_TEE_BASE 0x81130000 +#define CSI_DRV_ERRNO_PMU_BASE 0x81140000 + +#endif /* CSI_DRV_ERRNO_H */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eth.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eth.h new file mode 100644 index 000000000..6ab39f9c1 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eth.h @@ -0,0 +1,105 @@ +/** + * Copyright (C) 2016 CSI Project. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef _CSI_NET_H_ +#define _CSI_NET_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define CSI_ETH_VERSION_MAJOR_MINOR(major,minor) (((major) << 8) | (minor)) + +/** +\brief Driver Version +*/ +typedef struct csi_driver_version { + uint16_t api; ///< API version + uint16_t drv; ///< Driver version +} csi_drv_version_t; + +/* General return codes */ +#define CSI_ETH_OK 0 ///< Operation succeeded +#define CSI_ETH_ERROR CSI_DRV_ERRNO_ETH_BASE+1 ///< Unspecified error +#define CSI_ETH_ERROR_BUSY CSI_DRV_ERRNO_ETH_BASE+2 ///< Driver is busy +#define CSI_ETH_ERROR_TIMEOUT CSI_DRV_ERRNO_ETH_BASE+3 ///< Timeout occurred +#define CSI_ETH_ERROR_UNSUPPORTED CSI_DRV_ERRNO_ETH_BASE+4 ///< Operation not supported +#define CSI_ETH_ERROR_PARAMETER CSI_DRV_ERRNO_ETH_BASE+5 ///< Parameter error +#define CSI_ETH_ERROR_SPECIFIC CSI_DRV_ERRNO_ETH_BASE+6 ///< Start of driver specific errors + +/** +\brief General power states +*/ +typedef enum eth_power_state { + CSI_ETH_POWER_OFF, ///< Power off: no operation possible + CSI_ETH_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events + CSI_ETH_POWER_FULL ///< Power on: full operation at maximum performance +} eth_power_state_t; + +/** +\brief Ethernet Media Interface type +*/ +#define CSI_ETH_INTERFACE_MII (0) ///< Media Independent Interface (MII) +#define CSI_ETH_INTERFACE_RMII (1) ///< Reduced Media Independent Interface (RMII) +#define CSI_ETH_INTERFACE_SMII (2) ///< Serial Media Independent Interface (SMII) + +/** +\brief Ethernet link speed +*/ +#define CSI_ETH_SPEED_10M (0) ///< 10 Mbps link speed +#define CSI_ETH_SPEED_100M (1) ///< 100 Mbps link speed +#define CSI_ETH_SPEED_1G (2) ///< 1 Gpbs link speed + +/** +\brief Ethernet duplex mode +*/ +#define CSI_ETH_DUPLEX_HALF (0) ///< Half duplex link +#define CSI_ETH_DUPLEX_FULL (1) ///< Full duplex link + +/** +\brief Ethernet link state +*/ +typedef enum eth_link_state { + ETH_LINK_DOWN, ///< Link is down + ETH_LINK_UP ///< Link is up +} eth_link_state_t; + +/** +\brief Ethernet link information +*/ +typedef volatile struct eth_link_info { + uint32_t speed : 2; ///< Link speed: 0= 10 MBit, 1= 100 MBit, 2= 1 GBit + uint32_t duplex : 1; ///< Duplex mode: 0= Half, 1= Full + uint32_t Autonegotiation : 1; ///< Set the interface to Auto Negotiation mode of transmission parameters + uint32_t Loopback : 1; ///< Set the interface into a Loop-back test mode + uint32_t Isolation : 1; ///< Set to indicate electrical isolation of PHY interface from MII/RMII interface + uint32_t reserved : 26; +} eth_link_info_t; + +/** +\brief Ethernet MAC Address +*/ +typedef struct eth_mac_addr { + uint8_t b[6]; ///< MAC Address (6 bytes), MSB first +} eth_mac_addr_t; + +#ifdef __cplusplus +} +#endif + +#endif /* CSI_NET_H_ */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eth_mac.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eth_mac.h new file mode 100644 index 000000000..f3bda90fb --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eth_mac.h @@ -0,0 +1,422 @@ +/** + * Copyright (C) 2016 CSI Project. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CSI_ETH_H_ +#define _CSI_ETH_H_ + +#include "drv_eth.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *eth_mac_handle_t; + +#define MAX_FRAMELEN 1518 /* (note: maximum ethernet frame length would be 1518) */ + +#define CSI_ETH_MAC_API_VERSION CSI_DRIVER_VERSION_MAJOR_MINOR(2,1) /* API version */ + +#define _CSI_Driver_ETH_MAC_(n) Driver_ETH_MAC##n +#define CSI_Driver_ETH_MAC_(n) _CSI_Driver_ETH_MAC_(n) + +/****** Ethernet MAC Control Codes *****/ + +#define CSI_ETH_MAC_CONFIGURE (0x01) ///< Configure MAC; arg = configuration +#define CSI_ETH_MAC_CONTROL_TX (0x02) ///< Transmitter; arg: 0=disabled (default), 1=enabled +#define CSI_ETH_MAC_CONTROL_RX (0x03) ///< Receiver; arg: 0=disabled (default), 1=enabled +#define CSI_ETH_MAC_FLUSH (0x04) ///< Flush buffer; arg = CSI_ETH_MAC_FLUSH_... +#define CSI_ETH_MAC_SLEEP (0x05) ///< Sleep mode; arg: 1=enter and wait for Magic packet, 0=exit +#define CSI_ETH_MAC_VLAN_FILTER (0x06) ///< VLAN Filter for received frames; arg15..0: VLAN Tag; arg16: optional CSI_ETH_MAC_VLAN_FILTER_ID_ONLY; 0=disabled (default) + +/*----- Ethernet MAC Configuration -----*/ +#define CSI_ETH_MAC_SPEED_Pos 0 +#define CSI_ETH_MAC_SPEED_Msk (3UL << CSI_ETH_MAC_SPEED_Pos) +#define CSI_ETH_MAC_SPEED_10M (CSI_ETH_SPEED_10M << CSI_ETH_MAC_SPEED_Pos) ///< 10 Mbps link speed +#define CSI_ETH_MAC_SPEED_100M (CSI_ETH_SPEED_100M << CSI_ETH_MAC_SPEED_Pos) ///< 100 Mbps link speed +#define CSI_ETH_MAC_SPEED_1G (CSI_ETH_SPEED_1G << CSI_ETH_MAC_SPEED_Pos) ///< 1 Gpbs link speed +#define CSI_ETH_MAC_DUPLEX_Pos 2 +#define CSI_ETH_MAC_DUPLEX_Msk (1UL << CSI_ETH_MAC_DUPLEX_Pos) +#define CSI_ETH_MAC_DUPLEX_HALF (CSI_ETH_DUPLEX_HALF << CSI_ETH_MAC_DUPLEX_Pos) ///< Half duplex link +#define CSI_ETH_MAC_DUPLEX_FULL (CSI_ETH_DUPLEX_FULL << CSI_ETH_MAC_DUPLEX_Pos) ///< Full duplex link +#define CSI_ETH_MAC_LOOPBACK (1UL << 4) ///< Loop-back test mode +#define CSI_ETH_MAC_CHECKSUM_OFFLOAD_RX (1UL << 5) ///< Receiver Checksum offload +#define CSI_ETH_MAC_CHECKSUM_OFFLOAD_TX (1UL << 6) ///< Transmitter Checksum offload +#define CSI_ETH_MAC_ADDRESS_BROADCAST (1UL << 7) ///< Accept frames with Broadcast address +#define CSI_ETH_MAC_ADDRESS_MULTICAST (1UL << 8) ///< Accept frames with any Multicast address +#define CSI_ETH_MAC_ADDRESS_ALL (1UL << 9) ///< Accept frames with any address (Promiscuous Mode) + +/*----- Ethernet MAC Flush Flags -----*/ +#define CSI_ETH_MAC_FLUSH_RX (1UL << 0) ///< Flush Receive buffer +#define CSI_ETH_MAC_FLUSH_TX (1UL << 1) ///< Flush Transmit buffer + +/*----- Ethernet MAC VLAN Filter Flag -----*/ +#define CSI_ETH_MAC_VLAN_FILTER_ID_ONLY (1UL << 16) ///< Compare only the VLAN Identifier (12-bit) + + +/****** Ethernet MAC Frame Transmit Flags *****/ +#define CSI_ETH_MAC_TX_FRAME_FRAGMENT (1UL << 0) ///< Indicate frame fragment +#define CSI_ETH_MAC_TX_FRAME_EVENT (1UL << 1) ///< Generate event when frame is transmitted +#define CSI_ETH_MAC_TX_FRAME_TIMESTAMP (1UL << 2) ///< Capture frame time stamp + + +/****** Ethernet MAC Timer Control Codes *****/ +#define CSI_ETH_MAC_TIMER_GET_TIME (0x01) ///< Get current time +#define CSI_ETH_MAC_TIMER_SET_TIME (0x02) ///< Set new time +#define CSI_ETH_MAC_TIMER_INC_TIME (0x03) ///< Increment current time +#define CSI_ETH_MAC_TIMER_DEC_TIME (0x04) ///< Decrement current time +#define CSI_ETH_MAC_TIMER_SET_ALCSI (0x05) ///< Set alarm time +#define CSI_ETH_MAC_TIMER_ADJUST_CLOCK (0x06) ///< Adjust clock frequency; time->ns: correction factor * 2^31 + + +/** +\brief Ethernet MAC Time +*/ +typedef struct eth_mac_time { + uint32_t ns; ///< Nano seconds + uint32_t sec; ///< Seconds +} eth_mac_time_t; + + +/****** Ethernet MAC Event *****/ +#define CSI_ETH_MAC_EVENT_RX_FRAME (1UL << 0) ///< Frame Received +#define CSI_ETH_MAC_EVENT_TX_FRAME (1UL << 1) ///< Frame Transmitted +#define CSI_ETH_MAC_EVENT_WAKEUP (1UL << 2) ///< Wake-up (on Magic Packet) +#define CSI_ETH_MAC_EVENT_TIMER_ALCSI (1UL << 3) ///< Timer Alarm +#define CSI_ETH_MAC_EVENT_LINK_CHANGE (1UL << 4) ///< Link state + +typedef void (*eth_event_cb_t)(eth_mac_handle_t handle, uint32_t event); ///< Pointer to \ref eth_event_cb_t : Signal Ethernet Event. + +typedef enum +{ + FRAME_FILTER_RULE_POSITIVE_MATCHING = 0, /*!< Specifies that a filter should match a given pattern */ + FRAME_FILTER_RULE_NEGATIVE_MATCHING = 1, /*!< Specifies that a filter should NOT match a given pattern */ +} frame_filter_rule_t; + +/** +\brief Ethernet MAC Capabilities +*/ +typedef struct eth_capabilities { + uint32_t checksum_offload_rx_ip4 : 1; ///< 1 = IPv4 header checksum verified on receive + uint32_t checksum_offload_rx_ip6 : 1; ///< 1 = IPv6 checksum verification supported on receive + uint32_t checksum_offload_rx_udp : 1; ///< 1 = UDP payload checksum verified on receive + uint32_t checksum_offload_rx_tcp : 1; ///< 1 = TCP payload checksum verified on receive + uint32_t checksum_offload_rx_icmp : 1; ///< 1 = ICMP payload checksum verified on receive + uint32_t checksum_offload_tx_ip4 : 1; ///< 1 = IPv4 header checksum generated on transmit + uint32_t checksum_offload_tx_ip6 : 1; ///< 1 = IPv6 checksum generation supported on transmit + uint32_t checksum_offload_tx_udp : 1; ///< 1 = UDP payload checksum generated on transmit + uint32_t checksum_offload_tx_tcp : 1; ///< 1 = TCP payload checksum generated on transmit + uint32_t checksum_offload_tx_icmp : 1; ///< 1 = ICMP payload checksum generated on transmit + uint32_t media_interface : 2; ///< Ethernet Media Interface type + uint32_t mac_address : 1; ///< 1 = driver provides initial valid MAC address + uint32_t event_rx_frame : 1; ///< 1 = callback event generated + uint32_t event_tx_frame : 1; ///< 1 = callback event generated + uint32_t event_wakeup : 1; ///< 1 = wakeup event generated + uint32_t precision_timer : 1; ///< 1 = Precision Timer supported + uint32_t reserved : 15; ///< Reserved (must be zero) +} eth_capabilities_t; + +#if 0 +/** +\brief Ethernet Frame filter +*/ +typedef struct eth_frame_filter { + struct { + uint32_t and_or : 1; ///< 1 = AND: Packets will be rejected unless all enabled filters accept the packet; 0 = OR: Packets will be accepted unless all enabled filters reject the packet + uint32_t unicast_en : 1; ///< 1 = Packets with a destination address matching the local MAC address will be accepted + uint32_t multicast_en : 1; ///< 1 = Packets which have the Least Significant bit set in the destination address will be accepted + uint32_t broadcast_en : 1; ///< 1 = Packets which have a destination address of FF-FF-FF-FF-FF-FF will be accepted + uint32_t crc_en : 1; ///< 1 = All packets with an invalid CRC will be discarded + uint32_t patten_match_en : 1; ///< 1 = Packets which meet the Pattern Match criteria will be accepted + uint32_t magic_packet_en : 1; ///< 1 = Magic Packets for the local MAC address will be accepted + uint32_t hash_table_en : 1; ///< 1 = Packets which meet the Hash Table criteria will be accepted + } sum; ///< summary + uint32_t patten_match; ///< patten match filter + uint32_t magic_packet; ///< patten match filter + uint32_t hash_table; ///< hash table filter +} eth_frame_filter_t; +#else +/** + * Structure describing a frame filter list item + */ +typedef struct +{ + uint32_t id; /*!< Unique identifier for a packet filter item */ + frame_filter_rule_t rule; /*!< Filter matches are either POSITIVE or NEGATIVE matching */ + uint16_t offset; /*!< Offset in bytes to start filtering (referenced to the start of the ethernet packet) */ + uint16_t mask_size; /*!< Size of the mask in bytes */ + uint8_t* mask; /*!< Pattern mask bytes to be ANDed with the pattern eg. "\xff00" (must be in network byte order) */ + uint8_t* pattern; /*!< Pattern bytes used to filter eg. "\x0800" (must be in network byte order) */ + bool enabled_status; /*!< When returned from mhd_get_packet_filters, indicates if the filter is enabled */ +} eth_frame_filter_t; + +struct eth_frame_filter_list +{ + struct eth_frame_filter_list* next; +}; +typedef struct eth_frame_filter_list eth_frame_filter_list_t; +#endif + +typedef struct { + eth_event_cb_t cb_event; + eth_capabilities_t capabilities; +}eth_mac_priv_t; + +/** + \brief Get driver version. + \param[in] handle ethernet handle + \return ethernet version including chip version and driver version +*/ +csi_drv_version_t csi_eth_mac_get_version(eth_mac_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle ethernet handle + \return ethernet capabilities +*/ +eth_capabilities_t csi_eth_mac_get_capabilities(eth_mac_handle_t handle); + +/** + \brief This function is used to initialize Ethernet device and related resource, an event callback is registered. It is called when the middleware component like TCPIP starts operation. + \param[in] cb callback to handle ethernet event + \return return ethernet handle if success + */ +eth_mac_handle_t csi_eth_mac_initialize(eth_event_cb_t cb); + +/** + \brief This function is used to de-initialize Ethernet device. It is called when the middleware component stops operation and releases the software resources used by the interface. + \param[in] handle ethernet handle + \return error code + */ +int32_t csi_eth_mac_uninitialize(eth_mac_handle_t handle); + +/** + \brief Control Ethernet MAC Device Power. + \param[in] handle ethernet handle + \param[in] state Power state + \return error code +*/ +int32_t csi_eth_mac_power_control(eth_mac_handle_t handle, eth_power_state_t state); + +/** + \brief Get Ethernet MAC Address. + \param[in] handle ethernet handle + \param[in] mac Pointer to address + \return error code +*/ +int32_t csi_eth_mac_get_macaddr(eth_mac_handle_t handle, eth_mac_addr_t *mac); + +/** + \brief Set Ethernet MAC Address. + \param[in] handle ethernet handle + \param[in] mac Pointer to address + \return error code +*/ +int32_t csi_eth_mac_set_macaddr(eth_mac_handle_t handle, const eth_mac_addr_t *mac); + +/** + \brief Configure Address Filter. + \param[in] handle ethernet handle + \param[in] addr Pointer to addresses + \param[in] num_addr Number of addresses to configure + \return error code +*/ +int32_t csi_eth_mac_set_addrfilter(eth_mac_handle_t handle, const eth_mac_addr_t *addr, uint32_t num_addr); + +/** + \brief Send Ethernet frame. + \param[in] handle ethernet handle + \param[in] frame Pointer to frame buffer with data to send + \param[in] len Frame buffer length in bytes + \param[in] flags Frame transmit flags (see CSI_ETH_MAC_TX_FRAME_...) + \return error code +*/ +int32_t csi_eth_mac_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len, uint32_t flags); + +/** + \brief Read data of received Ethernet frame. + \param[in] handle ethernet handle + \param[in] frame Pointer to frame buffer for data to read into + \param[in] len Frame buffer length in bytes + \return number of data bytes read or execution status + - value >= 0: number of data bytes read + - value < 0: error occurred, value is execution status as defined with execution_status +*/ +int32_t csi_eth_mac_read_frame(eth_mac_handle_t handle, uint8_t *frame, uint32_t len); + +/** + \brief Get size of received Ethernet frame. + \param[in] handle ethernet handle + \return number of bytes in received frame +*/ +int32_t csi_eth_mac_get_rx_framesize(eth_mac_handle_t handle); + +/** + \brief Get time of received Ethernet frame. + \param[in] handle ethernet handle + \param[in] time Pointer to time structure for data to read into + \return error code +*/ +int32_t csi_eth_mac_get_rx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time); + +/** + \brief Get time of transmitted Ethernet frame. + \param[in] handle ethernet handle + \param[in] time Pointer to time structure for data to read into + \return error code +*/ +int32_t csi_eth_mac_get_tx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time); + +/** + \brief Control Ethernet Interface. + \param[in] handle ethernet handle + \param[in] control Operation + \param[in] arg Argument of operation (optional) + \return error code +*/ +int32_t csi_eth_mac_control(eth_mac_handle_t handle, uint32_t control, uint32_t arg); + +/** + \brief Control Precision Timer. + \param[in] handle ethernet handle + \param[in] control Operation + \param[in] time Pointer to time structure + \return error code +*/ +int32_t csi_eth_mac_control_time(eth_mac_handle_t handle, uint32_t control, eth_mac_time_t *time); + +/** + \brief Read Ethernet PHY Register through Management Interface. + \param[in] handle ethernet handle + \param[in] phy_addr 5-bit device address + \param[in] reg_addr 5-bit register address + \param[out] data Pointer where the result is written to + \return error code +*/ +int32_t csi_eth_mac_phy_read(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data); + +/** + \brief Write Ethernet PHY Register through Management Interface. + \param[in] handle ethernet handle + \param[in] phy_addr 5-bit device address + \param[in] reg_addr 5-bit register address + \param[in] data 16-bit data to write + \return error code +*/ +int32_t csi_eth_mac_phy_write(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t data); + +/** + \brief Callback function that signals a Ethernet Event. + \param[in] handle ethernet handle + \param[in] event event notification mask + \return none +*/ +void csi_eth_mac_signal_event(eth_mac_handle_t handle, uint32_t event); + +/** + \brief Add Frame Filter Setting with Filter ID. + \param[in] handle ethernet handle + \param[in] filter Pointer to filter setting + \return error code +*/ +int32_t csi_eth_mac_add_framefilter(eth_mac_handle_t handle, const eth_frame_filter_t *filter); + +/** + \brief Remove Frame Filter Setting. + \param[in] handle ethernet handle + \param[in] filter_id Frame Filter ID + \return error code +*/ +int32_t csi_eth_mac_remove_framefilter(eth_mac_handle_t handle, uint32_t filter_id); + +/** + \brief Enable/Disable Specified Frame Filter ID. + \param[in] handle ethernet handle + \param[in] filter_id Frame Filter ID + \param[in] en Enable or disable + \return error code +*/ +int32_t csi_eth_mac_en_framefilter(eth_mac_handle_t handle, uint32_t filter_id, bool en); + +/** + \brief Get frame filter table list. + \param[in] handle ethernet handle + \param[in] list frame filter table list + \param[in] count_out the count of filter setting added + \param[in] max_count max filter setting can be supported + \return error code +*/ +int32_t csi_eth_mac_get_framefilter(eth_mac_handle_t handle, eth_frame_filter_list_t* list, uint32_t* count_out, uint32_t max_count); + + +#ifdef CONFIG_ETH_ENC28J60_USE_PBUF +/** + \brief Begin to Send Ethernet frame. + \param[in] handle ethernet handle + \param[in] len Frame buffer length in bytes + \return error code +*/ +int32_t csi_eth_mac_ex_send_frame_begin(eth_mac_handle_t handle, uint32_t len); + +/** + * send a packet data + * @param address the packet data length + * + * @return + * - sent data length + */ +int32_t csi_eth_mac_ex_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len, uint32_t flags); + +/** + \brief End Send Ethernet frame. + \param[in] handle ethernet handle + \return error code +*/ +int32_t csi_eth_mac_ex_send_frame_end(eth_mac_handle_t handle); + +/** + \brief Read data of received Ethernet frame. + \param[in] handle ethernet handle + \param[in] frame Pointer to frame buffer for data to read into + \param[in] len Frame buffer length in bytes + \return number of data bytes read or execution status + - value >= 0: number of data bytes read + - value < 0: error occurred, value is execution status as defined with execution_status +*/ +int32_t csi_eth_mac_ex_read_frame(eth_mac_handle_t handle, uint8_t *frame, uint32_t len); + +/** + \brief Begin to Read data of received Ethernet frame. + \param[in] handle ethernet handle + \param[in] len Frame buffer length in bytes + \return >0 data byte in hardware buffer + ==0 no data + < 0 error +*/ +int32_t csi_eth_mac_ex_read_frame_begin(eth_mac_handle_t handle); + +/** + \brief Begin to Read data of received Ethernet frame. + \param[in] handle ethernet handle + \return error code +*/ +int32_t csi_eth_mac_ex_read_frame_end(eth_mac_handle_t handle); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eth_phy.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eth_phy.h new file mode 100644 index 000000000..adf4aa017 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_eth_phy.h @@ -0,0 +1,124 @@ +/** + * Copyright (C) 2016 CSI Project. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CSI_ETH_PHY_H_ +#define _CSI_ETH_PHY_H_ + +#include "drv_eth.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *eth_phy_handle_t; + +#define CSI_ETH_PHY_API_VERSION CSI_ETH_VERSION_MAJOR_MINOR(2,1) /* API version */ + + +#define _CSI_Driver_ETH_PHY_(n) Driver_ETH_PHY##n +#define CSI_Driver_ETH_PHY_(n) _CSI_Driver_ETH_PHY_(n) + + +/****** Ethernet PHY Mode *****/ +#define CSI_ETH_PHY_SPEED_Pos 0 +#define CSI_ETH_PHY_SPEED_Msk (3UL << CSI_ETH_PHY_SPEED_Pos) +#define CSI_ETH_PHY_SPEED_10M (CSI_ETH_SPEED_10M << CSI_ETH_PHY_SPEED_Pos) ///< 10 Mbps link speed +#define CSI_ETH_PHY_SPEED_100M (CSI_ETH_SPEED_100M << CSI_ETH_PHY_SPEED_Pos) ///< 100 Mbps link speed +#define CSI_ETH_PHY_SPEED_1G (CSI_ETH_SPEED_1G << CSI_ETH_PHY_SPEED_Pos) ///< 1 Gpbs link speed +#define CSI_ETH_PHY_DUPLEX_Pos 2 +#define CSI_ETH_PHY_DUPLEX_Msk (1UL << CSI_ETH_PHY_DUPLEX_Pos) +#define CSI_ETH_PHY_DUPLEX_HALF (CSI_ETH_DUPLEX_HALF << CSI_ETH_PHY_DUPLEX_Pos) ///< Half duplex link +#define CSI_ETH_PHY_DUPLEX_FULL (CSI_ETH_DUPLEX_FULL << CSI_ETH_PHY_DUPLEX_Pos) ///< Full duplex link +#define CSI_ETH_PHY_AUTO_NEGOTIATE (1UL << 3) ///< Auto Negotiation mode +#define CSI_ETH_PHY_LOOPBACK (1UL << 4) ///< Loop-back test mode +#define CSI_ETH_PHY_ISOLATE (1UL << 5) ///< Isolate PHY from MII/RMII interface + +typedef int32_t (*csi_eth_phy_read_t) (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data); ///< Read Ethernet PHY Register. +typedef int32_t (*csi_eth_phy_write_t) (uint8_t phy_addr, uint8_t reg_addr, uint16_t data); ///< Write Ethernet PHY Register. + +typedef struct { + csi_eth_phy_read_t phy_read; + csi_eth_phy_write_t phy_write; + eth_link_info_t link_info; +}eth_phy_priv_t; + +// Function documentation +/** + \brief Get driver version. + \param[in] handle ethernet phy handle + \return driver version +*/ +csi_drv_version_t csi_eth_phy_get_version(eth_phy_handle_t handle); + +/** + \brief Initialize Ethernet PHY Device. + \param[in] fn_read + \param[in] fn_write + \return ethernet phy handle +*/ +eth_phy_handle_t csi_eth_phy_initialize(csi_eth_phy_read_t fn_read, csi_eth_phy_write_t fn_write); + +/** + \brief De-initialize Ethernet PHY Device. + \param[in] handle ethernet phy handle + \return error code +*/ +int32_t csi_eth_phy_uninitialize(eth_phy_handle_t handle); + +/** + \brief Control Ethernet PHY Device Power. + \param[in] handle ethernet phy handle + \param[in] state Power state + \return error code +*/ +int32_t csi_eth_phy_power_control(eth_phy_handle_t handle, eth_power_state_t state); + +/** + \brief Set Ethernet Media Interface. + \param[in] handle ethernet phy handle + \param[in] interface Media Interface type + \return error code +*/ +int32_t csi_eth_phy_set_interface(eth_phy_handle_t handle, uint32_t interface); + +/** + \brief Set Ethernet PHY Device Operation mode. + \param[in] handle ethernet phy handle + \param[in] mode Operation Mode + \return error code +*/ +int32_t csi_eth_phy_set_mode(eth_phy_handle_t handle, uint32_t mode); + +/** + \brief Get Ethernet PHY Device Link state. + \param[in] handle ethernet phy handle + \return current link status \ref eth_link_state_t +*/ +eth_link_state_t csi_eth_phy_get_linkstate(eth_phy_handle_t handle); + +/** + \brief Get Ethernet PHY Device Link information. + \param[in] handle ethernet phy handle + \return current link parameters \ref eth_link_info_t +*/ +eth_link_info_t csi_eth_phy_get_linkinfo(eth_phy_handle_t handle); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_flash.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_flash.h new file mode 100644 index 000000000..7afd288a9 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_flash.h @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_flash.c + * @brief header file for flash driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_FLASH_H_ +#define _CSI_FLASH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + +typedef struct { + uint32_t base; + void *priv; +} csi_flash_t; + +/** +\brief Flash Sector information +*/ +typedef struct { + uint32_t start; ///< Sector Start address + uint32_t end; ///< Sector End address (start+size-1) +} const flash_sector; + +/** +\brief Flash information +*/ +typedef struct { + flash_sector *sector_info; ///< Sector layout information (NULL=Uniform sectors) + uint32_t sector_count; ///< Number of sectors + uint32_t sector_size; ///< Uniform sector size in bytes (0=sector_info used) + uint32_t page_size; ///< Optimal programming page size in bytes + uint32_t program_unit; ///< Smallest programmable unit in bytes + uint8_t erased_value; ///< Contents of erased memory (usually 0xFF) +} flash_info_t; + +/** +\brief Flash Status +*/ +typedef struct { + uint32_t busy : 1; ///< Flash busy flag + uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation) +} flash_status_t; + +/****** FLASH Event *****/ +typedef enum { + FLASH_EVENT_READY = 0, ///< Flash Ready + FLASH_EVENT_ERROR , ///< Read/Program/Erase Error +} flash_event_e; + +typedef void (*flash_event_cb_t)(flash_event_e event); ///< Pointer to \ref flash_event_cb_t : FLASH Event call back. + +/** +\brief Flash Driver Capabilities. +*/ +typedef struct { + uint32_t event_ready : 1; ///< Signal Flash Ready event + uint32_t data_width : 2; ///< Data width: 0=8-bit, 1=16-bit, 2=32-bit + uint32_t erase_chip : 1; ///< Supports EraseChip operation +} flash_capabilities_t; + + + + +/** + \brief get flash instance count. + \return flash instance count +*/ +int32_t drv_flash_get_instance_count(void); + +/** + \brief get flash instance . + \param[in] idx must not exceed return value of drv_flash_get_instance_count() + \return pointer to flash instance +*/ +csi_flash_t *drv_flash_get_instance(int32_t idx); + +/** + \brief Get driver capabilities. + \param[in] instance flash instance to operate. + \return \ref flash_capabilities_t +*/ +flash_capabilities_t drv_flash_get_capabilities(const csi_flash_t *instance); + +/** + \brief Initialize FLASH Interface. 1. Initializes the resources needed for the FLASH interface 2.registers event callback function + \param[in] instance flash instance to operate. + \param[in] cb_event Pointer to \ref flash_event_cb_t + \return error code +*/ +int32_t drv_flash_initialize(const csi_flash_t *instance, flash_event_cb_t cb_event); + +/** + \brief De-initialize FLASH Interface. stops operation and releases the software resources used by the interface + \param[in] instance flash instance to operate. + \return error code +*/ +int32_t drv_flash_uninitialize(const csi_flash_t *instance); + +/** + \brief Get Flash information. + \param[in] instance flash instance to operate. + \return Pointer to Flash information \ref flash_info_t +*/ +flash_info_t *drv_flash_get_info(const csi_flash_t *instance); + +/** + \brief Read data from Flash. + \param[in] instance flash instance to operate. + \param[in] addr Data address. + \param[in] data Pointer to a buffer storing the data read from Flash. + \param[in] cnt Number of data items to read. + \return number of data items read or error code +*/ +int32_t drv_flash_read(const csi_flash_t *instance, uint32_t addr, void *data, uint32_t cnt); + +/** + \brief Program data to Flash. + \param[in] instance flash instance to operate. + \param[in] addr Data address. + \param[in] data Pointer to a buffer containing the data to be programmed to Flash.. + \param[in] cnt Number of data items to program. + \return number of data items programmed or error code +*/ +int32_t drv_flash_program(const csi_flash_t *instance, uint32_t addr, const void *data, uint32_t cnt); + +/** + \brief Erase Flash Sector. + \param[in] instance flash instance to operate. + \param[in] addr Sector address + \return error code +*/ +int32_t drv_flash_erase_sector(const csi_flash_t *instance, uint32_t addr); + +/** + \brief Erase complete Flash. + \param[in] instance flash instance to operate. + \return error code +*/ +int32_t drv_flash_erase_chip(const csi_flash_t *instance); + +/** + \brief Get FLASH status. + \param[in] instance flash instance to operate. + \return FLASH status \ref flash_status_t +*/ +flash_status_t drv_flash_get_status(const csi_flash_t *instance); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_FLASH_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_gpio.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_gpio.h new file mode 100644 index 000000000..5ec337b9f --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_gpio.h @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_gpio.h + * @brief header file for gpio driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_GPIO_H_ +#define _CSI_GPIO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/// definition for gpio port handle. +typedef void *gpio_port_handle_t; +/// definition for gpio pin handle. +typedef void *gpio_pin_handle_t; + +/****** GPIO specific error codes *****/ +typedef enum { + GPIO_ERROR_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not suphandleed + GPIO_ERROR_DIRECTION, ///< Specified direction not suphandleed + GPIO_ERROR_IRQ_MODE, ///< Specified irq mode not suphandleed +} drv_gpio_error_e; + +/*----- GPIO Control Codes: Mode -----*/ +typedef enum { + GPIO_MODE_PULLNONE = 1, ///< pull none for input + GPIO_MODE_PULLUP = 5, ///< pull up for input + GPIO_MODE_PULLDOWM = 3, ///< pull down for input + GPIO_MODE_OPEN_DRAIN = 2, ///< open drain mode for output + GPIO_MODE_PUSH_PULL = 4 ///< push-pull mode for output +} gpio_mode_e; + +/*----- GPIO Control Codes: Mode Parameters: Data Bits -----*/ +typedef enum { + GPIO_DIRECTION_INPUT = 0, ///< gpio as input + GPIO_DIRECTION_OUTPUT , ///< gpio as output +} gpio_direction_e; + +/*----- GPIO Control Codes: Mode Parameters: Parity -----*/ +typedef enum { + GPIO_IRQ_MODE_RISING_EDGE = 0, ///< interrupt mode for rising edge + GPIO_IRQ_MODE_FALLING_EDGE , ///< interrupt mode for falling edge + GPIO_IRQ_MODE_DOUBLE_EDGE , ///< interrupt mode for double edge + GPIO_IRQ_MODE_LOW_LEVEL , ///< interrupt mode for low level + GPIO_IRQ_MODE_HIGH_LEVEL , ///< interrupt mode for high level +} gpio_irq_mode_e; + +/** +\brief GPIO Driver Capabilities. +*/ +typedef struct { + uint32_t interrupt_mode : 1; ///< suphandles GPIO interrupt mode + uint32_t pull_mode : 1; +} gpio_capabilities_t; + + +typedef void (*gpio_event_cb_t)(void *arg); ///< gpio Event call back. + +/** + \brief Initialize GPIO module. 1. Initializes the resources needed for the GPIO handle 2.registers event callback function + 3.get gpio_port_handle + \param[in] port port_name. + \return gpio_port_handle +*/ +gpio_port_handle_t csi_gpio_port_initialize(port_name_t port); + +/** + \brief De-initialize GPIO handle. stops operation and releases the software resources used by the handle + \param[in] handle gpio port handle to operate. + \return error code +*/ +int32_t csi_gpio_port_uninitialize(gpio_port_handle_t handle); + +/** + \brief Get gpio capabilities.all pins have same capabilities in one handle + \param[in] handle handle instance to operate. + \return \ref gpio_capabilities_t +*/ +gpio_capabilities_t csi_gpio_get_io_capabilities(gpio_port_handle_t handle); + +/** + \brief config multiple pin within one handle + \param[in] handle gpio port handle to operate. + \param[in] mask the bitmask to identify which bits in the handle should be included (0 - ignore) + \param[in] mode \ref gpio_mode_e + \param[in] dir \ref gpio_direction_e + \return error code +*/ +int32_t csi_gpio_port_config(gpio_port_handle_t handle, + uint32_t mask, + gpio_mode_e mode, + gpio_direction_e dir); + +/** + \brief Write value to the handle(write value to multiple pins on one handle at the same time) + \param[in] handle gpio port handle to operate. + \param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore) + \param[in] value the value to be set + \return error code +*/ +int32_t csi_gpio_port_write(gpio_port_handle_t handle, uint32_t mask, uint32_t value); + +/** + \brief Read the current value on the handle(read value of multiple pins on one handle at the same time) + \param[in] handle gpio port handle to operate. + \param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore) + \param[out] value an integer with each bit corresponding to an associated handle pin setting + \return error code +*/ +int32_t csi_gpio_port_read(gpio_port_handle_t handle, uint32_t mask, uint32_t *value); + +/** + \brief Initialize GPIO handle. + \param[in] gpio_pin Pointer to the pin_t. + \param[in] cb_event Pointer to \ref gpio_event_cb_t + \param[in] arg Pointer to \ref arg used for the callback + \return gpio_pin_handle +*/ +gpio_pin_handle_t csi_gpio_pin_initialize(pin_t gpio_pin, gpio_event_cb_t cb_event, void *arg); + +/** + \brief De-initialize GPIO pin handle.stops operation and releases the software resources used by the handle. + \param[in] handle gpio pin handle to operate. + \return error code +*/ +int32_t csi_gpio_pin_uninitialize(gpio_pin_handle_t handle); + +/** + \brief config pin + \param[in] pin gpio pin handle to operate. + \param[in] mode \ref gpio_mode_e + \param[in] dir \ref gpio_direction_e + \return error code +*/ +int32_t csi_gpio_pin_config(gpio_pin_handle_t pin, + gpio_mode_e mode, + gpio_direction_e dir); + +/** + \brief Set one or zero to the selected GPIO pin. + \param[in] pin gpio pin handle to operate. + \param[in] value the value to be set + \return error code +*/ +int32_t csi_gpio_pin_write(gpio_pin_handle_t pin, bool value); + +/** + \brief Get the value of selected GPIO pin. + \param[in] pin gpio pin handle to operate. + \param[out] value buf to store the pin value + \return error code +*/ +int32_t csi_gpio_pin_read(gpio_pin_handle_t pin, bool *value); + +/** + \brief set GPIO interrupt mode. + \param[in] pin gpio pin handle to operate. + \param[in] mode the irq mode to be set + \param[in] enable the enable flag + \return error code +*/ +int32_t csi_gpio_pin_irq_set(gpio_pin_handle_t pin, gpio_irq_mode_e mode, bool enable); + + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_GPIO_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_iic.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_iic.h new file mode 100644 index 000000000..b4b492f84 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_iic.h @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_iic.h + * @brief header file for iic driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_IIC_H_ +#define _CSI_IIC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/// definition for iic handle. +typedef void *iic_handle_t; + +/*----- IIC Control Codes: Mode -----*/ +typedef enum { + IIC_MODE_MASTER, ///< IIC Master + IIC_MODE_SLAVE ///< IIC Slave +} iic_mode_e; + +/*----- IIC Control Codes: IIC Bus Speed -----*/ +typedef enum { + I2C_BUS_SPEED_STANDARD = 0, ///< Standard Speed (100kHz) + I2C_BUS_SPEED_FAST = 1, ///< Fast Speed (400kHz) + I2C_BUS_SPEED_FAST_PLUS = 2, ///< Fast+ Speed ( 1MHz) + I2C_BUS_SPEED_HIGH = 3 ///< High Speed (3.4MHz) +} iic_speed_e; + +/*----- IIC Control Codes: IIC Address Mode -----*/ +typedef enum { + I2C_ADDRESS_7BIT = 0, ///< 7-bit address mode + I2C_ADDRESS_10BIT = 1 ///< 10-bit address mode +} iic_address_mode_e; + +/** +\brief IIC Status +*/ +typedef struct { + uint32_t busy : 1; ///< Transmitter/Receiver busy flag + uint32_t mode : 1; ///< Mode: 0=Slave, 1=Master + uint32_t direction : 1; ///< Direction: 0=Transmitter, 1=Receiver + uint32_t general_call : 1; ///< General Call(address 0) indication (cleared on start of next Slave operation) + uint32_t arbitration_lost : 1; ///< Master lost arbitration(in case of multi-masters) (cleared on start of next Master operation) + uint32_t bus_error : 1; ///< Bus error detected (cleared on start of next Master/Slave operation) +} iic_status_t; + +/****** IIC Event *****/ +typedef enum { + I2C_EVENT_TRANSFER_DONE = 0, ///< Master/Slave Transmit/Receive finished + I2C_EVENT_TRANSFER_INCOMPLETE = 1, ///< Master/Slave Transmit/Receive incomplete transfer + I2C_EVENT_SLAVE_TRANSMIT = 2, ///< Slave Transmit operation requested + I2C_EVENT_SLAVE_RECEIVE = 3, ///< Slave Receive operation requested + I2C_EVENT_ADDRESS_NACK = 4, ///< Address not acknowledged from Slave + I2C_EVENT_GENERAL_CALL = 5, ///< General Call indication + I2C_EVENT_ARBITRATION_LOST = 6, ///< Master lost arbitration + I2C_EVENT_BUS_ERROR = 7, ///< Bus error detected (START/STOP at illegal position) + I2C_EVENT_BUS_CLEAR = 8 ///< Bus clear finished +} iic_event_e; + +typedef void (*iic_event_cb_t)(iic_event_e event, void *arg); ///< Pointer to \ref iic_event_cb_t : IIC Event call back. + +/** +\brief IIC Driver Capabilities. +*/ +typedef struct { + uint32_t address_10_bit : 1; ///< supports 10-bit addressing +} iic_capabilities_t; + +/** + \brief Initialize IIC Interface specified by pins. \n + 1. Initializes the resources needed for the IIC interface 2.registers event callback function + \param[in] scl scl pin of iic. + \param[in] sda sda pin of iic. + \param[in] cb_event Pointer to \ref iic_event_cb_t + \param[in] cb_arg argument for call back function + \return 0 for success, negative for error code +*/ +iic_handle_t csi_iic_initialize(pin_t scl, pin_t sda, iic_event_cb_t cb_event, void *cb_arg); + +/** + \brief De-initialize IIC Interface. stops operation and releases the software resources used by the interface + \param[in] handle iic handle to operate. + \return 0 for success, negative for error code +*/ +int32_t csi_iic_uninitialize(iic_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle iic handle to operate. + \return \ref iic_capabilities_t +*/ +iic_capabilities_t csi_iic_get_capabilities(iic_handle_t handle); + +/** + \brief config iic attributes. + \param[in] handle iic handle to operate. + \param[in] mode iic mode \ref iic_mode_e. if negative, then this attribute not changed. + \param[in] speed iic speed \ref iic_speed_e. if negative, then this attribute not changed. + \param[in] addr_mode iic address mode \ref iic_address_mode_e. if negative, then this attribute not changed. + \param[in] slave_addr iic address of slave. if negative, then this attribute not changed. + \return 0 for success, negative for error code +*/ +int32_t csi_iic_config(iic_handle_t handle, + iic_mode_e mode, + iic_speed_e speed, + iic_address_mode_e addr_mode, + int32_t slave_addr); + +/** + \brief Start transmitting data as I2C Master. + This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens. + \ref csi_iic_get_status can indicates transmission status. + \param[in] handle iic handle to operate. + \param[in] data data to send to I2C Slave + \param[in] num Number of data items to send + \param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated + \return 0 for success, negative for error code +*/ +int32_t csi_iic_master_send(iic_handle_t handle, const void *data, uint32_t num, bool xfer_pending); + +/** + \brief Start receiving data as I2C Master. + This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens. + \ref csi_iic_get_status can indicates transmission status. + \param[in] handle iic handle to operate. + \param[out] data Pointer to buffer for data to receive from IIC receiver + \param[in] num Number of data items to receive + \param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated + \return 0 for success, negative for error code +*/ +int32_t csi_iic_master_receive(iic_handle_t handle, void *data, uint32_t num, bool xfer_pending); + +/** + \brief Start transmitting data as I2C Slave. + This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens. + \ref csi_iic_get_status can indicates transmission status. + \param[in] handle iic handle to operate. + \param[in] data Pointer to buffer with data to transmit to I2C Master + \param[in] num Number of data items to send + \return 0 for success, negative for error code +*/ +int32_t csi_iic_slave_send(iic_handle_t handle, const void *data, uint32_t num); + +/** + \brief Start receiving data as I2C Slave. + This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens. + \ref csi_iic_get_status can indicates transmission status. + \param[in] handle iic handle to operate. + \param[out] data Pointer to buffer for data to receive from I2C Master + \param[in] num Number of data items to receive + \return 0 for success, negative for error code +*/ +int32_t csi_iic_slave_receive(iic_handle_t handle, const void *data, uint32_t num); + +/** + \brief abort transfer. + \param[in] handle iic handle to operate. + \return 0 for success, negative for error code +*/ +int32_t csi_iic_abort_transfer(iic_handle_t handle); + +/** + \brief Get IIC status. + \param[in] handle iic handle to operate. + \return IIC status \ref iic_status_t +*/ +iic_status_t csi_iic_get_status(iic_handle_t handle); + +/** + \brief control IIC power. + \param[in] handle iic handle to operate. + \param[in] state power state.\ref csi_power_stat_e. + \return error code +*/ +int32_t csi_iic_power_control(iic_handle_t handle, csi_power_stat_e state); + +/** + \brief config iic mode. + \param[in] handle iic handle to operate. + \param[in] mode \ref iic_mode_e.if negative, then this attribute not changed + \return error code +*/ +int32_t csi_iic_config_mode(iic_handle_t handle, iic_mode_e mode); + +/** + \brief config iic speed. + \param[in] handle iic handle to operate. + \param[in] speed \ref iic_speed_e.if negative, then this attribute not changed + \return error code +*/ +int32_t csi_iic_config_speed(iic_handle_t handle, iic_speed_e speed); + +/** + \brief config iic address mode. + \param[in] handle iic handle to operate. + \param[in] addr_mode \ref iic_address_mode_e.if negative, then this attribute not changed + \return error code +*/ +int32_t csi_iic_config_addr_mode(iic_handle_t handle, iic_address_mode_e addr_mode); + + +/** + \brief config iic slave address. + \param[in] handle iic handle to operate. + \param[in] slave_addr slave address.if negative, then this attribute not changed + \return error code +*/ +int32_t csi_iic_config_slave_addr(iic_handle_t handle, int32_t slave_addr); + +/** + \brief Get IIC transferred data count. + \param[in] handle iic handle to operate. + \return number of data bytes transferred +*/ +uint32_t csi_iic_get_data_count(iic_handle_t handle); + +/** + \brief Send START command. + \param[in] handle iic handle to operate. + \return error code +*/ +int32_t csi_iic_send_start(iic_handle_t handle); + +/** + \brief Send STOP command. + \param[in] handle iic handle to operate. + \return error code +*/ +int32_t csi_iic_send_stop(iic_handle_t handle); + +/** + \brief Reset I2C peripheral. + \param[in] handle iic handle to operate. + \return error code +*/ +int32_t csi_iic_reset(iic_handle_t handle); + +/** + \brief Read a single byte from the I2C bus. + \param[in] handle iic handle to operate. + \param[in] last Acknoledge,indicates if the byte is to be acknowledged (1 = acknowledge) + \return error code if negative, else the data is the lowest byte of return value +*/ +int32_t csi_iic_read_byte(iic_handle_t handle, int32_t last); + +/** + \brief Write one byte. + \param[in] handle iic handle to operate. + \return 0 if NAK was received, 1 if ACK was received, 2 for timeout. negative for error +*/ +int32_t csi_iic_write_byte(iic_handle_t handle, uint8_t data); + +/** + \brief Check to see if the I2C slave has been addressed. + \param[in] handle iic handle to operate. + \return 1 - read addressed, 2 - write to all slaves, + 3 - write addressed, 0 - the slave has not been addressed. + negative for error +*/ +int32_t csi_iic_slave_check_addressed(iic_handle_t handle); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_IIC_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_intc.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_intc.h new file mode 100644 index 000000000..10ee4cea1 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_intc.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_intc.h + * @brief header file for intc driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_INTC_H_ +#define _CSI_INTC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef enum int_trigger_mode_t +{ + INT_MODE_LOW_LEVEL, + INT_MODE_HIGH_LEVEL, + INT_MODE_RISING_EDGE, + INT_MODE_FALLING_EDGE, + INT_MODE_DOUBLE_EDGE, +} int_trigger_mode_t; + +/** + \brief initialize the INTC interrupt controller + \param [in] prio_bits the priority bits of INTC interrupt controller. + */ +void csi_intc_init(void); + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the INTC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +void csi_intc_enable_irq(int32_t IRQn); + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the INTC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +void csi_intc_disable_irq(int32_t IRQn); + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the INTC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +uint32_t csi_intc_get_pending_irq(int32_t IRQn); + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +void csi_intc_set_pending_irq(int32_t IRQn); + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +void csi_intc_clear_pending_irq(int32_t IRQn); + +/** + \brief Get Wake up Interrupt + \details Reads the wake up register in the INTC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt is not set as wake up interrupt. + \return 1 Interrupt is set as wake up interrupt. + */ +uint32_t csi_intc_get_wakeup_irq(int32_t IRQn); + +/** + \brief Set Wake up Interrupt + \details Sets the wake up bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +void csi_intc_set_wakeup_irq(int32_t IRQn); + +/** + \brief Clear Wake up Interrupt + \details Clears the wake up bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +void csi_intc_clear_wakeup_irq(int32_t IRQn); + +/** + \brief Get Active Interrupt + \details Reads the active register in the INTC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +uint32_t csi_intc_get_active(int32_t IRQn); + +/** + \brief Set Threshold register + \details set the threshold register in the INTC. + \param [in] VectThreshold specific vecter threshold. + \param [in] PrioThreshold specific priority threshold. + */ +void csi_intc_set_threshold(uint32_t VectThreshold, uint32_t PrioThreshold); + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +void csi_intc_set_prio(int32_t IRQn, uint32_t priority); + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +uint32_t csi_intc_get_prio(int32_t IRQn); + +/** + \brief funciton is acknowledge the IRQ. this interface is internally used by irq system + \param[in] irq irq number to operate + \return 0 on success; -1 on failure + */ +int csi_intc_ack_irq(int32_t IRQn); + +/** + \briefThis function is set the attributes of an IRQ. + \param[in] irq irq number to operate + \param[in] priority interrupt priority + \param[in] trigger_mode interrupt trigger_mode + \return 0 on success; -1 on failure +*/ +int csi_intc_set_attribute(int32_t IRQn, uint32_t priority,int_trigger_mode_t trigger_mode); + +#endif /* _CSI_INTC_H_ */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_pmu.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_pmu.h new file mode 100644 index 000000000..0d7774264 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_pmu.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_pmu.h + * @brief header file for pmu driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_PMU_H_ +#define _CSI_PMU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/// definition for pmu handle. +typedef void *pmu_handle_t; + +/****** PMU specific error codes *****/ +typedef enum { + EDRV_PMU_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported +} pmu_error_e; + +/*----- PMU Control Codes: Mode -----*/ +typedef enum { + PMU_MODE_RUN = 0, ///< Running mode + PMU_MODE_SLEEP , ///< Sleep mode + PMU_MODE_DORMANT , ///< Dormant mode + PMU_MODE_STDBY , ///< Standby mode + PMU_MODE_SHUTDOWN ///< Shutdown mode +} pmu_mode_e; + +/*----- PMU Control Codes: Wakeup type -----*/ +typedef enum { + PMU_WAKEUP_TYPE_PULSE = 0, ///< Pulse interrupt + PMU_WAKEUP_TYPE_LEVEL ///< Level interrupt +} pmu_wakeup_type_e; + +/*----- PMU Control Codes: Wakeup polarity -----*/ +typedef enum { + PMU_WAKEUP_POL_LOW = 0, ///< Low or negedge + PMU_WAKEUP_POL_HIGH ///< High or posedge +} pmu_wakeup_pol_e; + +/****** PMU Event *****/ +typedef enum { + PMU_EVENT_SLEEP_DONE = 0, ///< Send completed; however PMU may still transmit data + PMU_EVENT_BEFORE_SLEEP = 1 +} pmu_event_e; + +typedef void (*pmu_event_cb_t)(int32_t idx, pmu_event_e event, pmu_mode_e mode); ///< Pointer to \ref pmu_event_cb_t : PMU Event call back. + +typedef int32_t (*pmu_action_cb_t)(pmu_event_e event); + +/** + \brief Initialize PMU Interface. 1. Initializes the resources needed for the PMU interface 2.registers event callback function + \param[in] idx the id of the pmu + \param[in] cb_event Pointer to \ref pmu_event_cb_t + \return return pmu handle if success +*/ +pmu_handle_t drv_pmu_initialize(int32_t idx, pmu_event_cb_t cb_event); + +/** + \brief De-initialize PMU Interface. stops operation and releases the software resources used by the interface + \param[in] handle pmu handle to operate. + \return error code +*/ +int32_t drv_pmu_uninitialize(pmu_handle_t handle); + +int32_t drv_pmu_power_control(int32_t idx, csi_power_stat_e state); + +/** + \brief choose the pmu mode to enter + \param[in] handle pmu handle to operate. + \param[in] mode \ref pmu_mode_e + \return error code +*/ +int32_t drv_pmu_enter_sleep(pmu_handle_t handle, pmu_mode_e mode); + +/** + \brief choose the pmu mode to enter + \param[in] handle pmu handle to operate. + \param[in] callback Pointer to \ref pmu_action_cb_t + \return error code +*/ +int32_t drv_pmu_register_module(pmu_action_cb_t callback); + +/** + \brief exit the pmu mode + \param[in] handle pmu handle to operate. + \return error code +*/ +int32_t drv_pmu_exit_sleep(pmu_handle_t handle); + +/** + \brief Config the wakeup source. + \param[in] handle pmu handle to operate + \param[in] type \ref pmu_wakeup_type + \param[in] pol \ref pmu_wakeup_pol + \param[in] enable flag control the wakeup source is enable or not + \return error code +*/ +int32_t drv_pmu_config_wakeup_source(pmu_handle_t handle, uint32_t irq_num, pmu_wakeup_type_e type, pmu_wakeup_pol_e pol, uint8_t enable); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_PMU_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_pwm.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_pwm.h new file mode 100644 index 000000000..9d585429a --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_pwm.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_pwm.h + * @brief header file for pwm driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CSI_PWM_H_ +#define _CSI_PWM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + +/// definition for pwm handle. +typedef void *pwm_handle_t; + +/****** PWM specific error codes *****/ +typedef enum { + EDRV_PWM_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported +} drv_pwm_error_e; + + +/** + \brief Initialize PWM Interface. 1. Initializes the resources needed for the PWM interface 2.registers event callback function + \param[in] pwm_pin pin name of pwm + \return handle pwm handle to operate. +*/ +pwm_handle_t drv_pwm_initialize(pin_t pwm_pin); + +/** + \brief De-initialize PWM Interface. stops operation and releases the software resources used by the interface + \param[in] handle pwm handle to operate. + \return error code +*/ +int32_t drv_pwm_uninitialize(pwm_handle_t handle); + +/** + \brief config pwm mode. + \param[in] handle pwm handle to operate. + \param[in] sysclk configured system clock. + \param[in] period_us the PWM period in us + \param[in] duty the PMW duty. ( 0 - 10000 represents 0% - 100% ,other values are invalid) + \return error code +*/ +int32_t drv_pwm_config(pwm_handle_t handle, + uint32_t sysclk, + uint32_t period_us, + uint32_t duty); + +/** + \brief start generate pwm signal. + \param[in] handle pwm handle to operate. + \return error code +*/ +int32_t drv_pwm_start(pwm_handle_t handle); + +/** + \brief Stop generate pwm signal. + \param[in] handle pwm handle to operate. + \return error code +*/ +int32_t drv_pwm_stop(pwm_handle_t handle); + +/** + \brief Get PWM status. + \param[in] handle pwm handle to operate. + \return PWM status \ref pwm_status_t +pwm_status_t drv_pwm_get_status(pwm_handle_t handle); +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_PWM_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_rsa.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_rsa.h new file mode 100644 index 000000000..c7b41c108 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_rsa.h @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_rsa.h + * @brief header file for rsa driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CSI_RSA_H_ +#define _CSI_RSA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + +/// definition for rsa handle. +typedef void *rsa_handle_t; + +/****** RSA specific error codes *****/ +typedef enum { + RSA_ERROR_DATA_BITS , ///< Specified number of Data bits not supported + RSA_ERROR_ENDIAN ///< Specified endian not supported +} drv_rsa_error_e; + +/*----- RSA Control Codes: Mode Parameters: Data Bits -----*/ +typedef enum { + RSA_DATA_BITS_192 = 0, ///< 192 Data bits + RSA_DATA_BITS_256 , ///< 256 Data bits + RSA_DATA_BITS_512 , ///< 512 Data bits + RSA_DATA_BITS_1024 , ///< 1024 Data bits (default) + RSA_DATA_BITS_2048 ///< 2048 Data bits +} rsa_data_bits_e; + +/*----- RSA Control Codes: Mode Parameters: Endian -----*/ +typedef enum { + RSA_ENDIAN_MODE_LITTLE = 0, ///< RSA Little Endian Mode + RSA_ENDIAN_MODE_BIG ///< RSA Big Endian Mode +} rsa_endian_mode_e; + +typedef enum { + RSA_PADDING_MODE_PKCS1 = 1, ///< RSA PKCS1 Padding Mode + RSA_PADDING_MODE_NO , ///< RSA NO Padding Mode + RSA_PADDING_MODE_SSLV23 , ///< RSA SSLV23 Padding Mode + RSA_PADDING_MODE_PKCS1_OAEP , ///< RSA PKCS1 OAEP Padding Mode + RSA_PADDING_MODE_X931 , ///< RSA X931 Padding Mode + RSA_PADDING_MODE_PSS ///< RSA PSS Padding Mode +} rsa_padding_type_e; + +typedef enum { + RSA_HASH_TYPE_MD5 = 0, + RSA_HASH_TYPE_SHA1 , + RSA_HASH_TYPE_SHA224 , + RSA_HASH_TYPE_SHA256 , + RSA_HASH_TYPE_SHA384 , + RSA_HASH_TYPE_SHA512 +} rsa_hash_type_e; + +/*----- RSA Control Codes: Mode Parameters: Padding mode -----*/ +typedef struct { + rsa_padding_type_e padding_type; + rsa_hash_type_e hash_type; +} rsa_padding_t; + +/** +\brief RSA Status +*/ +typedef struct { + uint32_t busy : 1; ///< Calculate busy flag +} rsa_status_t; + +/****** RSA Event *****/ +typedef enum { + RSA_EVENT_ENCRYPT_COMPLETE = 0, ///< Encrypt completed + RSA_EVENT_DECRYPT_COMPLETE , ///< Decrypt completed + RSA_EVENT_SIGN_COMPLETE , ///< Sign completed + RSA_EVENT_VERIFY_COMPLETE , ///< Verify completed +} rsa_event_e; + +typedef void (*rsa_event_cb_t)(rsa_event_e event); ///< Pointer to \ref rsa_event_cb_t : RSA Event call back. + + +/** +\brief RSA Device Driver Capabilities. +*/ +typedef struct { + uint32_t bits_192 : 1; ///< supports 192bits modular length + uint32_t bits_256 : 1; ///< supports 256bits modular length + uint32_t bits_512 : 1; ///< supports 512bits modular length + uint32_t bits_1024 : 1; ///< supports 1024bits modular length + uint32_t bits_2048 : 1; ///< supports 2048bits modular length +} rsa_capabilities_t; + + +// Function documentation + +/** + \brief get rsa handle count. + \return rsa handle count +*/ +int32_t csi_rsa_get_instance_count(void); + +/** + \brief Initialize RSA Interface. 1. Initializes the resources needed for the RSA interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_rsa_get_instance_count() + \param[in] cb_event Pointer to \ref rsa_event_cb_t + \return pointer to rsa handle +*/ +rsa_handle_t csi_rsa_initialize(int32_t idx, rsa_event_cb_t cb_event); + +/** + \brief De-initialize RSA Interface. stops operation and releases the software resources used by the interface + \param[in] handle rsa handle to operate. + \return error code +*/ +int32_t csi_rsa_uninitialize(rsa_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle rsa handle to operate. + \return \ref rsa_capabilities_t +*/ +rsa_capabilities_t csi_rsa_get_capabilities(rsa_handle_t handle); + +/** + \brief config rsa mode. + \param[in] handle rsa handle to operate. + \param[in] data_bits \ref rsa_data_bits_e + \param[in] endian \ref rsa_endian_mode_e + \return error code +*/ +int32_t csi_rsa_config(rsa_handle_t handle, + rsa_data_bits_e data_bits, + rsa_endian_mode_e endian, + void *arg + ); + +/** + \brief encrypt + \param[in] handle rsa handle to operate. + \param[in] n Pointer to the public modulus + \param[in] e Pointer to the public exponent + \param[in] src Pointer to the source data. + \param[in] src_size the source data len + \param[out] out Pointer to the result buffer + \param[out] out_size the result size + \param[in] padding \ref rsa_padding_t + \return error code +*/ +int32_t csi_rsa_encrypt(rsa_handle_t handle, void *n, void *e, void *src, int32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding); + + +/** + \brief decrypt + \param[in] handle rsa handle to operate. + \param[in] n Pointer to the public modulus + \param[in] d Pointer to the privte exponent + \param[in] src Pointer to the source data. + \param[in] src_size the source data len + \param[out] out Pointer to the result buffer + \param[out] out_size the result size + \param[in] padding \ref rsa_padding_t + \return error code +*/ +int32_t csi_rsa_decrypt(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding); + +/** + \brief rsa sign + \param[in] handle rsa handle to operate. + \param[in] n Pointer to the public modulus + \param[in] d Pointer to the privte exponent + \param[in] src Pointer to the source data. + \param[in] src_size the source data len + \param[out] signature Pointer to the signature + \param[out] sig_size the signature size + \param[in] padding \ref rsa_padding_t + \return error code +*/ +int32_t csi_rsa_sign(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *signature, void *sig_size, rsa_padding_t padding); + +/** + \brief rsa verify + \param[in] handle rsa handle to operate. + \param[in] n Pointer to the public modulus + \param[in] e Pointer to the public exponent + \param[in] src Pointer to the source data. + \param[in] src_size the source data len + \param[in] signature Pointer to the signature + \param[in] sig_size the signature size + \param[out] result Pointer to the result + \param[in] padding \ref rsa_padding_t + \return error code +*/ +int32_t csi_rsa_verify(rsa_handle_t handle, void *n, void *e, void *src, uint32_t src_size, void *signature, uint32_t sig_size, void *result, rsa_padding_t padding); +/** + \brief Get RSA status. + \param[in] handle rsa handle to operate. + \return RSA status \ref rsa_status_t +*/ +rsa_status_t csi_rsa_get_status(rsa_handle_t handle); + + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_RSA_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_rtc.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_rtc.h new file mode 100644 index 000000000..182b3df84 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_rtc.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_rtc.h + * @brief header file for rtc driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_RTC_H_ +#define _CSI_RTC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/// definition for rtc handle. +typedef void *rtc_handle_t; + +/****** rtc specific error codes *****/ +typedef enum { + EDRV_RTC_TIME = (EDRV_SPECIFIC + 1), ///< timer data not supported +} drv_rtc_error_e; + +/** +\brief RTC Status +*/ +typedef struct { + uint32_t active : 1; ///< rtc is running or not +} rtc_status_t; + +/****** RTC Event *****/ +typedef enum { + RTC_EVENT_TIMER_INTRERRUPT = 0 ///< generate interrupt +} rtc_event_e; + +typedef void (*rtc_event_cb_t)(rtc_event_e event); ///< Pointer to \ref rtc_event_cb_t : RTC Event call back. + +/** +\brief RTC Device Driver Capabilities. +*/ +typedef struct { + uint32_t interrupt_mode : 1; ///< supports Interrupt mode + uint32_t wrap_mode : 1; ///< supports wrap mode +} rtc_capabilities_t; + +/** + \brief get rtc instance count. + \return rtc instance count +*/ +int32_t csi_rtc_get_instance_count(void); + +/** + \brief Initialize RTC Interface. 1. Initializes the resources needed for the RTC interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_rtc_get_instance_count() + \param[in] cb_event Pointer to \ref rtc_event_cb_t + \return pointer to rtc instance +*/ +rtc_handle_t csi_rtc_initialize(int32_t idx, rtc_event_cb_t cb_event); + +/** + \brief De-initialize RTC Interface. stops operation and releases the software resources used by the interface + \param[in] handle rtc handle to operate. + \return error code +*/ +int32_t csi_rtc_uninitialize(rtc_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle rtc handle to operate. + \return \ref rtc_capabilities_t +*/ +rtc_capabilities_t csi_rtc_get_capabilities(rtc_handle_t handle); + +/** + \brief Set RTC timer. + \param[in] handle rtc handle to operate. + \param[in] rtctime pointer to rtc time + \return error code +*/ +int32_t csi_rtc_set_time(rtc_handle_t handle, const struct tm *rtctime); + +/** + \brief Get RTC timer. + \param[in] handle rtc handle to operate. + \param[in] rtctime pointer to rtc time + \return error code +*/ +int32_t csi_rtc_get_time(rtc_handle_t handle, struct tm *rtctime); + + + +/** + \brief Start RTC timer. + \param[in] handle rtc handle to operate. + \return error code +*/ +int32_t csi_rtc_start(rtc_handle_t handle); + +/** + \brief Stop RTC timer. + \param[in] handle rtc handle to operate. + \return error code +*/ +int32_t csi_rtc_stop(rtc_handle_t handle); + +/** + \brief config rtc mode. + \param[in] handle rtc handle to operate. + \return error code +*/ +//int32_t drv_rtc_config (rtc_handle_t handle/*,rtc_mode_e mode*/); + +/** + \brief Get RTC status. + \param[in] handle rtc handle to operate. + \return RTC status \ref rtc_status_t +*/ +rtc_status_t csi_rtc_get_status(rtc_handle_t handle); + +/** + \brief config RTC timer. + \param[in] handle rtc handle to operate. + \param[in] rtctime time to wake up + \return error code +*/ +int32_t csi_rtc_timer_config(rtc_handle_t handle, const struct tm *rtctime); + +/** + \brief disable or enable RTC timer. + \param[in] handle rtc handle to operate. + \param[in] en set 1 enable for rtc timer + \return error code +*/ +int32_t csi_rtc_timer_enable(rtc_handle_t handle, uint8_t en); + + + + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_RTC_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_sha.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_sha.h new file mode 100644 index 000000000..238d1548f --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_sha.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_sha.h + * @brief header file for sha driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CSI_SHA_H_ +#define _CSI_SHA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + + +/// definition for sha handle. +typedef void *sha_handle_t; + +/****** SHA specific error codes *****/ +typedef enum { + SHA_ERROR_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported + SHA_ERROR_ENDIAN ///< Specified endian not supported +} drv_sha_error_e; + +/*----- SHA Control Codes: Mode -----*/ +typedef enum { + SHA_MODE_1 = 1, ///< SHA_1 mode + SHA_MODE_256 , ///< SHA_256 mode + SHA_MODE_224 , ///< SHA_224 mode + SHA_MODE_512 , ///< SHA_512 mode + SHA_MODE_384 , ///< SHA_384 mode + SHA_MODE_512_256 , ///< SHA_512_256 mode + SHA_MODE_512_224 ///< SHA_512_224 mode +} sha_mode_e; + +/*----- SHA Control Codes: Mode Parameters: Endian -----*/ +typedef enum { + SHA_ENDIAN_MODE_BIG = 0, ///< Big Endian Mode + SHA_ENDIAN_MODE_LITTLE , ///< Little Endian Mode +} sha_endian_mode_e; + +/** +\brief SHA Status +*/ +typedef struct { + uint32_t busy : 1; ///< calculate busy flag +} sha_status_t; + +/****** SHA Event *****/ +typedef enum { + SHA_EVENT_COMPLETE = 0 ///< calculate completed +} sha_event_e; + +typedef void (*sha_event_cb_t)(sha_event_e event); ///< Pointer to \ref sha_event_cb_t : SHA Event call back. + + +/** +\brief SHA Device Driver Capabilities. +*/ +typedef struct { + uint32_t sha1 : 1; ///< supports sha1 mode + uint32_t sha224 : 1; ///< supports sha224 mode + uint32_t sha256 : 1; ///< supports sha256 mode + uint32_t sha384 : 1; ///< supports sha384 mode + uint32_t sha512 : 1; ///< supports sha512 mode + uint32_t sha512_224 : 1; ///< supports sha512_224 mode + uint32_t sha512_256 : 1; ///< supports sha512_256 mode + uint32_t endianmode : 1; ///< supports endian mode control + uint32_t interruptmode : 1; ///< supports interrupt mode +} sha_capabilities_t; + + +// Function documentation + +/** + \brief get sha handle count. + \return sha handle count +*/ +int32_t csi_sha_get_instance_count(void); + +/** + \brief Initialize SHA Interface. 1. Initializes the resources needed for the SHA interface 2.registers event callback function + \param[in] handle Pointer to the buffer store the sha context + \param[in] cb_event Pointer to \ref sha_event_cb_t + \return return sha handle if success +*/ +sha_handle_t csi_sha_initialize(sha_handle_t handle, sha_event_cb_t cb_event); + +/** + \brief De-initialize SHA Interface. stops operation and releases the software resources used by the interface + \param[in] handle sha handle to operate. + \return error code +*/ +int32_t csi_sha_uninitialize(sha_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle sha handle to operate. + \return \ref sha_capabilities_t +*/ +sha_capabilities_t csi_sha_get_capabilities(sha_handle_t handle); + +/** + \brief config sha mode. + \param[in] handle sha handle to operate. + \param[in] mode \ref sha_mode_e + \param[in] endian \ref sha_endian_mode_e + \return error code +*/ +int32_t csi_sha_config(sha_handle_t handle, + sha_mode_e mode, + sha_endian_mode_e endian + ); + +/** + \brief start the engine + \param[in] handle sha handle to operate. + \param[in] context Pointer to the sha context. + \return error code +*/ +int32_t csi_sha_starts(sha_handle_t handle, void *context); + +/** + \brief updata the engine + \param[in] handle sha handle to operate. + \param[in] context Pointer to the sha context. + \param[in] input Pointer to the Source data + \param[in] len the data len + \return error code +*/ +int32_t csi_sha_update(sha_handle_t handle, void *context, const void *input, uint32_t len); + +/** + \brief finish the engine + \param[in] handle sha handle to operate. + \param[in] context Pointer to the sha context. + \param[out] output Pointer to the dest data + \return error code +*/ +int32_t csi_sha_finish(sha_handle_t handle, void *context, void *output); + +/** + \brief Get SHA status. + \param[in] handle sha handle to operate. + \return SHA status \ref sha_status_t +*/ +sha_status_t csi_sha_get_status(sha_handle_t handle); + + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_SHA_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_spi.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_spi.h new file mode 100644 index 000000000..3e5afe570 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_spi.h @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_spi.h + * @brief header file for spi driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_SPI_H_ +#define _CSI_SPI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#ifdef CONFIG_SPI_DMA +#include +#endif + +/// definition for spi handle. +typedef void *spi_handle_t; + +/****** SPI specific error codes *****/ +typedef enum { + EDRV_SPI_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported + EDRV_SPI_FRAME_FORMAT, ///< Specified Frame Format not supported + EDRV_SPI_DATA_BITS, ///< Specified number of Data bits not supported + EDRV_SPI_BIT_ORDER, ///< Specified Bit order not supported + EDRV_SPI_SS_MODE ///< Specified Slave Select Mode not supported +} drv_spi_err_e; + +/*----- SPI Control Codes: Mode -----*/ +typedef enum { + SPI_MODE_INACTIVE = 0, ///< SPI Inactive + SPI_MODE_MASTER, ///< SPI Master (Output on MOSI, Input on MISO); arg = Bus Speed in bps + SPI_MODE_SLAVE, ///< SPI Slave (Output on MISO, Input on MOSI) + SPI_MODE_MASTER_SIMPLEX, ///< SPI Master (Output/Input on MOSI); arg = Bus Speed in bps + SPI_MODE_SLAVE_SIMPLEX ///< SPI Slave (Output/Input on MISO) +} spi_mode_e; + +/*----- SPI Control Codes: Mode Parameters: Frame Format -----*/ +typedef enum { + SPI_FORMAT_CPOL0_CPHA0 = 0, ///< Clock Polarity 0, Clock Phase 0 (default) + SPI_FORMAT_CPOL0_CPHA1, ///< Clock Polarity 0, Clock Phase 1 + SPI_FORMAT_CPOL1_CPHA0, ///< Clock Polarity 1, Clock Phase 0 + SPI_FORMAT_CPOL1_CPHA1, ///< Clock Polarity 1, Clock Phase 1 +} spi_format_e; + +/*----- SPI Control Codes: Mode Parameters: Bit Order -----*/ +typedef enum { + SPI_ORDER_MSB2LSB = 0, ///< SPI Bit order from MSB to LSB (default) + SPI_ORDER_LSB2MSB ///< SPI Bit order from LSB to MSB +} spi_bit_order_e; + +/*----- SPI Control Codes: Mode Parameters: Data Width in bits -----*/ +#define SPI_DATAWIDTH_MAX 32 /* 1 ~ 32 bit*/ + +/*----- SPI Control Codes: Mode Parameters: Slave Select Mode -----*/ +typedef enum { + /*options for SPI_MODE_MASTER/SPI_MODE_MASTER_SIMPLEX */ + SPI_SS_MASTER_UNUSED = 0, ///< SPI Slave Select when Master: Not used (default).SS line is not controlled by master, For example,SS line connected to a fixed low level + SPI_SS_MASTER_SW, ///< SPI Slave Select when Master: Software controlled. SS line is configured by software + SPI_SS_MASTER_HW_OUTPUT, ///< SPI Slave Select when Master: Hardware controlled Output.SS line is activated or deactivated automatically by hardware + SPI_SS_MASTER_HW_INPUT, ///< SPI Slave Select when Master: Hardware monitored Input.Used in multi-master configuration where a master does not drive the Slave Select when driving the bus, but rather monitors it + /*options for SPI_MODE_SLAVE/SPI_MODE_SLAVE_SIMPLEX */ + SPI_SS_SLAVE_HW, ///< SPI Slave Select when Slave: Hardware monitored (default).Hardware monitors the Slave Select line and accepts transfers only when the line is active + SPI_SS_SLAVE_SW ///< SPI Slave Select when Slave: Software controlled.Used only when the Slave Select line is not used. Software controls if the slave is responding or not(enables or disables transfers) +} spi_ss_mode_e; + +/****** SPI Slave Select Signal definitions *****/ +typedef enum { + SPI_SS_INACTIVE = 0, ///< SPI Slave Select Signal/line Inactive + SPI_SS_ACTIVE ///< SPI Slave Select Signal/line Active +} spi_ss_stat_e; + +/** +\brief SPI Status +*/ +typedef struct { + uint32_t busy : 1; ///< Transmitter/Receiver busy flag + uint32_t data_lost : 1; ///< Data lost: Receive overflow / Transmit underflow (cleared on start of transfer operation) + uint32_t mode_fault : 1; ///< Mode fault detected; optional (cleared on start of transfer operation) +} spi_status_t; + +/****** SPI Event *****/ +typedef enum { + SPI_EVENT_TRANSFER_COMPLETE = 0, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation + SPI_EVENT_TX_COMPLETE, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation + SPI_EVENT_RX_COMPLETE, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation + SPI_EVENT_DATA_LOST, ///< Data lost: Receive overflow / Transmit underflow. Occurs in slave mode when data is requested/sent by master but send/receive/transfer operation has not been started and indicates that data is lost. Occurs also in master mode when driver cannot transfer data fast enough. + SPI_EVENT_MODE_FAULT ///< Master Mode Fault (SS deactivated when Master).Occurs in master mode when Slave Select is deactivated and indicates Master Mode Fault. The driver is ready for the next transfer operation. +} spi_event_e; + +typedef void (*spi_event_cb_t)(spi_event_e event, void *arg); ///< Pointer to \ref spi_event_cb_t : SPI Event call back. + +/** +\brief SPI Driver Capabilities. +*/ +typedef struct { + uint32_t simplex : 1; ///< supports Simplex Mode (Master and Slave) + uint32_t ti_ssi : 1; ///< supports TI Synchronous Serial Interface + uint32_t microwire : 1; ///< supports Microwire Interface + uint32_t event_mode_fault : 1; ///< Signal Mode Fault event: \ref spi_event_e +} spi_capabilities_t; + +/** + \brief Initialize SPI Interface. 1. Initializes the resources needed for the SPI interface 2.registers event callback function + \param[in] mosi spi pin of mosi + \param[in] miso spi pin of miso + \param[in] sclk spi pin of sclk + \param[in] ssel spi pin of ssel + \param[in] cb_event event call back function \ref spi_event_cb_t + \param[in] cb_arg argument for call back function + \return return spi handle if success +*/ +spi_handle_t csi_spi_initialize(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel, spi_event_cb_t cb_event, void *cb_arg); + +/** + \brief De-initialize SPI Interface. stops operation and releases the software resources used by the interface + \param[in] handle spi handle to operate. + \return error code +*/ +int32_t csi_spi_uninitialize(spi_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle spi handle to operate. + \return \ref spi_capabilities_t +*/ +spi_capabilities_t csi_spi_get_capabilities(spi_handle_t handle); + +/** + \brief config spi mode. + \param[in] handle spi handle to operate. + \param[in] sysclk sysclk for spi module. + \param[in] baud spi baud rate. if negative, then this attribute not changed + \param[in] mode \ref spi_mode_e . if negative, then this attribute not changed + \param[in] format \ref spi_format_e . if negative, then this attribute not changed + \param[in] order \ref spi_bit_order_e . if negative, then this attribute not changed + \param[in] ss_mode \ref spi_ss_mode_e . if negative, then this attribute not changed + \param[in] bit_width spi data bitwidth: (1 ~ SPI_DATAWIDTH_MAX) . if negative, then this attribute not changed + \return error code +*/ +int32_t csi_spi_config(spi_handle_t handle, + int32_t sysclk, + int32_t baud, + spi_mode_e mode, + spi_format_e format, + spi_bit_order_e order, + spi_ss_mode_e ss_mode, + int32_t bit_width); + +/** + \brief config spi default tx value. + \param[in] handle spi handle to operate. + \param[in] value default tx value + \return error code +*/ +int32_t csi_spi_set_default_tx_value(spi_handle_t handle, uint32_t value); + +/** +\brief sending data to SPI transmitter,(received data is ignored). + if non-blocking mode, this function only start the sending, + \ref spi_event_e is signaled when operation completes or error happens. + \ref csi_spi_get_status can indicates operation status. + if blocking mode, this function return after operation completes or error happens. + \param[in] handle spi handle to operate. + \param[in] data Pointer to buffer with data to send to SPI transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits, + \param[in] num Number of data items to send. + \param[in] block_mode blocking and non_blocking to selcect + \return error code +*/ +int32_t csi_spi_send(spi_handle_t handle, const void *data, uint32_t num, uint8_t block_mode); + +/** + \brief receiving data from SPI receiver.transmits the default value as specified by csi_spi_set_default_tx_value + if non-blocking mode, this function only start the receiving, + \ref spi_event_e is signaled when operation completes or error happens. + \ref csi_spi_get_status can indicates operation status. + if blocking mode, this function return after operation completes or error happens. + \param[in] handle spi handle to operate. + \param[out] data Pointer to buffer for data to receive from SPI receiver + \param[in] num Number of data items to receive + \param[in] block_mode blocking and non_blocking to selcect + \return error code +*/ +int32_t csi_spi_receive(spi_handle_t handle, void *data, uint32_t num, uint8_t block_mode); + +/** + \brief sending/receiving data to/from SPI transmitter/receiver. + if non-blocking mode, this function only start the transfer, + \ref spi_event_e is signaled when operation completes or error happens. + \ref csi_spi_get_status can indicates operation status. + if blocking mode, this function return after operation completes or error happens. + \param[in] handle spi handle to operate. + \param[in] data_out Pointer to buffer with data to send to SPI transmitter + \param[out] data_in Pointer to buffer for data to receive from SPI receiver + \param[in] num_out Number of data items to send + \param[in] num_in Number of data items to receive + \param[in] block_mode blocking and non_blocking to selcect + \return error code +*/ +int32_t csi_spi_transfer(spi_handle_t handle, const void *data_out, void *data_in, uint32_t num_out, uint32_t num_in, uint8_t block_mode); + +/** + \brief abort spi transfer. + \param[in] handle spi handle to operate. + \return error code +*/ +int32_t csi_spi_abort_transfer(spi_handle_t handle); + +/** + \brief Get SPI status. + \param[in] handle spi handle to operate. + \return SPI status \ref spi_status_t +*/ +spi_status_t csi_spi_get_status(spi_handle_t handle); + +/** + \brief config the SPI mode. + \param[in] handle spi handle + \param[in] mode spi mode. \ref spi_mode_e + \return error code +*/ +int32_t csi_spi_config_mode(spi_handle_t handle, spi_mode_e mode); + +/** + \brief Set the SPI clock divider. + \param[in] handle spi handle + \param[in] baud spi baud rate + \param[in] apbfreq sysclk for spi module. + \return error code +*/ +int32_t csi_spi_config_baudrate(spi_handle_t handle, int32_t baud, int32_t apbfreq); + +/** + \brief config the SPI mode. + \param[in] handle spi handle + \param[in] order spi bit order.\ref spi_bit_order_e + \return error code +*/ +int32_t csi_spi_config_bit_order(spi_handle_t handle, spi_bit_order_e order); + +/** + \brief Set the SPI datawidth. + \param[in] handle spi handle + \param[in] datawidth date frame size in bits + \return error code +*/ +int32_t csi_spi_config_datawidth(spi_handle_t handle, int32_t datawidth); + +/** + \brief config the SPI format. + \param[in] handle spi handle + \param[in] format spi format. \ref spi_format_e + \return error code +*/ +int32_t csi_spi_config_format(spi_handle_t handle, spi_format_e format); + +/** + \brief config the SPI slave select mode. + \param[in] handle spi handle + \param[in] ss_mode spi slave select mode. \ref spi_ss_mode_e + \return error code +*/ +int32_t csi_spi_config_ss_mode(spi_handle_t handle, spi_ss_mode_e ss_mode); + +/** + \brief Get spi transferred data count. + \param[in] handle spi handle to operate. + \return number of data bytes transferred +*/ +uint32_t csi_spi_get_data_count(spi_handle_t handle); + +/** + \brief control spi power. + \param[in] handle spi handle to operate. + \param[in] state power state.\ref csi_power_stat_e. + \return error code +*/ +int32_t csi_spi_power_control(spi_handle_t handle, csi_power_stat_e state); + +/** + \brief Check if a value is available to read. + \param[in] handle spi handle to operate. + \return non-zero if a value is available +*/ +int32_t csi_spi_slave_readable(spi_handle_t handle); + +/** + \brief Control the Slave Select signal (SS). + \param[in] handle spi handle to operate. + \param[in] stat SS state. \ref spi_ss_stat_e. + \return error code +*/ +int32_t csi_spi_ss_control(spi_handle_t handle, spi_ss_stat_e stat); + + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_SPI_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_tee.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_tee.h new file mode 100644 index 000000000..61d61b1d2 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_tee.h @@ -0,0 +1,640 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * @file drv_tee.h + * @brief Header File for TEE + * @version V1.0 + * @date 12 Sep 2017 + ******************************************************************************/ +#ifndef _CSI_AES_H_ +#define _CSI_AES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/****** TEE AES mode *****/ +typedef enum { + TEE_AES_MODE_ECB = 0, ///< TEE AES ECB mode + TEE_AES_MODE_CBC = 1, ///< TEE AES CBC mode + TEE_AES_MODE_MAX, ///< invaild mode +} +tee_aes_mode_e; + +/** + \brief TEE AES encrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to plaintext buffer + \param[in] in_len Plaintext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to ciphertext buffer + \param[in] mode \ref tee_aes_mode_e + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_aes_encrypt(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t iv[16], + uint8_t *out, + tee_aes_mode_e mode); + +/** + \brief TEE AES decrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to plaintext buffer + \param[in] mode \ref tee_aes_mode_e + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_aes_decrypt(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t iv[16], + uint8_t *out, + uint32_t mode); + +/** + \brief TEE AES ECB encrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to plaintext buffer + \param[in] in_len Plaintext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to ciphertext buffer + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_aes_encrypt_ecb(in, in_len, key, key_len, out) \ + csi_tee_aes_encrypt(in, in_len, key, key_len, NULL, out, TEE_AES_MODE_ECB) + +/** + \brief TEE AES ECB decrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to plaintext buffer + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_aes_decrypt_ecb(in, in_len, key, key_len, out) \ + csi_tee_aes_decrypt(in, in_len, key, key_len, NULL, out, TEE_AES_MODE_ECB) + +/** + \brief TEE AES CBC encrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to plaintext buffer + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_aes_encrypt_cbc(in, in_len, key, key_len, iv, out) \ + csi_tee_aes_encrypt(in, in_len, key, key_len, iv, out, TEE_AES_MODE_CBC) + +/** + \brief TEE AES CBC decrypt + \note Length should be a multiple of the block size (16 bytes) + After calling this function, the content of iv is updated. + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to secret key + \param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256 + \param[out] out Pointer to plaintext buffer + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_aes_decrypt_cbc(in, in_len, key, key_len, iv, out) \ + csi_tee_aes_decrypt(in, in_len, key, key_len, iv, out, TEE_AES_MODE_CBC) + +/** + \brief TEE BASE64 encode/decode + \param[in] in Pointer to input data buffer + \param[in] in_len input data buffer length + \param[out] out Pointer to output data buffer + \param[out] out_len output data buffer length + \param[in] is_encode 1 encode 0 decode + \param[in] wsafe base64 websafe feature,set 1, replace "+/" with "-_" + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_base64(const uint8_t *in, uint32_t in_len, + uint8_t *out, uint32_t *out_len, + uint32_t is_encode, + uint32_t wsafe); + +/** + \brief TEE BASE64 encode + \param[in] in Pointer to input data buffer + \param[in] in_len input data buffer length + \param[out] out Pointer to output data buffer + \param[out] out_len output data buffer length + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_base64_encode(in,in_len,out,out_len) \ + csi_tee_base64(in,in_len,out,out_len,1,0) + +/** + \brief TEE BASE64 decode + \param[in] in Pointer to input data buffer + \param[in] in_len input data buffer length + \param[out] out Pointer to output data buffer + \param[out] out_len output data buffer length + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_base64_decode(in,in_len,out,out_len) \ + csi_tee_base64(in,in_len,out,out_len,0,0) + +/** + \brief TEE BASE64 web safe encode + \param[in] in Pointer to input data buffer + \param[in] in_len input data buffer length + \param[out] out Pointer to output data buffer + \param[out] out_len output data buffer length + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_base64_websafe_encode(in,in_len,out,out_len) \ + csi_tee_base64(in,in_len,out,out_len,1,1) + +/** + \brief TEE BASE64 web safe decode + \param[in] in Pointer to input data buffer + \param[in] in_len input data buffer length + \param[out] out Pointer to output data buffer + \param[out] out_len output data buffer length + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_base64_websafe_decode(in,in_len,out,out_len) \ + csi_tee_base64(in,in_len,out,out_len,0,1) + +/** + \brief TEE obtain CID from Key Provisioning + \param[out] out Pointer to cid buffer + \param[out] out_len cid buffer length,if cid obtain successfully, + out_len is updated to actual cid sizes + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_get_cid(uint8_t *out, uint32_t *out_len); + +/****** lpm mode *****/ +typedef enum { + TEE_LPM_MODE_WAIT = 0, ///< lpm wait + TEE_LPM_MODE_DOZE = 1, ///< lpm doze + TEE_LPM_MODE_STOP = 2, ///< lpm stop + TEE_LPM_MODE_STANDBY = 3, ///< lpm standby + TEE_LPM_MODE_MAX, +} tee_lpm_mode_e; + +/** + \brief TEE set low power mode + \param[in] gate not use for now + \param[in] irqid not use for now + \param[in] mode \ref tee_lpm_mode_e + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_enter_lpm(uint32_t gate, uint32_t irqid, tee_lpm_mode_e mode); + +/** + \brief TEE obtain manifest info from manifest table + \note call csi_tee_get_sys_img_info, csi_tee_get_sys_os_version or csi_tee_get_sys_partition is better + \param[out] out Pointer to info buffer + \param[out] out_len Info buffer length,if info obtain successfully, + out_len is updated to actual sizes + \param[in] name info name + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_get_manifest_info(uint8_t *out, uint32_t *out_len, char *name); + +/** + \brief TEE obtain image buffer from manifest table + \param[out] out Pointer to image buffer + \param[out] out_len Image buffer length,if info obtain successfully, + out_len is updated to actual image buffer sizes + \param[in] img_name image name + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_get_sys_img_info(out,out_len,img_name) \ + csi_tee_get_manifest_info(out,out_len,img_name) + +/** + \brief TEE obtain os version from manifest table + \param[out] out Pointer to os version buffer + \param[out] out_len OS version buffer length,if info obtain successfully, + out_len is updated to actual os version buffer sizes + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_get_sys_os_version(out,out_len) \ + csi_tee_get_manifest_info(out,out_len,"os_v") + +/** + \brief TEE obtain partition buffer from manifest table + \param[out] out Pointer to partition buffer + \param[out] out_len Partition buffer length,if info obtain successfully, + out_len is updated to actual partition buffer sizes + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_get_sys_partition(out,out_len) \ + csi_tee_get_manifest_info(out,out_len,"sys_p") + +/** + \brief TEE set random seed + \param[in] Seed random sedd + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_rand_seed(uint32_t seed); + +/** + \brief TEE ramdom date generation + \param[out] out Pointer to random data buffer + \param[in] out_len Data buffer length + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_rand_generate(uint8_t *out, uint32_t out_len); + +/****** TEE RSA sign type *****/ +typedef enum { + TEE_RSA_MD5 = 0, ///< MD5 + TEE_RSA_SHA1 = 1, ///< SHA1 + TEE_RSA_SHA256 = 3, ///< SHA256 + TEE_RSA_SIGN_TYPE_MAX, ///< invailed type +} tee_rsa_sign_type_e; + +/** + \brief TEE RSA sign with private key + \param[in] in Pointer to digest buffer + \param[in] in_len Digest buffer length + \param[in] key Pointer to private key,key contains n, e, d + \param[in] key_len Private key size,must be 128*3 = 384 bytes for RSA1024, 256*3 = 768 bytes for RSA2048 + \param[out] sign Pointer to sign buffer + \param[out] sign_len Sign buffer length + \param[in] type \ref tee_rsa_sign_type_e + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_rsa_sign(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t *sign, uint32_t *sign_len, + tee_rsa_sign_type_e type); + +/** + \brief TEE RSA verify with public key + \param[in] in Pointer to digest buffer + \param[in] in_len Digest buffer length + \param[in] key Pointer to public key,key contains n, e + \param[in] key_len Public key size,must be 128*2 = 256 bytes for RSA1024, 256*2 = 512 bytes for RSA2048 + \param[in] sign Pointer to sign buffer + \param[in] sign_len Sign buffer length + \param[in] type \ref tee_rsa_sign_type_e + \return return 0 if verify successful,otherwise error code +*/ +int32_t csi_tee_rsa_verify(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t *sign, uint32_t sign_len, + tee_rsa_sign_type_e type); + +/****** TEE RSA padding mode *****/ +typedef enum { + TEE_RSA_PKCS1_PADDING = 0x01, ///< RSA PKCS padding mode + TEE_RSA_NO_PADDING = 0x02, ///< RSA no padding mode +} tee_rsa_padding_mode_e; + +/** + \brief TEE RSA encrypt with public key + \param[in] in Pointer to plaintext buffer + \param[in] in_len Plaintext buffer length + \param[in] key Pointer to public key,key contains n, e + \param[in] key_len Public key size, must be 128*2 = 256 bytes for RSA1024, 256*2 = 512 bytes for RSA2048 + \param[in] out Pointer to ciphertext buffer + \param[in] out_len Ciphertext buffer length + \param[in] padding \ref tee_rsa_padding_mode_e + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_rsa_encrypt(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t *out, uint32_t *out_len, + tee_rsa_padding_mode_e padding); +/** + \brief TEE RSA decrypt with private key + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to private key,key contains n, e, d + \param[in] key_len Private key size,must be 128*3 = 384 bytes for RSA1024, 256*3 = 768 bytes for RSA2048 + \param[in] out Pointer to plaintext buffer + \param[in] out_len Plaintext buffer length + \param[in] padding \ref tee_rsa_padding_mode_e + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_rsa_decrypt(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t *out, uint32_t *out_len, + tee_rsa_padding_mode_e padding); + +/** + \brief TEE RSA sign with internal private key + \note Only use if key provisioning exist + \param[in] in Pointer to digest buffer + \param[in] in_len Digest buffer length + \param[out] sign Pointer to sign buffer + \param[out] sign_len Sign buffer length + \param[in] type \ref tee_rsa_sign_type_e + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_cid_rsa_sign(in,in_len,sign,sign_len,type) \ + csi_tee_rsa_sign(in,in_len,NULL,0,sign,sign_len,type) + +/** + \brief TEE RSA verify with internal public key + \note Only use if key provisioning exist + \param[in] in Pointer to digest buffer + \param[in] in_len Digest buffer length + \param[in] sign Pointer to sign buffer + \param[in] sign_len Sign buffer length + \param[in] type \ref tee_rsa_sign_type_e + \return return 0 if verify successful,otherwise error code +*/ +#define csi_tee_cid_rsa_verify(in,in_len,sign,sign_len,type) \ + csi_tee_rsa_verify(in,in_len,NULL,0,sign,sign_len,type) + +/** + \brief TEE RSA encrypt with internal public key + \note Only use if key provisioning exist + \param[in] in Pointer to plaintext buffer + \param[in] in_len Plaintext buffer length + \param[in] out Pointer to ciphertext buffer + \param[in] out_len Ciphertext buffer length + \param[in] padding \ref tee_rsa_padding_mode_e + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_cid_rsa_encrypt(in,in_len,out,out_len,padding) \ + csi_tee_rsa_encrypt(in,in_len,NULL,0,out,out_len,padding) + +/** + \brief TEE RSA decrypt with internal private key + \note Only use if key provisioning exist + \param[in] in Pointer to ciphertext buffer + \param[in] in_len Ciphertext buffer length + \param[in] key Pointer to private key,key contains n, e, d + \param[in] key_len Private key size,must be 128*3 = 384 bytes for RSA1024, 256*3 = 768 bytes for RSA2048 + \param[in] out Pointer to plaintext buffer + \param[in] out_len Plaintext buffer length + \param[in] padding \ref tee_rsa_padding_mode_e + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_cid_rsa_decrypt(in,in_len,out,out_len,padding) \ + csi_tee_rsa_decrypt(in,in_len,NULL,0,out,out_len,padding) + +/** + \brief verify boot image with boot public key + \note Only use if key provisioning exist + \param[in] in Pointer to digest buffer + \param[in] in_len Digest buffer length + \param[in] sign Pointer to sign buffer + \param[in] sign_len Sign buffer length + \param[in] type \ref tee_rsa_sign_type_e + \return return 0 if verify successful,otherwise error code +*/ +int32_t csi_tee_img_rsa_verify(const uint8_t *in, uint32_t in_len, + uint8_t *sign, uint32_t sign_len, + tee_rsa_sign_type_e type); + +/****** TEE HASH operation mode *****/ +typedef enum { + TEE_HASH_OP_NONE = 0, ///< No operation + TEE_HASH_OP_START = 1, ///< HASH init + TEE_HASH_OP_UPDATA = 2, ///< HASH update + TEE_HASH_OP_FINISH = 3, ///< HASH finish + TEE_HASH_OP_MAX, ///< invailed operation +} tee_hash_op_e; + +/****** TEE HMAC type *****/ +typedef enum { + TEE_HMAC_SHA1 = 1, ///< HMAC with SHA1 +} tee_hmac_type_e; + +/** + \brief TEE HAMC + \note Call csi_tee_hmac_digest is better + out buffer size must be large enough according to type, eg. 20 bytes for TEE_HMAC_SHA1 + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[in] key Pointer to key buffer + \param[in] key_len Key buffer size + \param[out] out Pointer to output date buffer + \param[in] type \ref tee_hmac_type_e + \param[in] hash_op \ref tee_hash_op_e + \param[in] ctx Pointer to context of hmac + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_hmac(const uint8_t *in, uint32_t in_len, + const uint8_t *key, uint32_t key_len, + uint8_t *out, + tee_hmac_type_e type, + tee_hash_op_e hash_op, + uint32_t *ctx); + +/** + \brief TEE HAMC digest + \note out buffer size must be large enough according to type, eg. 20 bytes for TEE_HMAC_SHA1 + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[in] key Pointer to key buffer + \param[in] key_len Key buffer size + \param[out] out Pointer to output date buffer + \param[in] type \ref tee_hmac_type_e + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_hmac_digest(in,in_len,key,key_len,out,type) \ + csi_tee_hmac(in,in_len,key,key_len,out,type,TEE_HASH_OP_NONE,NULL) + +/****** TEE SHA type *****/ +typedef enum { + TEE_SHA1 = 0, ///< SHA1 + TEE_SHA256 = 1, ///< SHA256 + TEE_SHA224 = 2, ///< SHA224 + TEE_SHA384 = 3, ///< SHA384 + TEE_SHA512 = 4, ///< SHA512 + TEE_SHA_MAX, ///< invaild sha type +} tee_sha_type_t; + +/** + \brief TEE SHA + \note Call csi_tee_sha_digest, csi_tee_sha_start, csi_tee_sha_update or csi_tee_sha_finish is better + out buffer size must be large enough according to type, eg. 20 bytes for TEE_SHA1, 32 bytes for TEE_SHA256 + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[out] out Pointer to output date buffer + \param[in] type \ref tee_sha_type_t + \param[in] hash_op \ref tee_hash_op_e + \param[in] ctx Pointer to context of sha + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_sha(const uint8_t *in, uint32_t in_len, + uint8_t *out, + tee_sha_type_t type, + tee_hash_op_e hash_op, + void *ctx); + +/** + \brief TEE SHA digest + \note out buffer size must be large enough according to type, eg. 20 bytes for TEE_SHA1, 32 bytes for TEE_SHA256 + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[out] out Pointer to output date buffer + \param[in] type \ref tee_sha_type_t + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_sha_digest(in,in_len,out,type) \ + csi_tee_sha(in,in_len,out,type,TEE_HASH_OP_NONE,NULL); + +/** + \brief TEE SHA start, initial sha + \param[in] type \ref tee_sha_type_t + \param[in] ctx Pointer to context of sha + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_sha_start(type,ctx) \ + csi_tee_sha(NULL,0,NULL,type,TEE_HASH_OP_START,ctx); + +/** + \brief TEE SHA update, update data + \param[in] in Pointer to input data buffer + \param[in] in_len Input data buffer length + \param[in] ctx Pointer to context of sha + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_sha_update(in,in_len,ctx) \ + csi_tee_sha(in,in_len,NULL,0,TEE_HASH_OP_UPDATA,ctx); + +/** + \brief TEE SHA digest, get sha digest + \note out buffer size must be large enough according to type, eg. 20 bytes for TEE_SHA1, 32 bytes for TEE_SHA256 + \param[out] out Pointer to output date buffer + \param[in] ctx Pointer to context of sha + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_sha_finish(out,ctx) \ + csi_tee_sha(NULL,0,out,0,TEE_HASH_OP_FINISH,ctx); + +/** + \brief TEE get device name and product key + \param[in] name_encrypted Pointer to device name ciphertext + \param[in] name_encrypted_len device name ciphertext length + \param[in] product_key_encrypted Pointer to device product key ciphertext + \param[in] product_key_encrypted_len Device product key ciphertext length + \param[out] name Pointer to device name + \param[out] name_len Device name length + \param[out] product_key Pointer to device product key + \param[out] product_key_len Device product key length + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_dev_info_get(const uint8_t *name_encrypted, uint32_t name_encrypted_len, + const uint8_t *product_key_encrypted, uint32_t product_key_encrypted_len, + const uint8_t *name, uint32_t *name_len, + const uint8_t *product_key, uint32_t *product_key_len); + +/** + \brief TEE device info sign + \param[in] in Pointer to input date buffer + \param[in] in_len Input data buffer length + \param[in] device_secret Pointer to device secret ciphertext + \param[in] device_secret_len Device secret ciphertext length + \param[out] sign Pointer to signed buffer + \param[out] sign_len Signed buffer length + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_dev_info_sign(const uint8_t *in, uint32_t in_len, + const uint8_t *device_secret, uint32_t device_secret_len, + const uint8_t *sign, uint32_t *sign_len); + +/** + \brief TEE device info encrypt/decrypt + \param[in] in Pointer to input date buffer + \param[in] in_len Input data buffer length + \param[in] out Pointer to output date buffer + \param[in] out_len Onput data buffer length + \param[in] is_enc 1 incrypt 0 decrypt + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_dev_info_crypt(const uint8_t *in, uint32_t in_len, + uint8_t *out, uint32_t *out_len, + uint8_t is_enc); + +/** + \brief TEE device info encrypt + \param[in] in Pointer to input date buffer + \param[in] in_len Input data buffer length + \param[in] out Pointer to output date buffer + \param[in] out_len Onput data buffer length + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_dev_info_encrypt(in, in_len, out, out_len) \ + csi_tee_dev_info_crypt(in, in_len, out, out_len, 1) + +/** + \brief TEE device info decrypt + \param[in] in Pointer to input date buffer + \param[in] in_len Input data buffer length + \param[in] out Pointer to output date buffer + \param[in] out_len Onput data buffer length + \return return 0 if successful,otherwise error code +*/ +#define csi_tee_dev_info_decrypt(in, in_len, out, out_len) \ + csi_tee_dev_info_crypt(in, in_len, out, out_len, 0) + +/****** system clock source type *****/ +typedef enum { + IHS_CLK = 0, ///< internel clock source + EHS_CLK = 1 ///< externel clock source +} clk_src_e; + +/****** system clock value scope *****/ +typedef enum { + OSR_8M_CLK_16M = 0x80204, ///< register value for clock 16M + OSR_8M_CLK_24M = 0x80206, ///< register value for clock 24M + OSR_8M_CLK_32M = 0x80208, ///< register value for clock 32M + OSR_8M_CLK_40M = 0x8020a, ///< register value for clock 40M + OSR_8M_CLK_48M = 0x8020c ///< register value for clock 48M +} clk_val_e; + +/** + \brief Set system frequence + \param[in] clk_src indicate clock source type + \param[in] clk_val system freqence to be set + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_set_sys_freq(uint32_t clk_src, uint32_t clk_val); + +/** + \brief Get system frequence + \param[in] clk_val value address to store system freqence + \return return 0 if successful,otherwise error code +*/ +int32_t csi_tee_get_sys_freq(uint32_t *clk_val); + + +int32_t csi_tee_xor(uint8_t *out, uint32_t *out_len); +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_AES_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_timer.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_timer.h new file mode 100644 index 000000000..a2474194f --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_timer.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_timer.h + * @brief header file for timer driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_TIMER_H_ +#define _CSI_TIMER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/// definition for timer handle. +typedef void *timer_handle_t; + +/*----- TIMER Control Codes: Mode -----*/ +typedef enum { + TIMER_MODE_FREE_RUNNING = 0, ///< free running mode + TIMER_MODE_RELOAD ///< reload mode +} timer_mode_e; + +/** +\brief TIMER Status +*/ +typedef struct { + uint32_t active : 1; ///< timer active flag + uint32_t timeout : 1; ///< timeout flag +} timer_status_t; + +/** +\brief TIMER Event +*/ +typedef enum { + TIMER_EVENT_TIMEOUT = 0 ///< time out event +} timer_event_e; + +typedef void (*timer_event_cb_t)(timer_event_e event, void *arg); ///< Pointer to \ref timer_event_cb_t : TIMER Event call back. + +/** +\brief TIMER Device Driver Capabilities. +*/ +typedef struct { + uint32_t interrupt_mode : 1; ///< supports Interrupt mode +} timer_capabilities_t; + +/** + \brief get timer instance count. + \return timer instance count +*/ +int32_t csi_timer_get_instance_count(void); + +/** + \brief Initialize TIMER Interface. 1. Initializes the resources needed for the TIMER interface 2.registers event callback function + \param[in] idx instance timer index + \param[in] cb_event Pointer to \ref timer_event_cb_t + \param[in] cb_arg arguments of cb_event + \return pointer to timer instance +*/ +timer_handle_t csi_timer_initialize(int32_t idx, timer_event_cb_t cb_event, void *cb_arg); + +/** + \brief De-initialize TIMER Interface. stops operation and releases the software resources used by the interface + \param[in] handle timer handle to operate. + \return error code +*/ +int32_t csi_timer_uninitialize(timer_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle timer handle to operate. + \return \ref timer_capabilities_t +*/ +timer_capabilities_t csi_timer_get_capabilities(timer_handle_t handle); + +/** + \brief config timer mode. + \param[in] handle timer handle to operate. + \param[in] mode \ref timer_mode_e + \return error code +*/ +int32_t csi_timer_config(timer_handle_t handle, timer_mode_e mode); + +/** + \brief Set timer. + \param[in] handle timer handle to operate. + \param[in] timeout the timeout value in microseconds(us). + \return error code +*/ +int32_t csi_timer_set_timeout(timer_handle_t handle, uint32_t timeout); + +/** + \brief Start timer. + \param[in] handle timer handle to operate. + \param[in] apbfreq APB frequency + \return error code +*/ +int32_t csi_timer_start(timer_handle_t handle, uint32_t apbfreq); + +/** + \brief Stop timer. + \param[in] handle timer handle to operate. + \return error code +*/ +int32_t csi_timer_stop(timer_handle_t handle); + +/** + \brief suspend timer. + \param[in] handle timer handle to operate. + \return error code +*/ +int32_t csi_timer_suspend(timer_handle_t handle); + +/** + \brief resume timer. + \param[in] handle timer handle to operate. + \return error code +*/ +int32_t csi_timer_resume(timer_handle_t handle); + +/** + \brief get timer current value + \param[in] handle timer handle to operate. + \param[in] value timer current value + \return error code +*/ +int32_t csi_timer_get_current_value(timer_handle_t handle, uint32_t *value); + +/** + \brief Get TIMER status. + \param[in] handle timer handle to operate. + \return TIMER status \ref timer_status_t +*/ +timer_status_t csi_timer_get_status(timer_handle_t handle); + +/** + \brief get timer reload value + \param[in] handle timer handle to operate. + \param[in] value timer reload value + \return error code +*/ +int32_t csi_timer_get_load_value(timer_handle_t handle, uint32_t *value); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_TIMER_H_ */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_trng.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_trng.h new file mode 100644 index 000000000..5646c4c76 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_trng.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_trng.h + * @brief header file for trng driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ +#ifndef _CSI_TRNG_H_ +#define _CSI_TRNG_H_ + +#include "drv_common.h" +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +/// definition for trng handle. +typedef void *trng_handle_t; +/****** TRNG specific error codes *****/ +typedef enum { + TRNG_ERROR_MODE = 0, ///< Specified Mode not supported +} drv_trng_error_e; + +/*----- TRNG Control Codes: Mode -----*/ +typedef enum { + TRNG_MODE_LOWPOWER = 0, ///< TRNG Low power Mode + TRNG_MODE_NORMAL ///< TRNG Normal Mode +} trng_mode_e; + +/** +\brief TRNG Status +*/ +typedef struct { + uint32_t busy : 1; + uint32_t data_valid : 1; ///< Data is valid flag +} trng_status_t; + +/****** TRNG Event *****/ +typedef enum { + TRNG_EVENT_DATA_GENERATE_COMPLETE = 0 ///< Get data from TRNG success +} trng_event_e; +typedef void (*trng_event_cb_t)(trng_event_e event); ///< Pointer to \ref trng_event_cb_t : TRNG Event call back. + +/** +\brief TRNG Device Driver Capabilities. +*/ +typedef struct { + uint32_t lowper_mode : 1; ///< supports low power mode +} trng_capabilities_t; + +// Function documentation + +/** + \brief get trng handle count. + \return trng handle count +*/ +int32_t csi_trng_get_instance_count(void); + +/** + \brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_trng_get_instance_count() + \param[in] cb_event Pointer to \ref trng_event_cb_t + \return pointer to trng handle +*/ +trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event); + +/** + \brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface + \param[in] handle trng handle to operate. + \return error code +*/ +int32_t csi_trng_uninitialize(trng_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle trng handle to operate. + \return \ref trng_capabilities_t +*/ +trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle); + +/** + \brief Get data from the TRNG. + \param[in] handle trng handle to operate. + \param[out] data Pointer to buffer with data get from TRNG + \param[in] num Number of data items to obtain + \return error code +*/ +int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num); + +/** + \brief Get TRNG status. + \param[in] handle trng handle to operate. + \return TRNG status \ref trng_status_t +*/ +trng_status_t csi_trng_get_status(trng_handle_t handle); + + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_TRNG_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_usart.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_usart.h new file mode 100644 index 000000000..cd8bbf6d7 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_usart.h @@ -0,0 +1,495 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_usart.h + * @brief header file for usart driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_USART_H_ +#define _CSI_USART_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/// definition for usart handle. +typedef void *usart_handle_t; + +/****** USART specific error codes *****/ +typedef enum { + EDRV_USART_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported + EDRV_USART_BAUDRATE, ///< Specified baudrate not supported + EDRV_USART_DATA_BITS, ///< Specified number of Data bits not supported + EDRV_USART_PARITY, ///< Specified Parity not supported + EDRV_USART_STOP_BITS, ///< Specified number of Stop bits not supported + EDRV_USART_FLOW_CONTROL, ///< Specified Flow Control not supported + EDRV_USART_CPOL, ///< Specified Clock Polarity not supported + EDRV_USART_CPHA ///< Specified Clock Phase not supported +} drv_usart_error_e; + +/*----- USART Control Codes: Mode -----*/ +typedef enum { + USART_MODE_ASYNCHRONOUS = 0, ///< USART (Asynchronous) + USART_MODE_SYNCHRONOUS_MASTER , ///< Synchronous Master + USART_MODE_SYNCHRONOUS_SLAVE , ///< Synchronous Slave (external clock signal) + USART_MODE_SINGLE_WIRE , ///< USART Single-wire (half-duplex) + USART_MODE_SINGLE_IRDA , ///< UART IrDA + USART_MODE_SINGLE_SMART_CARD , ///< UART Smart Card +} usart_mode_e; + +/*----- USART Control Codes: Mode Parameters: Data Bits -----*/ +typedef enum { + USART_DATA_BITS_5 = 0, ///< 5 Data bits + USART_DATA_BITS_6 , ///< 6 Data bit + USART_DATA_BITS_7 , ///< 7 Data bits + USART_DATA_BITS_8 , ///< 8 Data bits (default) + USART_DATA_BITS_9 ///< 9 Data bits +} usart_data_bits_e; + +/*----- USART Control Codes: Mode Parameters: Parity -----*/ +typedef enum { + USART_PARITY_NONE = 0, ///< No Parity (default) + USART_PARITY_EVEN , ///< Even Parity + USART_PARITY_ODD , ///< Odd Parity + USART_PARITY_1 , ///< Parity forced to 1 + USART_PARITY_0 ///< Parity forced to 0 +} usart_parity_e; + +/*----- USART Control Codes: Mode Parameters: Stop Bits -----*/ +typedef enum { + USART_STOP_BITS_1 = 0, ///< 1 Stop bit (default) + USART_STOP_BITS_2 , ///< 2 Stop bits + USART_STOP_BITS_1_5 , ///< 1.5 Stop bits + USART_STOP_BITS_0_5 ///< 0.5 Stop bits +} usart_stop_bits_e; + +/*----- USART Control Codes: Mode Parameters: Clock Polarity (Synchronous mode) -----*/ +typedef enum { + USART_CPOL0 = 0, ///< CPOL = 0 (default). data are captured on rising edge (low->high transition) + USART_CPOL1 ///< CPOL = 1. data are captured on falling edge (high->lowh transition) +} usart_cpol_e; + +/*----- USART Control Codes: Mode Parameters: Clock Phase (Synchronous mode) -----*/ +typedef enum { + USART_CPHA0 = 0, ///< CPHA = 0 (default). sample on first (leading) edge + USART_CPHA1 ///< CPHA = 1. sample on second (trailing) edge +} usart_cpha_e; + +/*----- USART Control Codes: flush data type-----*/ +typedef enum { + USART_FLUSH_WRITE, + USART_FLUSH_READ +} usart_flush_type_e; + +/*----- USART Control Codes: flow control type-----*/ +typedef enum { + USART_FLOWCTRL_NONE, + USART_FLOWCTRL_CTS, + USART_FLOWCTRL_RTS, + USART_FLOWCTRL_CTS_RTS +} usart_flowctrl_type_e; + +/*----- USART Modem Control -----*/ +typedef enum { + USART_RTS_CLEAR, ///< Deactivate RTS + USART_RTS_SET, ///< Activate RTS + USART_DTR_CLEAR, ///< Deactivate DTR + USART_DTR_SET ///< Activate DTR +} usart_modem_ctrl_e; + +/*----- USART Modem Status -----*/ +typedef struct { + uint32_t cts : 1; ///< CTS state: 1=Active, 0=Inactive + uint32_t dsr : 1; ///< DSR state: 1=Active, 0=Inactive + uint32_t dcd : 1; ///< DCD state: 1=Active, 0=Inactive + uint32_t ri : 1; ///< RI state: 1=Active, 0=Inactive +} usart_modem_stat_t; + +/*----- USART Control Codes: on-off intrrupte type-----*/ +typedef enum { + USART_INTR_WRITE, + USART_INTR_READ +} usart_intr_type_e; + +/** +\brief USART Status +*/ +typedef struct { + uint32_t tx_busy : 1; ///< Transmitter busy flag + uint32_t rx_busy : 1; ///< Receiver busy flag + uint32_t tx_underflow : 1; ///< Transmit data underflow detected (cleared on start of next send operation)(Synchronous Slave) + uint32_t rx_overflow : 1; ///< Receive data overflow detected (cleared on start of next receive operation) + uint32_t rx_break : 1; ///< Break detected on receive (cleared on start of next receive operation) + uint32_t rx_framing_error : 1; ///< Framing error detected on receive (cleared on start of next receive operation) + uint32_t rx_parity_error : 1; ///< Parity error detected on receive (cleared on start of next receive operation) +} usart_status_t; + +/****** USART Event *****/ +typedef enum { + USART_EVENT_SEND_COMPLETE = 0, ///< Send completed; however USART may still transmit data + USART_EVENT_RECEIVE_COMPLETE = 1, ///< Receive completed + USART_EVENT_TRANSFER_COMPLETE = 2, ///< Transfer completed + USART_EVENT_TX_COMPLETE = 3, ///< Transmit completed (optional) + USART_EVENT_TX_UNDERFLOW = 4, ///< Transmit data not available (Synchronous Slave) + USART_EVENT_RX_OVERFLOW = 5, ///< Receive data overflow + USART_EVENT_RX_TIMEOUT = 6, ///< Receive character timeout (optional) + USART_EVENT_RX_BREAK = 7, ///< Break detected on receive + USART_EVENT_RX_FRAMING_ERROR = 8, ///< Framing error detected on receive + USART_EVENT_RX_PARITY_ERROR = 9, ///< Parity error detected on receive + USART_EVENT_CTS = 10, ///< CTS state changed (optional) + USART_EVENT_DSR = 11, ///< DSR state changed (optional) + USART_EVENT_DCD = 12, ///< DCD state changed (optional) + USART_EVENT_RI = 13, ///< RI state changed (optional) + USART_EVENT_RECEIVED = 14, ///< Received data, but no send()/receive()/transfer() called +} usart_event_e; + +typedef void (*usart_event_cb_t)(usart_event_e event, void *cb_arg); ///< Pointer to \ref usart_event_cb_t : USART Event call back. + +/** +\brief USART Driver Capabilities. +*/ +typedef struct { + uint32_t asynchronous : 1; ///< supports UART (Asynchronous) mode + uint32_t synchronous_master : 1; ///< supports Synchronous Master mode + uint32_t synchronous_slave : 1; ///< supports Synchronous Slave mode + uint32_t single_wire : 1; ///< supports UART Single-wire mode + uint32_t irda : 1; ///< supports UART IrDA mode + uint32_t smart_card : 1; ///< supports UART Smart Card mode + uint32_t smart_card_clock : 1; ///< Smart Card Clock generator available + uint32_t flow_control_rts : 1; ///< RTS Flow Control available + uint32_t flow_control_cts : 1; ///< CTS Flow Control available + uint32_t event_tx_complete : 1; ///< Transmit completed event: \ref ARM_USART_EVENT_TX_COMPLETE + uint32_t event_rx_timeout : 1; ///< Signal receive character timeout event: \ref ARM_USART_EVENT_RX_TIMEOUT + uint32_t rts : 1; ///< RTS Line: 0=not available, 1=available + uint32_t cts : 1; ///< CTS Line: 0=not available, 1=available + uint32_t dtr : 1; ///< DTR Line: 0=not available, 1=available + uint32_t dsr : 1; ///< DSR Line: 0=not available, 1=available + uint32_t dcd : 1; ///< DCD Line: 0=not available, 1=available + uint32_t ri : 1; ///< RI Line: 0=not available, 1=available + uint32_t event_cts : 1; ///< Signal CTS change event: \ref ARM_USART_EVENT_CTS + uint32_t event_dsr : 1; ///< Signal DSR change event: \ref ARM_USART_EVENT_DSR + uint32_t event_dcd : 1; ///< Signal DCD change event: \ref ARM_USART_EVENT_DCD + uint32_t event_ri : 1; ///< Signal RI change event: \ref ARM_USART_EVENT_RI +} usart_capabilities_t; + +/** + \brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function + \param[in] tx usart pin of tx + \param[in] rx usart pin of rx + \param[in] cb_event Pointer to \ref usart_event_cb_t + \param[in] cb_arg argument for cb_event + \return return usart handle if success +*/ +usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg); + +/** + \brief De-initialize USART Interface. stops operation and releases the software resources used by the interface + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_uninitialize(usart_handle_t handle); +/** + \brief Get driver capabilities. + \param[in] handle usart handle to operate. + \return \ref usart_capabilities_t +*/ +usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle); + +/** + \brief config usart mode. + \param[in] handle usart handle to operate. + \param[in] sysclk system clock. + \param[in] baud baud rate. + \param[in] mode \ref usart_mode_e . + \param[in] parity \ref usart_parity_e . + \param[in] stopbits \ref usart_stop_bits_e . + \param[in] bits \ref usart_data_bits_e . + \return error code +*/ +int32_t csi_usart_config(usart_handle_t handle, + uint32_t sysclk, + uint32_t baud, + usart_mode_e mode, + usart_parity_e parity, + usart_stop_bits_e stopbits, + usart_data_bits_e bits); + +/** + \brief config usart default tx value. used in synchronous mode + \param[in] handle usart handle to operate. + \param[in] value default tx value + \return error code +*/ +int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value); + +/** + \brief Start sending data to USART transmitter,(received data is ignored). + This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens. + \ref csi_usart_get_status can indicates operation status. + \param[in] handle usart handle to operate. + \param[in] data Pointer to buffer with data to send to USART transmitter. data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits + \param[in] num Number of data items to send + \return error code +*/ +int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num/*,bool asynch*/); + +/** + \brief Abort Send data to USART transmitter + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_abort_send(usart_handle_t handle); + +/** + \brief Start receiving data from USART receiver.transmits the default value as specified by csi_usart_set_default_tx_value. \n + This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens. + \ref csi_usart_get_status can indicates operation status. + \param[in] handle usart handle to operate. + \param[out] data Pointer to buffer for data to receive from USART receiver.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits + \param[in] num Number of data items to receive + \return error code +*/ +int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num/*,bool asynch*/); + +/** + \brief query data from UART receiver FIFO. + \param[in] handle usart handle to operate. + \param[out] data Pointer to buffer for data to receive from UART receiver + \param[in] num Number of data items to receive + \return receive fifo data num +*/ +int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num/*,bool asynch*/); + +/** + \brief Abort Receive data from USART receiver + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_abort_receive(usart_handle_t handle); + +/** + \brief Start synchronously sends data to the USART transmitter and receives data from the USART receiver. used in synchronous mode + This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens. + \ref csi_usart_get_status can indicates operation status. + \param[in] handle usart handle to operate. + \param[in] data_out Pointer to buffer with data to send to USART transmitter.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits + \param[out] data_in Pointer to buffer for data to receive from USART receiver.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits + \param[in] num Number of data items to transfer + \return error code +*/ +int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num/*,bool asynch*/); + +/** + \brief abort sending/receiving data to/from USART transmitter/receiver. + \param[in] handle usart handle to operate. + \return error code +*/ +int32_t csi_usart_abort_transfer(usart_handle_t handle); + +/** + \brief Get USART status. + \param[in] handle usart handle to operate. + \return USART status \ref usart_status_t +*/ +usart_status_t csi_usart_get_status(usart_handle_t handle); + +/** + \brief flush receive/send data. + \param[in] handle usart handle to operate. + \param[in] type \ref usart_flush_type_e . + \return \ref execution_status +*/ +int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type); + +/** + \brief control interrupt on/off. + \param[in] handle usart handle to operate. + \param[in] type \ref usart_intr_type_e. + \param[in] flag 0-OFF, 1-ON. + \return error code +*/ +int32_t csi_usart_interrupt_on_off(usart_handle_t handle, usart_intr_type_e type, int flag); + +/** + \brief set the baut drate of usart. + \param[in] addr usart base to operate. + \param[in] baudrate baud rate + \param[in] apbfreq the frequency of the apb. + \return error code +*/ +int32_t csi_usart_config_baudrate(usart_handle_t handle, uint32_t baudrate, uint32_t apbfreq); + +/** + \brief config usart mode. + \param[in] handle usart handle to operate. + \param[in] mode \ref usart_mode_e + \return error code +*/ +int32_t csi_usart_config_mode(usart_handle_t handle, usart_mode_e mode); + +/** + \brief config usart parity. + \param[in] handle usart handle to operate. + \param[in] parity \ref usart_parity_e + \return error code +*/ +int32_t csi_usart_config_parity(usart_handle_t handle, usart_parity_e parity); + +/** + \brief config usart stop bit number. + \param[in] handle usart handle to operate. + \param[in] stopbits \ref usart_stop_bits_e + \return error code +*/ +int32_t dw_usart_config_stopbits(usart_handle_t handle, usart_stop_bits_e stopbit); + +/** + \brief config usart data length. + \param[in] handle usart handle to operate. + \param[in] databits \ref usart_data_bits_e + \return error code +*/ +int32_t csi_usart_config_databits(usart_handle_t handle, usart_data_bits_e databits); + +/** + \brief get character in query mode. + \param[in] handle usart handle to operate. + \param[in] the pointer to the received character if return 0. + \return error code +*/ +int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch); + +/** + \brief transmit character in query mode. + \param[in] handle usart handle to operate. + \param[in] ch the input character + \return error code +*/ +int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch); + +/** + \brief Get usart send data count. + \param[in] handle usart handle to operate. + \return number of data bytes transferred +*/ +uint32_t csi_usart_get_tx_count(usart_handle_t handle); + +/** + \brief Get usart receive data count. + \param[in] handle usart handle to operate. + \return number of data bytes transferred +*/ +uint32_t csi_usart_get_rx_count(usart_handle_t handle); + +/** + \brief control usart power. + \param[in] handle usart handle to operate. + \param[in] state power state.\ref csi_power_stat_e. + \return error code +*/ +int32_t csi_usart_power_control(usart_handle_t handle, csi_power_stat_e state); + +/** + \brief config usart flow control type. + \param[in] handle usart handle to operate. + \param[in] flowctrl_type flow control type.\ref usart_flowctrl_type_e. + \param[in] tx_flow The TX flow pin name + \param[in] rx_flow The RX flow pin name + \return error code +*/ +int32_t csi_usart_config_flowctrl(usart_handle_t handle, + usart_flowctrl_type_e flowctrl_type, + pin_t tx_flow, pin_t rx_flow); +/** + \brief usart modem control. + \param[in] handle usart handle to operate. + \param[in] modem_ctrl modem control action.\ref usart_modem_ctrl_e. + \return error code +*/ +int32_t csi_usart_modem_ctrl(usart_handle_t handle, usart_modem_ctrl_e modem_ctrl); + +/** + \brief get usart modem status. + \param[in] handle usart handle to operate. + \param[in] modem_ctrl modem control action.\ref usart_modem_ctrl_e. + \return modem status.\ref usart_modem_stat_t. +*/ +usart_modem_stat_t csi_usart_get_modem_stat(usart_handle_t handle); + +/** + \brief config usart clock Polarity and Phase. + \param[in] handle usart handle to operate. + \param[in] cpol Clock Polarity.\ref usart_cpol_e. + \param[in] cpha Clock Phase.\ref usart_cpha_e. + \return error code +*/ +int32_t csi_usart_config_clock(usart_handle_t handle, usart_cpol_e cpol, usart_cpha_e cpha); + +/** + \brief config usart guard time. + \param[in] handle usart handle to operate. + \param[in] num_of_bits guard time in number of bit periods. + \return error code +*/ +int32_t csi_usart_config_guard_time(usart_handle_t handle, uint32_t num_of_bits); + +/** + \brief check if usart is readable(data received). + \param[in] handle usart handle to operate. + \return 1 - a character can be read, 0 if nothing to read ,negative for error code +*/ +int32_t csi_usart_readable(usart_handle_t handle); + +/** + \brief check if usart is writable(free for data sending). + \param[in] handle usart handle to operate. + \return 1 - a character can be written, 0 - cannot be written ,negative for error code +*/ +int32_t csi_usart_writable(usart_handle_t handle); + +/** + \brief control the transmit. + \param[in] handle usart handle to operate. + \param[in] 1 - enable the transmitter. 0 - disable the transmitter + \return error code +*/ +int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable); + +/** + \brief control the receive. + \param[in] handle usart handle to operate. + \param[in] 1 - enable the receiver. 0 - disable the receiver + \return error code +*/ +int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable); + +/** + \brief control the break. + \param[in] handle usart handle to operate. + \param[in] 1- Enable continuous Break transmission,0 - disable continuous Break transmission + \return error code +*/ +int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_USART_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_wdt.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_wdt.h new file mode 100644 index 000000000..bf69c127c --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_wdt.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file drv_wdt.h + * @brief header file for wdt driver + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CSI_WDT_H_ +#define _CSI_WDT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/// definition for wdt handle. +typedef void *wdt_handle_t; + +/****** WDT Event *****/ +typedef enum { + WDT_EVENT_TIMEOUT = 0 ///< generate the interrupt +} wdt_event_e; + +typedef void (*wdt_event_cb_t)(wdt_event_e event); ///< Pointer to \ref wdt_event_cb_t : WDT Event call back. + +/** +\brief WDT Device Driver Capabilities. +*/ +typedef struct { + uint32_t interrupt : 1; ///< supports interrupt +} wdt_capabilities_t; + +/** + \brief get wdt instance count. + \return wdt instance count +*/ +int32_t csi_wdt_get_instance_count(void); + +/** + \brief Initialize WDT Interface. 1. Initializes the resources needed for the WDT interface 2.registers event callback function + \param[in] idx must not exceed return value of csi_wdt_get_instance_count() + \param[in] cb_event Pointer to \ref wdt_event_cb_t + \return pointer to wdt instance +*/ +wdt_handle_t csi_wdt_initialize(int32_t idx, wdt_event_cb_t cb_event); + +/** + \brief De-initialize WDT Interface. stops operation and releases the software resources used by the interface + \param[in] handle wdt handle to operate. + \return error code +*/ +int32_t csi_wdt_uninitialize(wdt_handle_t handle); + +/** + \brief Get driver capabilities. + \param[in] handle wdt handle to operate. + \return \ref wdt_capabilities_t +*/ +wdt_capabilities_t csi_wdt_get_capabilities(wdt_handle_t handle); + +/** + \brief Set the WDT value. + \param[in] handle wdt handle to operate. + \param[in] value the timeout value(ms). + \return error code +*/ +int32_t csi_wdt_set_timeout(wdt_handle_t handle, uint32_t value); + +/** + \brief Start the WDT. + \param[in] handle wdt handle to operate. + \return error code +*/ +int32_t csi_wdt_start(wdt_handle_t handle); + +/** + \brief Stop the WDT. + \param[in] handle wdt handle to operate. + \return error code +*/ +int32_t csi_wdt_stop(wdt_handle_t handle); + +/** + \brief Restart the WDT. + \param[in] handle wdt handle to operate. + \return error code +*/ +int32_t csi_wdt_restart(wdt_handle_t handle); + +/** + \brief Read the WDT Current value. + \param[in] handle wdt handle to operate. + \param[in] value Pointer to the Value. + \return error code +*/ +int32_t csi_wdt_read_current_value(wdt_handle_t handle, uint32_t *value); + +#ifdef __cplusplus +} +#endif + +#endif /* _CSI_WDT_H_ */ diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_wifi.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_wifi.h new file mode 100644 index 000000000..0ea3d3eab --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_wifi.h @@ -0,0 +1,1051 @@ +/** + * Copyright (C) 2016 CSI Project. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CSI_WIFI_H__ +#define __CSI_WIFI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef bool +#define bool int8_t +#define false 0 ///< XOS definition of 'false' +#define true 1 ///< XOS definition of 'true' +#endif + +typedef enum { + WIFI_EVENT_WIFI_READY = 0, /**< WiFi ready */ + WIFI_EVENT_SCAN_DONE, /**< finish scanning AP */ + WIFI_EVENT_STA_START, /**< station start */ + WIFI_EVENT_STA_STOP, /**< station stop */ + WIFI_EVENT_STA_CONNECTED, /**< station connected to AP */ + WIFI_EVENT_STA_DISCONNECTED, /**< station disconnected from AP */ + WIFI_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by station changed */ + WIFI_EVENT_STA_GOT_IP, /**< station got IP from connected AP */ + WIFI_EVENT_STA_WPS_ER_SUCCESS, /**< station wps succeeds in enrollee mode */ + WIFI_EVENT_STA_WPS_ER_FAILED, /**< station wps fails in enrollee mode */ + WIFI_EVENT_STA_WPS_ER_TIMEOUT, /**< station wps timeout in enrollee mode */ + WIFI_EVENT_STA_WPS_ER_PIN, /**< station wps pin code in enrollee mode */ + WIFI_EVENT_AP_START, /**< soft-AP start */ + WIFI_EVENT_AP_STOP, /**< soft-AP stop */ + WIFI_EVENT_AP_STACONNECTED, /**< a station connected to soft-AP */ + WIFI_EVENT_AP_STADISCONNECTED, /**< a station disconnected from soft-AP */ + WIFI_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */ + WIFI_EVENT_AP_STA_GOT_IP6, /**< station or ap interface v6IP addr is preferred */ + WIFI_EVENT_ETH_START, /**< ethernet start */ + WIFI_EVENT_ETH_STOP, /**< ethernet stop */ + WIFI_EVENT_ETH_CONNECTED, /**< ethernet phy link up */ + WIFI_EVENT_ETH_DISCONNECTED, /**< ethernet phy link down */ + WIFI_EVENT_ETH_GOT_IP, /**< ethernet got IP from connected AP */ + WIFI_EVENT_MAX +} wifi_event_id_t; + + +typedef enum { + CSI_IF_WIFI_STA = 0, /**< CSI station interface */ + CSI_IF_WIFI_AP, /**< CSI soft-AP interface */ + CSI_IF_ETH, /**< CSI ethernet interface */ + CSI_IF_MAX +} csi_interface_t; + +typedef enum { + WIFI_MODE_NULL = 0, /**< null mode */ + WIFI_MODE_STA, /**< WiFi station mode */ + WIFI_MODE_AP, /**< WiFi soft-AP mode */ + WIFI_MODE_APSTA, /**< WiFi station + soft-AP mode */ + WIFI_MODE_MAX +} wifi_mode_t; + +typedef csi_interface_t wifi_interface_t; + +#define WIFI_IF_STA CSI_IF_WIFI_STA +#define WIFI_IF_AP CSI_IF_WIFI_AP + +typedef enum { + WIFI_COUNTRY_CN = 0, /**< country China, channel range [1, 14] */ + WIFI_COUNTRY_JP, /**< country Japan, channel range [1, 14] */ + WIFI_COUNTRY_US, /**< country USA, channel range [1, 11] */ + WIFI_COUNTRY_EU, /**< country Europe, channel range [1, 13] */ + WIFI_COUNTRY_MAX +} wifi_country_t; + +typedef enum { + WIFI_AUTH_OPEN = 0, /**< authenticate mode : open */ + WIFI_AUTH_WEP, /**< authenticate mode : WEP */ + WIFI_AUTH_WPA_PSK, /**< authenticate mode : WPA_PSK */ + WIFI_AUTH_WPA2_PSK, /**< authenticate mode : WPA2_PSK */ + WIFI_AUTH_WPA_WPA2_PSK, /**< authenticate mode : WPA_WPA2_PSK */ + WIFI_AUTH_WPA2_ENTERPRISE, /**< authenticate mode : WPA2_ENTERPRISE */ + WIFI_AUTH_MAX +} wifi_auth_mode_t; + +enum { + WIFI_REASON_UNSPECIFIED = 1, + WIFI_REASON_AUTH_EXPIRE = 2, + WIFI_REASON_AUTH_LEAVE = 3, + WIFI_REASON_ASSOC_EXPIRE = 4, + WIFI_REASON_ASSOC_TOOMANY = 5, + WIFI_REASON_NOT_AUTHED = 6, + WIFI_REASON_NOT_ASSOCED = 7, + WIFI_REASON_ASSOC_LEAVE = 8, + WIFI_REASON_ASSOC_NOT_AUTHED = 9, + WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, + WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11, + WIFI_REASON_IE_INVALID = 13, + WIFI_REASON_MIC_FAILURE = 14, + WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, + WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, + WIFI_REASON_IE_IN_4WAY_DIFFERS = 17, + WIFI_REASON_GROUP_CIPHER_INVALID = 18, + WIFI_REASON_PAIRWISE_CIPHER_INVALID = 19, + WIFI_REASON_AKMP_INVALID = 20, + WIFI_REASON_UNSUPP_RSN_IE_VERSION = 21, + WIFI_REASON_INVALID_RSN_IE_CAP = 22, + WIFI_REASON_802_1X_AUTH_FAILED = 23, + WIFI_REASON_CIPHER_SUITE_REJECTED = 24, + + WIFI_REASON_BEACON_TIMEOUT = 200, + WIFI_REASON_NO_AP_FOUND = 201, + WIFI_REASON_AUTH_FAIL = 202, + WIFI_REASON_ASSOC_FAIL = 203, + WIFI_REASON_HANDSHAKE_TIMEOUT = 204, +}; + +typedef enum { + WIFI_SECOND_CHAN_NONE = 0, /**< the channel width is HT20 */ + WIFI_SECOND_CHAN_ABOVE, /**< the channel width is HT40 and the second channel is above the primary channel */ + WIFI_SECOND_CHAN_BELOW, /**< the channel width is HT40 and the second channel is below the primary channel */ +} wifi_second_chan_t; + +typedef enum { + WIFI_SCAN_TYPE_ACTIVE = 0, /**< active scan */ + WIFI_SCAN_TYPE_PASSIVE, /**< passive scan */ +} wifi_scan_type_t; + +typedef struct { + uint32_t min; /**< minimum active scan time per channel, units: millisecond */ + uint32_t max; /**< maximum active scan time per channel, units: millisecond, values above 1500ms may + cause station to disconnect from AP and are not recommended. */ +} wifi_active_scan_time_t; + +typedef union { + wifi_active_scan_time_t active; /**< active scan time per channel */ + uint32_t passive; /**< passive scan time per channel, units: millisecond, values above 1500ms may + cause station to disconnect from AP and are not recommended. */ +} wifi_scan_time_t; + +typedef struct { + uint8_t *ssid; /**< SSID of AP */ + uint8_t *bssid; /**< MAC address of AP */ + uint8_t channel; /**< channel, scan the specific channel */ + bool show_hidden; /**< enable to scan AP whose SSID is hidden */ + wifi_scan_type_t scan_type; /**< scan type, active or passive */ + wifi_scan_time_t scan_time; /**< scan time per channel */ +} wifi_scan_config_t; + +typedef struct { + uint8_t bssid[6]; /**< MAC address of AP */ + uint8_t ssid[32]; /**< SSID of AP */ + uint8_t primary; /**< channel of AP */ + wifi_second_chan_t second; /**< second channel of AP */ + int8_t rssi; /**< signal strength of AP */ + wifi_auth_mode_t authmode; /**< authmode of AP */ + uint32_t low_rate_enable:1; /**< bit: 0 flag to identify if low rate is enabled or not */ + uint32_t reserved:31; /**< bit: 1..31 reserved */ +} wifi_ap_record_t; + +typedef enum { + WIFI_PS_NONE, /**< No power save */ + WIFI_PS_MODEM, /**< Modem power save */ +} wifi_ps_type_t; + +#define WIFI_PROTOCOL_11B 1 +#define WIFI_PROTOCOL_11G 2 +#define WIFI_PROTOCOL_11N 4 +#define WIFI_PROTOCOL_LR 8 + +typedef enum { + WIFI_BW_HT20 = 1, /* Bandwidth is HT20 */ + WIFI_BW_HT40, /* Bandwidth is HT40 */ + WIFI_BW_HT20_HT40, +} wifi_bandwidth_t; + +typedef struct { + uint8_t ssid[32]; /**< SSID of soft-AP */ + uint8_t password[64]; /**< Password of soft-AP */ + uint8_t ssid_len; /**< Length of SSID. If softap_config.ssid_len==0, check the SSID until there is a termination character; otherwise, set the SSID length according to softap_config.ssid_len. */ + uint8_t channel; /**< Channel of soft-AP */ + wifi_auth_mode_t authmode; /**< Auth mode of soft-AP. Do not support AUTH_WEP in soft-AP mode */ + uint8_t ssid_hidden; /**< Broadcast SSID or not, default 0, broadcast the SSID */ + uint8_t max_connection; /**< Max number of stations allowed to connect in, default 4, max 4 */ + uint16_t beacon_interval; /**< Beacon interval, 100 ~ 60000 ms, default 100 ms */ +} wifi_ap_config_t; + +typedef struct { + uint8_t ssid[32]; /**< SSID of target AP*/ + uint8_t password[64]; /**< password of target AP*/ + bool bssid_set; /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/ + uint8_t bssid[6]; /**< MAC address of target AP*/ +} wifi_sta_config_t; + +typedef union { + wifi_ap_config_t ap; /**< configuration of AP */ + wifi_sta_config_t sta; /**< configuration of STA */ +} wifi_config_t; + +typedef struct { + uint8_t mac[6]; /**< mac address of sta that associated with soft-AP */ +} wifi_sta_info_t; + +#define CSI_WIFI_MAX_CONN_NUM (10) /**< max number of stations which can connect to soft-AP */ + +typedef struct { + wifi_sta_info_t sta[CSI_WIFI_MAX_CONN_NUM]; /**< station list */ + int num; /**< number of station that associated with soft-AP */ +} wifi_sta_list_t; + +typedef enum { + WIFI_STORAGE_FLASH, /**< all configuration will strore in both memory and flash */ + WIFI_STORAGE_RAM, /**< all configuration will only store in the memory */ +} wifi_storage_t; + +/** + * @brief Vendor IE type + * + */ +typedef enum { + WIFI_VND_IE_TYPE_BEACON, + WIFI_VND_IE_TYPE_PROBE_REQ, + WIFI_VND_IE_TYPE_PROBE_RCSI, + WIFI_VND_IE_TYPE_ASSOC_REQ, + WIFI_VND_IE_TYPE_ASSOC_RCSI, +} wifi_vendor_ie_type_t; + +/** + * @brief Vendor IE index + * + */ +typedef enum { + WIFI_VND_IE_ID_0, + WIFI_VND_IE_ID_1, +} wifi_vendor_ie_id_t; + +typedef struct { + signed rssi:8; /**< signal intensity of packet */ + unsigned rate:5; /**< data rate */ + unsigned :1; /**< reserve */ + unsigned sig_mode:2; /**< 0:is not 11n packet; 1:is 11n packet */ + unsigned :16; /**< reserve */ + unsigned mcs:7; /**< if is 11n packet, shows the modulation(range from 0 to 76) */ + unsigned cwb:1; /**< if is 11n packet, shows if is HT40 packet or not */ + unsigned :16; /**< reserve */ + unsigned smoothing:1; /**< reserve */ + unsigned not_sounding:1; /**< reserve */ + unsigned :1; /**< reserve */ + unsigned aggregation:1; /**< Aggregation */ + unsigned stbc:2; /**< STBC */ + unsigned fec_coding:1; /**< if is 11n packet, shows if is LDPC packet or not */ + unsigned sgi:1; /**< SGI */ + unsigned noise_floor:8; /**< noise floor */ + unsigned ampdu_cnt:8; /**< ampdu cnt */ + unsigned channel:4; /**< which channel this packet in */ + unsigned :12; /**< reserve */ + unsigned timestamp:32; /**< timestamp */ + unsigned :32; /**< reserve */ + unsigned :32; /**< reserve */ + unsigned sig_len:12; /**< It is really lenth of packet */ + unsigned :12; /**< reserve */ + unsigned rx_state:8; /**< rx state */ +} wifi_pkt_rx_ctrl_t; + +typedef struct { + wifi_pkt_rx_ctrl_t rx_ctrl; + uint8_t payload[0]; /**< ieee80211 packet buff, The length of payload is described by sig_len */ +} wifi_promiscuous_pkt_t; + +/** + * @brief Promiscuous frame type + * + */ +typedef enum { + WIFI_PKT_CTRL, /**< control type, receive packet buf is wifi_pkt_rx_ctrl_t */ + WIFI_PKT_MGMT, /**< management type, receive packet buf is wifi_promiscuous_pkt_t */ + WIFI_PKT_DATA, /**< data type, receive packet buf is wifi_promiscuous_pkt_t */ + WIFI_PKT_MISC, /**< other type, receive packet buf is wifi_promiscuous_pkt_t */ +} wifi_promiscuous_pkt_type_t; + +#define CSI_OK 0 +#define CSI_FAIL -1 + +#define CSI_ERR_NO_MEM 0x101 +#define CSI_ERR_INVALID_ARG 0x102 +#define CSI_ERR_INVALID_STATE 0x103 +#define CSI_ERR_INVALID_SIZE 0x104 +#define CSI_ERR_NOT_FOUND 0x105 +#define CSI_ERR_NOT_SUPPORTED 0x106 +#define CSI_ERR_TIMEOUT 0x107 +#define CSI_ERR_INVALID_RCSIONSE 0x108 +#define CSI_ERR_INVALID_CRC 0x109 + +//#define CSI_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */ + +#define CSI_ERR_WIFI_OK CSI_OK /*!< No error */ +#define CSI_ERR_WIFI_FAIL CSI_FAIL /*!< General fail code */ +#define CSI_ERR_WIFI_NO_MEM CSI_ERR_NO_MEM /*!< Out of memory */ +#define CSI_ERR_WIFI_ARG CSI_ERR_INVALID_ARG /*!< Invalid argument */ +#define CSI_ERR_WIFI_NOT_SUPPORT CSI_ERR_NOT_SUPPORTED /*!< Indicates that API is not supported yet */ + +#define CSI_ERR_WIFI_NOT_INIT (CSI_DRV_ERRNO_WIFI_BASE + 1) /*!< WiFi driver was not installed by csi_wifi_init */ +#define CSI_ERR_WIFI_NOT_STARTED (CSI_DRV_ERRNO_WIFI_BASE + 2) /*!< WiFi driver was not started by csi_wifi_start */ +#define CSI_ERR_WIFI_IF (CSI_DRV_ERRNO_WIFI_BASE + 3) /*!< WiFi interface error */ +#define CSI_ERR_WIFI_MODE (CSI_DRV_ERRNO_WIFI_BASE + 4) /*!< WiFi mode error */ +#define CSI_ERR_WIFI_STATE (CSI_DRV_ERRNO_WIFI_BASE + 5) /*!< WiFi internal state error */ +#define CSI_ERR_WIFI_CONN (CSI_DRV_ERRNO_WIFI_BASE + 6) /*!< WiFi internal control block of station or soft-AP error */ +#define CSI_ERR_WIFI_NVS (CSI_DRV_ERRNO_WIFI_BASE + 7) /*!< WiFi internal NVS module error */ +#define CSI_ERR_WIFI_MAC (CSI_DRV_ERRNO_WIFI_BASE + 8) /*!< MAC address is invalid */ +#define CSI_ERR_WIFI_SSID (CSI_DRV_ERRNO_WIFI_BASE + 9) /*!< SSID is invalid */ +#define CSI_ERR_WIFI_PASSWORD (CSI_DRV_ERRNO_WIFI_BASE + 10) /*!< Password is invalid */ +#define CSI_ERR_WIFI_TIMEOUT (CSI_DRV_ERRNO_WIFI_BASE + 11) /*!< Timeout error */ +#define CSI_ERR_WIFI_WAKE_FAIL (CSI_DRV_ERRNO_WIFI_BASE + 12) /*!< WiFi is in sleep state(RF closed) and wakeup fail */ + +typedef enum +{ + FRAME_FILTER_MODE_FORWARD = 1, /*!< Packet filter engine forwards matching packets, discards non-matching packets */ + FRAME_FILTER_MODE_DISCARD = 0, /*!< Packet filter engine discards matching packets, forwards non-matching packets */ +} frame_filter_mode_t; + +typedef enum +{ + FRAME_FILTER_RULE_POSITIVE_MATCHING = 0, /*!< Specifies that a filter should match a given pattern */ + FRAME_FILTER_RULE_NEGATIVE_MATCHING = 1, /*!< Specifies that a filter should NOT match a given pattern */ +} frame_filter_rule_t; + +/** + * Structure describing a frame filter list item + */ +typedef struct +{ + uint32_t id; /*!< Unique identifier for a packet filter item */ + frame_filter_rule_t rule; /*!< Filter matches are either POSITIVE or NEGATIVE matching */ + uint16_t offset; /*!< Offset in bytes to start filtering (referenced to the start of the ethernet packet) */ + uint16_t mask_size; /*!< Size of the mask in bytes */ + uint8_t* mask; /*!< Pattern mask bytes to be ANDed with the pattern eg. "\xff00" (must be in network byte order) */ + uint8_t* pattern; /*!< Pattern bytes used to filter eg. "\x0800" (must be in network byte order) */ + bool enabled_status; /*!< When returned from mhd_get_packet_filters, indicates if the filter is enabled */ +} wifi_frame_filter_t; + +struct wifi_frame_filter_list +{ + struct wifi_frame_filter_list* next; +}; +typedef struct wifi_frame_filter_list wifi_frame_filter_list_t; + +typedef void (*wifi_event_cb_t)(uint32_t event); ///< Signal WiFi Event. Events refer to wifi_event_id_t + +/** + * @brief Init WiFi + * Alloc resource for WiFi driver, such as WiFi control structure, RX/TX buffer, + * WiFi NVS structure etc, this WiFi also start WiFi task + * + * @attention 1. This API must be called before all other WiFi API can be called + * + * @param cb callback to handle WiFi event + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NO_MEM: out of memory + * - others: refer to error code csi_err.h + */ +int32_t csi_wifi_init(wifi_event_cb_t *cb); + +/** + * @brief Deinit WiFi + * Free all resource allocated in csi_wifi_init and stop WiFi task + * + * @attention 1. This API should be called if you want to remove WiFi driver from the system + * + * @return CSI_OK: succeed + */ +int32_t csi_wifi_deinit(void); + +/** + * @brief Set the WiFi operating mode + * + * Set the WiFi operating mode as station, soft-AP or station+soft-AP, + * The default mode is soft-AP mode. + * + * @param mode WiFi operating mode + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + * - others: refer to error code in csi_err.h + */ +int32_t csi_wifi_set_mode(wifi_mode_t mode); + +/** + * @brief Get current operating mode of WiFi + * + * @param[out] mode store current WiFi mode + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + */ +int32_t csi_wifi_get_mode(wifi_mode_t *mode); + +/** + * @brief Start WiFi according to current configuration + * If mode is WIFI_MODE_STA, it create station control block and start station + * If mode is WIFI_MODE_AP, it create soft-AP control block and start soft-AP + * If mode is WIFI_MODE_APSTA, it create soft-AP and station control block and start soft-AP and station + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + * - CSI_ERR_WIFI_NO_MEM: out of memory + * - CSI_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - CSI_ERR_WIFI_FAIL: other WiFi internal errors + */ +int32_t csi_wifi_start(void); + +/** + * @brief Stop WiFi + * If mode is WIFI_MODE_STA, it stop station and free station control block + * If mode is WIFI_MODE_AP, it stop soft-AP and free soft-AP control block + * If mode is WIFI_MODE_APSTA, it stop station/soft-AP and free station/soft-AP control block + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + */ +int32_t csi_wifi_stop(void); + +/** + * @brief Restore WiFi stack persistent settings to default values + * + * This function will reset settings made using the following APIs: + * - csi_wifi_get_auto_connect, + * - csi_wifi_set_protocol, + * - csi_wifi_set_config related + * - csi_wifi_set_mode + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + */ +int32_t csi_wifi_restore(void); + +/** + * @brief Connect the WiFi station to the AP. + * + * @attention 1. This API only impact WIFI_MODE_STA or WIFI_MODE_APSTA mode + * @attention 2. If connecting to an AP, call csi_wifi_disconnect to disconnect. + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_NOT_START: WiFi is not started by csi_wifi_start + * - CSI_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - CSI_ERR_WIFI_SSID: SSID of AP which station connects is invalid + */ +int32_t csi_wifi_connect(void); + +/** + * @brief Disconnect the WiFi station from the AP. + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi was not initialized by csi_wifi_init + * - CSI_ERR_WIFI_NOT_STARTED: WiFi was not started by csi_wifi_start + * - CSI_ERR_WIFI_FAIL: other WiFi internal errors + */ +int32_t csi_wifi_disconnect(void); + +/** + * @brief deauthenticate all stations or associated id equals to aid + * + * @param aid when aid is 0, deauthenticate all stations, otherwise deauthenticate station whose associated id is aid + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_NOT_STARTED: WiFi was not started by csi_wifi_start + * - CSI_ERR_WIFI_ARG: invalid argument + * - CSI_ERR_WIFI_MODE: WiFi mode is wrong + */ +int32_t csi_wifi_deauth_sta(uint16_t aid); + +/** + * @brief Scan all available APs. + * + * @attention If this API is called, the found APs are stored in WiFi driver dynamic allocated memory and that + * will be freed in csi_wifi_get_ap_list, so generally, call csi_wifi_get_ap_list to cause + * the memory to be freed once the scan is done + * @attention The values of maximum active scan time and passive scan time per channel are limited to 1500 milliseconds. + * Values above 1500ms may cause station to disconnect from AP and are not recommended. + * + * @param config configuration of scanning + * @param block if block is true, this API will block the caller until the scan is done, otherwise + * it will return immediately + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_NOT_STARTED: WiFi was not started by csi_wifi_start + * - CSI_ERR_WIFI_TIMEOUT: blocking scan is timeout + * - others: refer to error code in csi_err.h + */ +int32_t csi_wifi_scan_start(wifi_scan_config_t *config, bool block); + +/** + * @brief Stop the scan in process + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_NOT_STARTED: WiFi is not started by csi_wifi_start + */ +int32_t csi_wifi_scan_stop(void); + +/** + * @brief Get AP list found in last scan + * + * @param[inout] number As input param, it stores max AP number ap_records can hold. + * As output param, it receives the actual AP number this API returns. + * @param ap_records wifi_ap_record_t array to hold the found APs + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_NOT_STARTED: WiFi is not started by csi_wifi_start + * - CSI_ERR_WIFI_ARG: invalid argument + * - CSI_ERR_WIFI_NO_MEM: out of memory + */ +int32_t csi_wifi_scan_get_ap_records(uint16_t *number, wifi_ap_record_t *ap_records); + + +/** + * @brief Get information of AP which station is associated with + * + * @param ap_info the wifi_ap_record_t to hold AP information + * + * @return + * - CSI_OK: succeed + * - others: fail + */ +int32_t csi_wifi_sta_get_ap_info(wifi_ap_record_t *ap_info); + +/** + * @brief Set current power save type + * + * @attention Default power save type is WIFI_PS_NONE. + * + * @param type power save type + * + * @return CSI_ERR_WIFI_NOT_SUPPORT: not supported yet + */ +int32_t csi_wifi_set_ps(wifi_ps_type_t type); + +/** + * @brief Get current power save type + * + * @attention Default power save type is WIFI_PS_NONE. + * + * @param[out] type: store current power save type + * + * @return CSI_ERR_WIFI_NOT_SUPPORT: not supported yet + */ +int32_t csi_wifi_get_ps(wifi_ps_type_t *type); + +/** + * @brief Set protocol type of specified interface + * The default protocol is (WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N) + * + * @attention Currently we only support 802.11b or 802.11bg or 802.11bgn mode + * + * @param ifx interfaces + * @param protocol_bitmap WiFi protocol bitmap + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_IF: invalid interface + * - others: refer to error codes in csi_err.h + */ +int32_t csi_wifi_set_protocol(wifi_interface_t ifx, uint8_t protocol_bitmap); + +/** + * @brief Get the current protocol bitmap of the specified interface + * + * @param ifx interface + * @param[out] protocol_bitmap store current WiFi protocol bitmap of interface ifx + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_IF: invalid interface + * - CSI_ERR_WIFI_ARG: invalid argument + * - others: refer to error codes in csi_err.h + */ +int32_t csi_wifi_get_protocol(wifi_interface_t ifx, uint8_t *protocol_bitmap); + +/** + * @brief Set the bandwidth of specified interface + * + * @attention 1. API return false if try to configure an interface that is not enabled + * @attention 2. WIFI_BW_HT40 is supported only when the interface support 11N + * + * @param ifx interface to be configured + * @param bw bandwidth + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_IF: invalid interface + * - CSI_ERR_WIFI_ARG: invalid argument + * - others: refer to error codes in csi_err.h + */ +int32_t csi_wifi_set_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t bw); + +/** + * @brief Get the bandwidth of specified interface + * + * @attention 1. API return false if try to get a interface that is not enable + * + * @param ifx interface to be configured + * @param[out] bw store bandwidth of interface ifx + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_IF: invalid interface + * - CSI_ERR_WIFI_ARG: invalid argument + */ +int32_t csi_wifi_get_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t *bw); + +/** + * @brief Set primary/secondary channel + * + * @attention 1. This is a special API for sniffer + * @attention 2. This API should be called after csi_wifi_start() or csi_wifi_set_promiscuous() + * + * @param primary for HT20, primary is the channel number, for HT40, primary is the primary channel + * @param second for HT20, second is ignored, for HT40, second is the second channel + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_IF: invalid interface + * - CSI_ERR_WIFI_ARG: invalid argument + */ +int32_t csi_wifi_set_channel(uint8_t primary, wifi_second_chan_t second); + +/** + * @brief Get the primary/secondary channel + * + * @attention 1. API return false if try to get a interface that is not enable + * + * @param[out] primary store current primary channel + * @param[out] second store current second channel + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + */ +int32_t csi_wifi_get_channel(uint8_t *primary, wifi_second_chan_t *second); + +/** + * @brief Set country code + * The default value is WIFI_COUNTRY_CN + * + * @param country country type + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + * - others: refer to error code in csi_err.h + */ +int32_t csi_wifi_set_country(wifi_country_t country); + +/** + * @brief Get country code + * + * @param country store current country + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + */ +int32_t csi_wifi_get_country(wifi_country_t *country); + +/** + * @brief Set MAC address of the WiFi station or the soft-AP interface. + * + * @attention 1. This API can only be called when the interface is disabled + * @attention 2. soft-AP and station have different MAC addresses, do not set them to be the same. + * @attention 3. The bit 0 of the first byte of MAC address can not be 1. For example, the MAC address + * can set to be "1a:XX:XX:XX:XX:XX", but can not be "15:XX:XX:XX:XX:XX". + * + * @param ifx interface + * @param mac the MAC address + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + * - CSI_ERR_WIFI_IF: invalid interface + * - CSI_ERR_WIFI_MAC: invalid mac address + * - CSI_ERR_WIFI_MODE: WiFi mode is wrong + * - others: refer to error codes in csi_err.h + */ +int32_t csi_wifi_set_mac(wifi_interface_t ifx, uint8_t mac[6]); + +/** + * @brief Get mac of specified interface + * + * @param ifx interface + * @param[out] mac store mac of the interface ifx + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + * - CSI_ERR_WIFI_IF: invalid interface + */ +int32_t csi_wifi_get_mac(wifi_interface_t ifx, uint8_t mac[6]); + +/** + * @brief The RX callback function in the promiscuous mode. + * Each time a packet is received, the callback function will be called. + * + * @param buf Data received. Type of data in buffer (wifi_promiscuous_pkt_t or wifi_pkt_rx_ctrl_t) indicated by 'type' parameter. + * @param type promiscuous packet type. + * + */ +typedef void (* wifi_promiscuous_cb_t)(void *buf, wifi_promiscuous_pkt_type_t type); + +/** + * @brief Register the RX callback function in the promiscuous mode. + * + * Each time a packet is received, the registered callback function will be called. + * + * @param cb callback + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + */ +int32_t csi_wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb); + +/** + * @brief Enable the promiscuous mode. + * + * @param en false - disable, true - enable + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + */ +int32_t csi_wifi_set_promiscuous(bool en); + +/** + * @brief Get the promiscuous mode. + * + * @param[out] en store the current status of promiscuous mode + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + */ +int32_t csi_wifi_get_promiscuous(bool *en); + +/** + * @brief Set the configuration of STA or AP + * + * @attention 1. This API can be called only when specified interface is enabled, otherwise, API fail + * @attention 2. For station configuration, bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP. + * @attention 3. Limited to only one channel, so when in the soft-AP+station mode, the soft-AP will adjust its channel automatically to be the same as + * the channel of the station. + * + * @param ifx interface + * @param conf station or soft-AP configuration + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + * - CSI_ERR_WIFI_IF: invalid interface + * - CSI_ERR_WIFI_MODE: invalid mode + * - CSI_ERR_WIFI_PASSWORD: invalid password + * - CSI_ERR_WIFI_NVS: WiFi internal NVS error + * - others: refer to the erro code in csi_err.h + */ +int32_t csi_wifi_set_config(wifi_interface_t ifx, wifi_config_t *conf); + +/** + * @brief Get configuration of specified interface + * + * @param ifx interface + * @param[out] conf station or soft-AP configuration + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + * - CSI_ERR_WIFI_IF: invalid interface + */ +int32_t csi_wifi_get_config(wifi_interface_t ifx, wifi_config_t *conf); + +/** + * @brief Get STAs associated with soft-AP + * + * @attention SSC only API + * + * @param[out] sta station list + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + * - CSI_ERR_WIFI_MODE: WiFi mode is wrong + * - CSI_ERR_WIFI_CONN: WiFi internal error, the station/soft-AP control block is invalid + */ +int32_t csi_wifi_ap_get_sta_list(wifi_sta_list_t *sta); + + +/** + * @brief Set the WiFi API configuration storage type + * + * @attention 1. The default value is WIFI_STORAGE_FLASH + * + * @param storage : storage type + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + */ +int32_t csi_wifi_set_storage(wifi_storage_t storage); + +/** + * @brief Set auto connect + * The default value is true + * + * @param en : true - enable auto connect / false - disable auto connect + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_MODE: WiFi internal error, the station/soft-AP control block is invalid + * - others: refer to error code in csi_err.h + */ +int32_t csi_wifi_set_auto_connect(bool en); + +/** + * @brief Get the auto connect flag + * + * @param[out] en store current auto connect configuration + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + */ +int32_t csi_wifi_get_auto_connect(bool *en); + +/** + * @brief Set vendor specific element + * + * @param enable enable or not + * @param type information element type + * @param idx information element index + * @param vnd_ie pointer to a vendor specific element + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + * - CSI_ERR_WIFI_ARG: invalid argument + * - CSI_ERR_WIFI_NO_MEM: out of memory + */ +int32_t csi_wifi_set_vendor_ie(bool enable, wifi_vendor_ie_type_t type, wifi_vendor_ie_id_t idx, uint8_t *vnd_ie); + +/** + * @brief Define function pointer for vendor specific element callback + * @param ctx reserved + * @param type information element type + * @param sa source address + * @param vnd_ie pointer to a vendor specific element + * @param rssi received signal strength indication + */ +typedef void (*csi_vendor_ie_cb_t) (void *ctx, wifi_vendor_ie_type_t type, const uint8_t sa[6], const uint8_t *vnd_ie, int rssi); + +/** + * @brief Set vendor specific element callback + * + * @param cb callback function + * @param ctx reserved + * + * @return + * - CSI_OK: succeed + * - CSI_ERR_WIFI_NOT_INIT: WiFi is not initialized by csi_wifi_init + */ +int32_t csi_wifi_set_vendor_ie_cb(csi_vendor_ie_cb_t cb, void *ctx); + +/** + * @brief get whether the wifi driver is allowed to transmit data or not + * + * @return + * - true : upper layer should stop to transmit data to wifi driver + * - false : upper layer can transmit data to wifi driver + */ +bool csi_wifi_tx_is_stop(void); + +/** + * @brief free the rx buffer which allocated by wifi driver + * + * @param buffer: rx buffer pointer + */ +void csi_wifi_free_rx_buffer(void *buffer); + +/** + * @brief transmit the buffer via wifi driver + * + * @param wifi_if : wifi interface id + * @param buffer : the buffer to be tansmit + * @param len : the length of buffer + * + * @return + * - ERR_OK : Successfully transmit the buffer to wifi driver + * - ERR_MEM : Out of memory + * - ERR_IF : WiFi driver error + * - ERR_ARG : Invalid argument + */ +int csi_wifi_tx(wifi_interface_t wifi_if, void *buffer, uint16_t len); + +/** + * @brief The WiFi RX callback function + * + * Each time the WiFi need to forward the packets to high layer, the callback function will be called. + * ebuf is rx buffer allocated by wifi driver + */ +typedef int32_t (*wifi_rxcb_t)(void *buffer, uint16_t len, void *ebuf); + +/** + * @brief Set the WiFi RX callback + * + * @attention 1. Currently we support only one RX callback for each interface + * + * @param ifx : interface + * @param fn : WiFi RX callback + * + * @return + * - CSI_OK : succeed + * - others : fail + */ +int32_t csi_wifi_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn); + +/** + \brief Add Frame Filter Setting with Filter ID. + \param[in] filter Pointer to filter setting + \return +*/ +int32_t csi_wifi_add_framefilter(const wifi_frame_filter_t *filter); + +/** + \brief Remove Frame Filter Setting. + \param[in] filter_id Frame Filter ID + \return +*/ +int32_t csi_wifi_remove_framefilter(uint32_t filter_id); + +/** + \brief Enable/Disable Specified Frame Filter ID. + \param[in] filter_id Frame Filter ID + \param[in] en Enable or disable + \return +*/ +int32_t csi_wifi_en_framefilter(uint32_t filter_id, bool en); + +/** + \brief Get frame filter table list. + \param[in] list frame filter table list + \param[in] count_out the count of filter setting added + \param[in] max_count max filter setting can be supported + \return +*/ +int32_t csi_wifi_get_framefilter(wifi_frame_filter_list_t* list, uint32_t* count_out, uint32_t max_count); + +/** +* @brief This function gets the radio status of the Wi-Fi driver. +* +* @param[out] on_off indicates the Wi-Fi radio is on or off. +* +* Value |Definition | +* ------------------------------|------------------------------------------------------------------------| +* \b 0 | OFF, the Wi-Fi radio is turned off, and Wi-Fi TX/RX is disabled.| +* \b 1 | ON, the Wi-Fi radio is turned on, and Wi-Fi TX/RX is enabled.| +* +* +* @return >=0 the operation completed successfully, <0 the operation failed. +* +* @note In repeater mode, both Wi-Fi interface and Wi-Fi radio are turned on/off at the same time. +*/ +int32_t wifi_config_get_radio(uint8_t *on_off); + +/** +* @brief This function sets the radio status of the Wi-Fi driver. This operation takes effect immediately. +* +* @param[in] on_off indicates the Wi-Fi radio is on or off. +* +* Value |Definition | +* ------------------------------|------------------------------------------------------------------------| +* \b 0 | OFF, the Wi-Fi radio is turned off, and Wi-Fi TX/RX is disabled| +* \b 1 | ON, the Wi-Fi radio is turned on, and Wi-Fi TX/RX is enabled| +* +* @return >=0 the operation completed successfully, <0 the operation failed. +* +* @note In repeater mode, both Wi-Fi interface and Wi-Fi radio are turned on/off at the same time. +*/ +int32_t wifi_config_set_radio(uint8_t on_off); + +/** +* @brief This function gets the RSSI of the connected AP. It's only used for the STA mode and while the station is connected to the AP. +* +* @param[out] rssi returns the RSSI of the connected AP. +* +* @return >=0 the operation completed successfully, <0 the operation failed. +* +* +*/ +int32_t csi_wifi_connection_get_rssi(int8_t *rssi); + + +#ifdef __cplusplus +} +#endif + +#endif /* __CSI_WIFI_H__ */ + + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_wifi_wps.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_wifi_wps.h new file mode 100644 index 000000000..9cb9c9dec --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/drv_wifi_wps.h @@ -0,0 +1,101 @@ +/** + * Copyright (C) 2016 CSI Project. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CSI_WIFI_WPS_H__ +#define __CSI_WIFI_WPS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WPS_APIs WPS APIs + * @brief WPS APIs + * + * WPS can only be used when station is enabled. + * + */ + +/** @addtogroup WPS_APIs + * @{ + */ + +#define CSI_ERR_WIFI_REGISTRAR (CSI_DRV_ERRNO_WIFI_BASE + 51) /*!< WPS registrar is not supported */ +#define CSI_ERR_WIFI_WPS_TYPE (CSI_DRV_ERRNO_WIFI_BASE + 52) /*!< WPS type error */ +#define CSI_ERR_WIFI_WPS_SM (CSI_DRV_ERRNO_WIFI_BASE + 53) /*!< WPS state machine is not initialized */ + +typedef enum wps_type { + WPS_TYPE_DISABLE = 0, + WPS_TYPE_PBC, + WPS_TYPE_PIN, + WPS_TYPE_MAX, +} wps_type_t; + +/** + * @brief Enable Wi-Fi WPS function. + * + * @attention WPS can only be used when station is enabled. + * + * @param wps_type : WPS type, so far only WPS_TYPE_PBC and WPS_TYPE_PIN is supported + * + * @return + * - CSI_OK : succeed + * - CSI_ERR_WIFI_WPS_TYPE : wps type is invalid + * - CSI_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - CSI_ERR_WIFI_FAIL : wps initialization fails + */ +int32_t csi_wifi_wps_enable(wps_type_t wps_type); + +/** + * @brief Disable Wi-Fi WPS function and release resource it taken. + * + * @return + * - CSI_OK : succeed + * - CSI_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + */ +int32_t csi_wifi_wps_disable(void); + +/** + * @brief WPS starts to work. + * + * @attention WPS can only be used when station is enabled. + * + * @param timeout_ms : maximum blocking time before API return. + * - 0 : non-blocking + * - 1~120000 : blocking time + * + * @return + * - CSI_OK : succeed + * - CSI_ERR_WIFI_WPS_TYPE : wps type is invalid + * - CSI_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - CSI_ERR_WIFI_WPS_SM : wps state machine is not initialized + * - CSI_ERR_WIFI_FAIL : wps initialization fails + */ +int32_t csi_wifi_wps_start(int timeout_ms); + +#ifdef __cplusplus +} +#endif + +#endif /* __CSI_WIFI_H__ */ + diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/system.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/system.c new file mode 100644 index 000000000..34433eea6 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/include/system.c @@ -0,0 +1,33 @@ +#include +#include +#include + +extern void CORET_IRQHandler(void); +extern void Default_handler(void); +extern void console_init(); +void (*g_irqvector[32])(void); + +void irq_vectors_init(void) +{ + int i; + + for (i = 0; i < 32; i++) { + g_irqvector[i] = Default_handler; + } + + g_irqvector[CORET_IRQn] = CORET_IRQHandler; +} + + +#define CONFIG_SYSTICK_HZ 100 +#define CONFIG_SYSTEM_FREQ 24000000 + +void SystemInit(void) +{ + irq_vectors_init(); + drv_coret_config(CONFIG_SYSTEM_FREQ / CONFIG_SYSTICK_HZ, CORET_IRQn); //10ms + drv_nvic_enable_irq(CORET_IRQn); + + console_init(); + return; +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/driver/uart.c b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/driver/uart.c new file mode 100644 index 000000000..60ac671c9 --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/driver/uart.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include "soc.h" +#include "pin_name.h" +#include "drv_usart.h" +#include "ck_sys_freq.h" + +#define CONSOLE_TXD PA10_ADC2_TXD0 +#define CONSOLE_RXD PA11_ACMP0N_ADC3_RXD0 +static usart_handle_t console_handle = NULL; +extern int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch); + +int putchar(int ch) +{ + if (ch == '\n') { + csi_usart_putchar(console_handle, '\r'); + } + + csi_usart_putchar(console_handle, ch); + + return 0; +} + +int fputc(int ch, FILE *fp) +{ + if (ch == '\n') { + csi_usart_putchar(console_handle, '\r'); + } + + csi_usart_putchar(console_handle, ch); + + return 0; +} + + +void usart_event_cb(usart_event_e event, void *cb_arg) +{ + //do nothing +} + +void console_init() +{ + int ret; + + console_handle = csi_usart_initialize(CONSOLE_TXD, CONSOLE_RXD, usart_event_cb, 0); + + if (!console_handle) { + return; + } + + ret = csi_usart_config(console_handle, + SYSTEM_CLOCK, + 115200, + USART_MODE_ASYNCHRONOUS, + USART_PARITY_NONE, + USART_STOP_BITS_1, + USART_DATA_BITS_8); + + if (ret < 0) { + return; + } +} + +void console_init_ree(uint32_t sysclk) +{ + int ret; + + + console_handle = csi_usart_initialize(CONSOLE_TXD, CONSOLE_RXD, usart_event_cb, 0); + + if (!console_handle) { + return; + } + + ret = csi_usart_config(console_handle, + sysclk, + 115200, + USART_MODE_ASYNCHRONOUS, + USART_PARITY_NONE, + USART_STOP_BITS_1, + USART_DATA_BITS_8); + + if (ret < 0) { + return; + } +} diff --git a/FreeRTOS/Demo/T-HEAD_CB2201_CDK/driver/uart.h b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/driver/uart.h new file mode 100644 index 000000000..42105056a --- /dev/null +++ b/FreeRTOS/Demo/T-HEAD_CB2201_CDK/driver/uart.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UART_H +#define UART_H +void console_init(void); +#endif diff --git a/FreeRTOS/Source/portable/ThirdParty/CDK/T-HEAD_CK802/port.c b/FreeRTOS/Source/portable/ThirdParty/CDK/T-HEAD_CK802/port.c new file mode 100644 index 000000000..db8d50f7a --- /dev/null +++ b/FreeRTOS/Source/portable/ThirdParty/CDK/T-HEAD_CK802/port.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. 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. + * + * 1 tab == 4 spaces! + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" + +extern void vPortStartTask(void); + +/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This +will be set to 0 prior to the first task being started. */ +portLONG ulCriticalNesting = 0x9999UL; + +/* Used to record one tack want to swtich task after enter critical area, we need know it + * and implement task switch after exit critical area */ +portLONG pendsvflag = 0; + +StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + StackType_t *stk = NULL; + + stk = pxTopOfStack; + + *(--stk) = (uint32_t)pxCode; /* Entry Point */ + *(--stk) = (uint32_t)0xE0000140L; /* PSR */ + *(--stk) = (uint32_t)0xFFFFFFFEL; /* R15 (LR) (init value will cause fault if ever used) */ + *(--stk) = (uint32_t)0x13131313L; /* R13 */ + *(--stk) = (uint32_t)0x12121212L; /* R12 */ + *(--stk) = (uint32_t)0x11111111L; /* R11 */ + *(--stk) = (uint32_t)0x10101010L; /* R10 */ + *(--stk) = (uint32_t)0x09090909L; /* R9 */ + *(--stk) = (uint32_t)0x08080808L; /* R8 */ + *(--stk) = (uint32_t)0x07070707L; /* R7 */ + *(--stk) = (uint32_t)0x06060606L; /* R6 */ + *(--stk) = (uint32_t)0x05050505L; /* R5 */ + *(--stk) = (uint32_t)0x04040404L; /* R4 */ + *(--stk) = (uint32_t)0x03030303L; /* R3 */ + *(--stk) = (uint32_t)0x02020202L; /* R2 */ + *(--stk) = (uint32_t)0x01010101L; /* R1 */ + *(--stk) = (uint32_t)pvParameters; /* R0 : argument */ + + return stk; +} + +BaseType_t xPortStartScheduler( void ) +{ + ulCriticalNesting = 0UL; + + vPortStartTask(); + + return pdFALSE; +} + + +void vPortEndScheduler( void ) +{ + /* Not implemented as there is nothing to return to. */ +} + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + ulCriticalNesting ++; +} + +void vPortExitCritical( void ) +{ + if (ulCriticalNesting == 0) { + while(1); + } + + ulCriticalNesting --; + if (ulCriticalNesting == 0) + { + portENABLE_INTERRUPTS(); + + if (pendsvflag) + { + pendsvflag = 0; + portYIELD(); + } + } +} + +#if configUSE_PREEMPTION == 0 +void xPortSysTickHandler( void ) +{ + portLONG ulDummy; + + ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); + xTaskIncrementTick(); + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); +} + +#else +void xPortSysTickHandler( void ) +{ + portLONG ulDummy; + + ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if (xTaskIncrementTick() != pdFALSE) + { + portYIELD_FROM_ISR(pdTRUE); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); +} +#endif + +void vPortYieldHandler( void ) +{ + uint32_t ulSavedInterruptMask; + + ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR(); + + vTaskSwitchContext(); + + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask ); +} + +__attribute__((weak)) void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName ) +{ + for(;;); +} + +__attribute__((weak)) void vApplicationMallocFailedHook( void ) +{ + for(;;); +} diff --git a/FreeRTOS/Source/portable/ThirdParty/CDK/T-HEAD_CK802/portasm.S b/FreeRTOS/Source/portable/ThirdParty/CDK/T-HEAD_CK802/portasm.S new file mode 100644 index 000000000..693ec641d --- /dev/null +++ b/FreeRTOS/Source/portable/ThirdParty/CDK/T-HEAD_CK802/portasm.S @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. 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. + * + * 1 tab == 4 spaces! + */ + +//#include + +/******************************************************************** + * Functions: vPortStartTask + * + ********************************************************************/ +.global vPortStartTask +.type vPortStartTask, %function +vPortStartTask: + psrclr ie + lrw r4, pxCurrentTCB + ld.w r4, (r4) // the current task stack pointer is the first member + ld.w sp, (r4) + + ldw r0, (sp, 64) + mtcr r0, epc + ldw r0, (sp, 60) + mtcr r0, epsr + ldw r15, (sp, 56) + ldm r0-r13, (sp) + addi sp, 68 + rte + +/******************************************************************** + * Functions: vPortYield + * + ********************************************************************/ +.global vPortYield +.type vPortYield, %function +vPortYield: + psrclr ee + subi sp, 68 + stm r0-r13, (sp) + stw r15, (sp, 56) + mfcr r0, psr + bseti r0, 8 + stw r0, (sp, 60) + stw r15, (sp, 64) + + lrw r2, pxCurrentTCB + ld.w r3, (r2) + st.w sp, (r3) + + jbsr vTaskSwitchContext + lrw r4, pxCurrentTCB + ld.w r4, (r4) + ld.w sp, (r4) + + ldw r0, (sp, 64) + mtcr r0, epc + ldw r0, (sp, 60) + mtcr r0, epsr + ldw r15, (sp, 56) + ldm r0-r13, (sp) + addi sp, 68 + + rte + +/******************************************************************** + * Functions: NOVIC_IRQ_Default_Handler + * + ********************************************************************/ +.global NOVIC_IRQ_Default_Handler +.type NOVIC_IRQ_Default_Handler, %function +NOVIC_IRQ_Default_Handler: + psrset ee + subi sp, 68 + stm r0-r13, (sp) + stw r15, (sp, 56) + mfcr r0, epsr + stw r0, (sp, 60) + mfcr r0, epc + stw r0, (sp, 64) + + lrw r7, pxCurrentTCB + ldw r7, (r7) + stw sp, (r7) + + lrw sp, g_top_irqstack + + lrw r1, g_irqvector + mfcr r0, psr + lsri r0, 16 + sextb r0 + subi r0, 32 + lsli r0, 2 + add r1, r0 + ldw r1, (r1) + lsri r0, 2 + jsr r1 + + lrw r7, pxCurrentTCB + ldw r7, (r7) + ldw sp, (r7) + + ldw r0, (sp, 64) + mtcr r0, epc + ldw r0, (sp, 60) + mtcr r0, epsr + ldm r0-r13, (sp) + ldw r15, (sp, 56) + addi sp, 68 + rte diff --git a/FreeRTOS/Source/portable/ThirdParty/CDK/T-HEAD_CK802/portmacro.h b/FreeRTOS/Source/portable/ThirdParty/CDK/T-HEAD_CK802/portmacro.h new file mode 100644 index 000000000..6db37cc54 --- /dev/null +++ b/FreeRTOS/Source/portable/ThirdParty/CDK/T-HEAD_CK802/portmacro.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. 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. + * + * 1 tab == 4 spaces! + */ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#include +#include +#include + +extern void vPortYield(void); +#ifdef __cplusplus +class vPortYield; +extern "C" { +#endif + + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; +typedef void (*portvectorfunc)(void); + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#endif + + +/* Hardware specifics. */ +#define portBYTE_ALIGNMENT 8 +#define portSTACK_GROWTH -1 +#define portMS_PERIOD_TICK 10 +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) + + +static inline void vPortEnableInterrupt( void ) +{ + __enable_irq(); +} + +static inline void vPortDisableInterrupt( void ) +{ + __disable_irq(); +} + +static inline portLONG GetCurrentPSR (void) +{ + return __get_PSR(); +} + +static inline portLONG SaveLocalPSR (void) +{ + portLONG flags = __get_PSR(); + __disable_irq(); + return flags; +} + +static inline void RestoreLocalPSR (portLONG newMask) +{ + __asm__ __volatile__( + "mtcr %0, psr \n" + : + :"r" (newMask) + :"memory" + ); +} + +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern __attribute__((naked)) void cpu_yeild(void); + +#define portDISABLE_INTERRUPTS() vPortDisableInterrupt() +#define portENABLE_INTERRUPTS() vPortEnableInterrupt() +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +#define portSET_INTERRUPT_MASK_FROM_ISR() SaveLocalPSR() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(a) RestoreLocalPSR(a) + +#define portNOP() asm("nop") + +extern portLONG ulCriticalNesting; +extern portLONG pendsvflag; + +#define portYIELD() if (ulCriticalNesting == 0) \ + { \ + vPortYield(); \ + } \ + else \ + { \ + pendsvflag = 1; \ + } \ + portNOP();portNOP() + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn)) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +#define portEND_SWITCHING_ISR( xSwitchRequired ) do { \ + if( xSwitchRequired != pdFALSE ) \ + { \ + portYIELD(); \ + } \ + }while(0) + +#define portYIELD_FROM_ISR( a ) vTaskSwitchContext() + + + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ +