Introduce a port for T-HEAD CK802. A simple demo for T-HEAD CB2201 is also included.

This commit is contained in:
Yuhui.Zheng 2020-01-10 07:53:14 +00:00
parent d2914041f8
commit 0d95aca202
125 changed files with 23809 additions and 0 deletions

View file

@ -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 */

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace>
<FindInFilesMask>
<![CDATA[*]]>
</FindInFilesMask>
</Workspace>

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<Session Name="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\RTOSDemo_CDK\RTOSDemo_CDK.cdkws">
<int Value="4" Name="m_selectedTab"/>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\RTOSDemo_CDK\RTOSDemo_CDK.cdkws" Name="m_workspaceName"/>
<TabInfoArray Name="TabInfoArray">
<TabInfo>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\RTOSDemo_CDK\RTOSDemo\main.c" Name="FileName"/>
<int Value="109" Name="FirstVisibleLine"/>
<int Value="117" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
<TabInfo>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\csi\csi_driver\include\system.c" Name="FileName"/>
<int Value="0" Name="FirstVisibleLine"/>
<int Value="3" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
<TabInfo>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Source\portable\CDK\T-HEAD_CK802\port.c" Name="FileName"/>
<int Value="14" Name="FirstVisibleLine"/>
<int Value="25" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
<TabInfo>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Source\portable\CDK\T-HEAD_CK802\portmacro.h" Name="FileName"/>
<int Value="25" Name="FirstVisibleLine"/>
<int Value="35" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
<TabInfo>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\FreeRTOSConfig.h" Name="FileName"/>
<int Value="27" Name="FirstVisibleLine"/>
<int Value="49" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
</TabInfoArray>
<SerializedObject Name="m_breakpoints">
<long Value="0" Name="Count"/>
</SerializedObject>
</Session>

View file

@ -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

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Session Name="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\RTOSDemo_CDK\RTOSDemo\RTOSDemo.cdkws">
<int Value="1" Name="m_selectedTab"/>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\RTOSDemo_CDK\RTOSDemo\RTOSDemo.cdkws" Name="m_workspaceName"/>
<TabInfoArray Name="TabInfoArray">
<TabInfo>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\RTOSDemo_CDK\RTOSDemo\gdb.init" Name="FileName"/>
<int Value="0" Name="FirstVisibleLine"/>
<int Value="0" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
<TabInfo>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\RTOSDemo_CDK\RTOSDemo\main.c" Name="FileName"/>
<int Value="15" Name="FirstVisibleLine"/>
<int Value="29" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
<TabInfo>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\driver\uart.c" Name="FileName"/>
<int Value="0" Name="FirstVisibleLine"/>
<int Value="19" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
<TabInfo>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\csi\csi_driver\csky\hobbit1_2\devices.c" Name="FileName"/>
<int Value="6" Name="FirstVisibleLine"/>
<int Value="22" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
<TabInfo>
<wxString Value="d:\ubuntu-share\freertos\demo\t-head_cb2201_cdk\csi\csi_driver\include\config.h" Name="FileName"/>
<int Value="3" Name="FirstVisibleLine"/>
<int Value="19" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
<TabInfo>
<wxString Value="D:\Ubuntu-Share\FreeRTOS\Demo\T-HEAD_CB2201_CDK\RTOSDemo_CDK\RTOSDemo\chip_name.h" Name="FileName"/>
<int Value="21" Name="FirstVisibleLine"/>
<int Value="37" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
<TabInfo>
<wxString Value="d:\ubuntu-share\freertos\demo\t-head_cb2201_cdk\csi\csi_core\ck802\core_ck802.h" Name="FileName"/>
<int Value="44" Name="FirstVisibleLine"/>
<int Value="68" Name="CurrentLine"/>
<wxArrayString Name="Bookmarks"/>
<IntVector Name="CollapsedFolds"/>
</TabInfo>
</TabInfoArray>
<SerializedObject Name="m_breakpoints">
<long Value="0" Name="Count"/>
</SerializedObject>
</Session>

View file

@ -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

View file

@ -0,0 +1,381 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project Name="RTOSDemo" Version="1" Language="C">
<Description/>
<Dependencies Name="Debug"/>
<VirtualDirectory Name="arch">
<File Name="crt0.S">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="inc">
<File Name="../../FreeRTOSConfig.h">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="script">
<File Name="ckcpu.ld">
<FileOption/>
</File>
<File Name="gdb.init">
<FileOption/>
</File>
<File Name="flash.init">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="src">
<File Name="main.c">
<FileOption/>
</File>
<File Name="../../driver/uart.c">
<FileOption/>
</File>
<File Name="../../Readme.txt">
<FileOption/>
</File>
</VirtualDirectory>
<MonitorProgress>
<FlashOperate>37</FlashOperate>
<DebugLaunch>47</DebugLaunch>
</MonitorProgress>
<VirtualDirectory Name="csi">
<File Name="../../csi/csi_driver/include/drv_usart.h">
<FileOption/>
</File>
<File Name="../../csi/csi_driver/csky/hobbit1_2/devices.c">
<FileOption/>
</File>
<File Name="../../csi/csi_driver/csky/hobbit1_2/isr.c">
<FileOption/>
</File>
<File Name="../../csi/csi_driver/csky/hobbit1_2/pinmux.c">
<FileOption/>
</File>
<File Name="../../csi/csi_driver/csky/hobbit1_2/include/pin_name.h">
<FileOption/>
</File>
<File Name="../../csi/csi_driver/csky/hobbit1_2/include/pinmux.h">
<FileOption/>
</File>
<File Name="../../csi/csi_driver/csky/hobbit1_2/include/soc.h">
<FileOption/>
</File>
<File Name="../../csi/csi_driver/csky/common/usart/dw_usart.c">
<FileOption/>
</File>
<File Name="../../csi/csi_driver/csky/common/usart/dw_usart.h">
<FileOption/>
</File>
<File Name="../../csi/csi_core/ck802/core_ck802.c">
<FileOption/>
</File>
<File Name="../../csi/csi_core/ck802/core_ck802.h">
<FileOption/>
</File>
<File Name="../../csi/csi_core/include/csi_core.h">
<FileOption/>
</File>
<File Name="../../csi/csi_core/include/csi-gcc/csi_gcc.h">
<FileOption/>
</File>
<File Name="../../csi/csi_core/include/csi-gcc/csi_instr.h">
<FileOption/>
</File>
<File Name="../../csi/csi_core/include/csi-gcc/csi_reg.h">
<FileOption/>
</File>
<File Name="../../csi/csi_core/include/csi-gcc/csi_simd.h">
<FileOption/>
</File>
<File Name="../../csi/csi_driver/include/system.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="FreeRTOS">
<File Name="../../../../Source/croutine.c">
<FileOption/>
</File>
<File Name="../../../../Source/event_groups.c">
<FileOption/>
</File>
<File Name="../../../../Source/list.c">
<FileOption/>
</File>
<File Name="../../../../Source/queue.c">
<FileOption/>
</File>
<File Name="../../../../Source/stream_buffer.c">
<FileOption/>
</File>
<File Name="../../../../Source/tasks.c">
<FileOption/>
</File>
<File Name="../../../../Source/timers.c">
<FileOption/>
</File>
<VirtualDirectory Name="inc">
<File Name="../../../../Source/include/atomic.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/croutine.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/deprecated_definitions.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/event_groups.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/FreeRTOS.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/list.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/message_buffer.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/mpu_prototypes.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/mpu_wrappers.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/portable.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/projdefs.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/queue.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/semphr.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/stack_macros.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/StackMacros.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/stdint.readme">
<FileOption/>
</File>
<File Name="../../../../Source/include/stream_buffer.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/task.h">
<FileOption/>
</File>
<File Name="../../../../Source/include/timers.h">
<FileOption/>
</File>
</VirtualDirectory>
<File Name="../../../../Source/portable/MemMang/heap_4.c">
<FileOption/>
</File>
<VirtualDirectory Name="port">
<File Name="../../../../Source/portable/ThirdParty/CDK/T-HEAD_CK802/port.c">
<FileOption/>
</File>
<File Name="../../../../Source/portable/ThirdParty/CDK/T-HEAD_CK802/portasm.S">
<FileOption/>
</File>
<File Name="../../../../Source/portable/ThirdParty/CDK/T-HEAD_CK802/portmacro.h">
<FileOption/>
</File>
</VirtualDirectory>
</VirtualDirectory>
<DebugSessions>
<watchExpressions>uxDeletedTasksWaitingCleanUp:0</watchExpressions>
<memoryExpressions>0xe000e100;;;</memoryExpressions>
<statistics>;;MHZ</statistics>
<peripheralTabs/>
<WatchDisplayFormat>0</WatchDisplayFormat>
<LocalDisplayFormat>0</LocalDisplayFormat>
<debugLayout/>
<memoryTabColSizeExpressions>100:8;100:8;100:8;100:8;</memoryTabColSizeExpressions>
</DebugSessions>
<BuildConfigs>
<BuildConfig Name="BuildSet">
<Target>
<ROMBank Selected="1">
<ROM1>
<InUse>yes</InUse>
<Start>0x60000000</Start>
<Size>0x4000</Size>
</ROM1>
<ROM2>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM2>
<ROM3>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM3>
<ROM4>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM4>
<ROM5>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM5>
</ROMBank>
<RAMBank>
<RAM1>
<InUse>no</InUse>
<Start>0x20000000</Start>
<Size>0x80000</Size>
<Init>yes</Init>
</RAM1>
<RAM2>
<InUse>no</InUse>
<Start>0x50000000</Start>
<Size>0x800000</Size>
<Init>yes</Init>
</RAM2>
<RAM3>
<InUse>yes</InUse>
<Start>0x60004000</Start>
<Size>0xc000</Size>
<Init>yes</Init>
</RAM3>
<RAM4>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM4>
<RAM5>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM5>
</RAMBank>
<CPU>ck802</CPU>
<UseMiniLib>yes</UseMiniLib>
<Endian>little</Endian>
<UseHardFloat>no</UseHardFloat>
<UseEnhancedLRW>yes</UseEnhancedLRW>
<UseContinueBuild>no</UseContinueBuild>
<UseSemiHost>no</UseSemiHost>
</Target>
<Output>
<OutputName>$(ProjectName)</OutputName>
<Type>Executable</Type>
<CreateHexFile>no</CreateHexFile>
<CreateBinFile>no</CreateBinFile>
<Preprocessor>no</Preprocessor>
<Disasm>yes</Disasm>
<CallGraph>no</CallGraph>
<Map>yes</Map>
</Output>
<User>
<BeforeCompile>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeCompile>
<BeforeMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeMake>
<AfterMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</AfterMake>
</User>
<Compiler>
<Define/>
<Undefine/>
<Optim>Optimize size (-Os)</Optim>
<DebugLevel>Default (-g)</DebugLevel>
<IncludePath>$(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</IncludePath>
<OtherFlags>-ffunction-sections -fdata-sections -mistack</OtherFlags>
<Verbose>no</Verbose>
<Ansi>no</Ansi>
<Syntax>no</Syntax>
<Pedantic>no</Pedantic>
<PedanticErr>no</PedanticErr>
<InhibitWarn>no</InhibitWarn>
<AllWarn>yes</AllWarn>
<WarnErr>no</WarnErr>
<OneElfS>no</OneElfS>
<Fstrict>no</Fstrict>
</Compiler>
<Asm>
<Define/>
<Undefine/>
<IncludePath>$(ProjectPath);$(CDKPath)/CSKY/csi/csi_core/include/;$(CDKPath)/CSKY/csi/csi_core/csi_cdk/;$(CDKPath)/CSKY/csi/csi_driver/include/</IncludePath>
<OtherFlags/>
<DebugLevel>gdwarf2</DebugLevel>
</Asm>
<Linker>
<Garbage>yes</Garbage>
<LDFile>$(ProjectPath)/ckcpu.ld</LDFile>
<LibName/>
<LibPath/>
<OtherFlags/>
<AutoLDFile>no</AutoLDFile>
</Linker>
<Debug>
<LoadApplicationAtStartup>yes</LoadApplicationAtStartup>
<Connector>ICE</Connector>
<StopAt>yes</StopAt>
<StopAtText>main</StopAtText>
<InitFile>$(ProjectPath)/gdb.init</InitFile>
<AutoRun>yes</AutoRun>
<ResetType>Soft Reset</ResetType>
<SoftResetVal>60000000</SoftResetVal>
<ResetAfterLoad>no</ResetAfterLoad>
<Dumpcore>no</Dumpcore>
<DumpcoreText>$(ProjectPath)/$(ProjectName).cdkcore</DumpcoreText>
<ConfigICE>
<IP>localhost</IP>
<PORT>1025</PORT>
<Clock>12000</Clock>
<Delay>10</Delay>
<WaitReset>50</WaitReset>
<DDC>yes</DDC>
<TRST>no</TRST>
<DebugPrint>no</DebugPrint>
<Connect>Normal</Connect>
<ResetType>soft</ResetType>
<SoftResetVal>0</SoftResetVal>
<RTOSType>None</RTOSType>
<DownloadToFlash>no</DownloadToFlash>
<ResetAfterConnect>yes</ResetAfterConnect>
<GDBName/>
<GDBServerType>Local</GDBServerType>
<OtherFlags/>
</ConfigICE>
<ConfigSIM>
<SIMTarget/>
<OtherFlags/>
<NoGraphic>yes</NoGraphic>
<Log>no</Log>
<SimTrace>no</SimTrace>
</ConfigSIM>
</Debug>
<Flash>
<InitFile>$(ProjectPath)/flash.init</InitFile>
<Erase>Erase Sectors</Erase>
<Algorithms Path="">hobbit1_2_OTP_CDK.elf</Algorithms>
<Program>no</Program>
<Verify>no</Verify>
<ResetAndRun>no</ResetAndRun>
<ResetType>Soft Reset</ResetType>
<SoftResetVal/>
<External>no</External>
<Command/>
<Arguments/>
</Flash>
</BuildConfig>
</BuildConfigs>
</Project>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<CDK_Workspace Name="RTOSDemo" Database="">
<Project Name="RTOSDemo" Path="RTOSDemo.cdkproj" Active="Yes"/>
<BuildMatrix>
<WorkspaceConfiguration Name="Debug" Selected="yes">
<Environment/>
<Project Name="RTOSDemo" ConfigName="BuildSet"/>
</WorkspaceConfiguration>
</BuildMatrix>
</CDK_Workspace>

View file

@ -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;
}

View file

@ -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__ */

View file

@ -0,0 +1,150 @@
/*************************************************************
// <<< Use Configuration Wizard in Context Menu >>>
*************************************************************/
/*************************************************************
// <m> Entry Point <2>
// <i> 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
}

View file

@ -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:

View file

@ -0,0 +1,6 @@
set *0x4000202c=0xc0206
set *0x40002004=0x8
set $pc=0x60000000
set $psr=0xe0000000

View file

@ -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;
}

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<CDK_Workspace Name="RTOSDemo_CDK" Database="">
<Project Name="RTOSDemo" Path="RTOSDemo/RTOSDemo.cdkproj" Active="Yes"/>
<BuildMatrix>
<WorkspaceConfiguration Name="Debug" Selected="yes">
<Environment/>
<Project Name="RTOSDemo" ConfigName="BuildSet"/>
</WorkspaceConfiguration>
</BuildMatrix>
</CDK_Workspace>

View file

@ -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.

View file

@ -0,0 +1 @@
CSI-CORE v1.0

View file

@ -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 <stdint.h>
#include <core_ck802.h>
#include <config.h>
/*******************************************************************************
* 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 <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
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 */

View file

@ -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 <stdint.h>
#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
<strong>IO Type Qualifiers</strong> 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 */

View file

@ -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

View file

@ -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;
}

View file

@ -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 <stdlib.h>
#include "csi_reg.h"
#include "csi_instr.h"
#include "csi_simd.h"
#endif /* _CSI_GCC_H_ */

View file

@ -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_ */

View file

@ -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<csi_gcc.h>
/**
\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_ */

File diff suppressed because it is too large Load diff

View file

@ -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 <stdint.h>
#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 <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
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_ */

View file

@ -0,0 +1,7 @@
if CONFIG_CSKY
source "../../csi/csi_driver/csky/Kconfig"
endif
if CONFIG_SANECHIPS
source "../../csi/csi_driver/sanechips/Kconfig"
endif

View file

@ -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

View file

@ -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

View file

@ -0,0 +1 @@
v1.0

View file

@ -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 <string.h>
#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;
}

View file

@ -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 <stdio.h>
#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

View file

@ -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

View file

@ -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 <stdio.h>
#include <string.h>
#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;
}

View file

@ -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

View file

@ -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 <stdio.h>
#include <string.h>
#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;
}

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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 <stdio.h>
#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

View file

@ -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

View file

@ -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 <stdio.h>
#include <string.h>
#include <stdbool.h>
#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;
}

View file

@ -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 <stdio.h>
#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

View file

@ -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 <stdio.h>
#include <string.h>
#include <stdbool.h>
#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;
}

View file

@ -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 <stdio.h>
#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;

View file

@ -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

View file

@ -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 <stdbool.h>
#include <stdio.h>
#include <string.h>
#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;
}

View file

@ -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

View file

@ -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 <stdbool.h>
#include <stdio.h>
#include <string.h>
#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;
}

View file

@ -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

View file

@ -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

View file

@ -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 <stdbool.h>
#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;
}

View file

@ -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 <stdio.h>
#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 */

View file

@ -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 <stdbool.h>
#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;
}
}

View file

@ -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 <stdio.h>
#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 */

View file

@ -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

View file

@ -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 <stdio.h>
#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;
}

View file

@ -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 <stdio.h>
#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 */

View file

@ -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

View file

@ -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

View file

@ -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 <drv_usart.h>
#include <drv_timer.h>
#include <drv_rtc.h>
#include <drv_trng.h>
#include <drv_crc.h>
#include <drv_aes.h>
#include <drv_rsa.h>
#include <drv_eflash.h>
#include <drv_spi.h>
#include <drv_gpio.h>
#include <stdio.h>
#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

View file

@ -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 <stdint.h>
#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_ */

View file

@ -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

View file

@ -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 <stdint.h>
#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 */

View file

@ -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 <config.h>
#ifdef __cplusplus
}
#endif
#endif /* SOC_H */

View file

@ -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 <drv_common.h>
#include "config.h"
#include "soc.h"
#ifndef CONFIG_KERNEL_NONE
#include <csi_kernel.h>
#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

View file

@ -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 <stdint.h>
#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;
}

View file

@ -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

View file

@ -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 <soc.h>
#include <config.h>
#include <drv_usart.h>
#include <stdio.h>
#include <drv_timer.h>
#include <drv_rtc.h>
#include <drv_trng.h>
#include <drv_crc.h>
#include <drv_aes.h>
#include <drv_rsa.h>
#include <drv_eflash.h>
#include <drv_spi.h>
#include <drv_gpio.h>
#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;
}

View file

@ -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

View file

@ -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 <stdint.h>
#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 */

View file

@ -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 */

View file

@ -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 <drv_common.h>
#include <config.h>
#include "soc.h"
#ifndef CONFIG_KERNEL_NONE
#include <csi_kernel.h>
#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();
}

View file

@ -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 <stdint.h>
#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;
}

View file

@ -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

View file

@ -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 <drv_usart.h>
#include <drv_trng.h>
#include <drv_crc.h>
#include <drv_aes.h>
#include <drv_rsa.h>
#include <drv_eflash.h>
#include <drv_timer.h>
#include <drv_gpio.h>
#include <drv_iic.h>
#include <drv_rtc.h>
#include <drv_spi.h>
#include <drv_wdt.h>
#include <drv_sha.h>
#include <drv_pwm.h>
#include <drv_dmac.h>
#include <stdio.h>
#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

View file

@ -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

View file

@ -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 <stdint.h>
#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 */

View file

@ -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 <config.h>
#ifdef CONFIG_HAVE_VIC
#define ATTRIBUTE_ISR __attribute__((isr))
#else
#define ATTRIBUTE_ISR
#endif
#ifdef __cplusplus
}
#endif
#endif /* SOC_H */

View file

@ -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 <drv_common.h>
#include "config.h"
#include "soc.h"
#ifndef CONFIG_KERNEL_NONE
#include <csi_kernel.h>
#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

View file

@ -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 <stdint.h>
#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;
}

View file

@ -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__ */

View file

@ -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 <stdint.h>
#include <drv_common.h>
#include <drv_errno.h>
/// 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_ */

View file

@ -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 <stdint.h>
#include <drv_errno.h>
#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 */

View file

@ -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 <stdint.h>
#include <drv_errno.h>
#include <drv_common.h>
/****** 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_ */

View file

@ -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 <stdint.h>
#include <drv_common.h>
/// 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_ */

View file

@ -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 <stdint.h>
#include <drv_common.h>
/// 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_ */

View file

@ -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 <errno.h>
#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 */

View file

@ -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_ */

Some files were not shown because too many files have changed in this diff Show more