1、add edu-riscv64 board for xizi;2、add microkernel dir for xizi
it is OK
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
SRC_FILES := lv_init.c lv_demo.c lv_demo_calendar.c 
 | 
			
		||||
SRC_FILES += lv_sensor_info.c lv_sensor_update_info.c lv_sensor_info_update_demo.c
 | 
			
		||||
# SRC_FILES += lv_sensor_info.c lv_sensor_update_info.c lv_sensor_info_update_demo.c
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ static void event_handler(lv_event_t * e)
 | 
			
		|||
void lv_demo_calendar(void)
 | 
			
		||||
{
 | 
			
		||||
    lv_obj_t  * calendar = lv_calendar_create(lv_scr_act());
 | 
			
		||||
    lv_obj_set_size(calendar, 800, 480);//lv_obj_set_size(calendar, 800, 480);
 | 
			
		||||
    lv_obj_set_size(calendar, 320, 320);//lv_obj_set_size(calendar, 800, 480);
 | 
			
		||||
    lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 0);
 | 
			
		||||
    lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
# XIZI_AIOT
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -5,7 +5,7 @@ MAKEFLAGS += --no-print-directory
 | 
			
		|||
.PHONY:COMPILE_APP COMPILE_KERNEL
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
riscv_support := kd233 maix-go hifive1-rev-B gapuino gd32vf103-rvstar rv32m1-vega aiit-riscv64-board xidatong-riscv64
 | 
			
		||||
riscv_support := kd233 maix-go hifive1-rev-B gapuino gd32vf103-rvstar rv32m1-vega aiit-riscv64-board xidatong-riscv64 edu-riscv64
 | 
			
		||||
arm_support += stm32f407-st-discovery stm32f407zgt6 stm32f103-nano nuvoton-m2354 ok1052-c imxrt1176-sbc aiit-arm32-board xidatong-arm32 xiwangtong-arm32 hc32f4a0
 | 
			
		||||
emulator_support += hifive1-emulator k210-emulator cortex-m0-emulator cortex-m3-emulator cortex-m4-emulator
 | 
			
		||||
support := $(riscv_support) $(arm_support) $(emulator_support) 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,9 @@ endif
 | 
			
		|||
ifeq ($(CONFIG_BOARD_XIDATONG_RISCV64_EVB),y)
 | 
			
		||||
SRC_DIR +=k210
 | 
			
		||||
endif
 | 
			
		||||
ifeq ($(CONFIG_BOARD_EDU_RISCV64_EVB),y)
 | 
			
		||||
SRC_DIR +=k210
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_BOARD_GAPUINO),y)
 | 
			
		||||
SRC_DIR +=gap8
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,23 +15,23 @@
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
* @file board.c
 | 
			
		||||
* @brief support aiit-riscv64-board init configure and start-up
 | 
			
		||||
* @brief support edu-riscv64 board init configure and start-up
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
* @date 2022-10-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
File name: board.c
 | 
			
		||||
Description: support aiit-riscv64-board init configure and driver/task/... init
 | 
			
		||||
Description: support edu-riscv64 board init configure and driver/task/... init
 | 
			
		||||
Others: https://canaan-creative.com/developer
 | 
			
		||||
History: 
 | 
			
		||||
1. Date: 2021-04-25
 | 
			
		||||
1. Date: 2022-10-25
 | 
			
		||||
Author: AIIT XUOS Lab
 | 
			
		||||
Modification: 
 | 
			
		||||
1. support aiit-riscv64-board InitBoardHardware
 | 
			
		||||
2. support aiit-riscv64-board Kd233Start
 | 
			
		||||
3. support aiit-riscv64-board shell cmd, include reboot, shutdown
 | 
			
		||||
1. support edu-riscv64 board InitBoardHardware
 | 
			
		||||
2. support edu-riscv64 board Kd233Start
 | 
			
		||||
3. support edu-riscv64 board shell cmd, include reboot, shutdown
 | 
			
		||||
*************************************************/
 | 
			
		||||
 | 
			
		||||
#include <board.h>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,21 +10,21 @@
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
* @file drv_io_config.c
 | 
			
		||||
* @brief support aiit-riscv64-board io configure
 | 
			
		||||
* @brief support edu-riscv64 board io configure
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
* @date 2022-10-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
File name: drv_io_config.c
 | 
			
		||||
Description: support aiit-riscv64-board io configure
 | 
			
		||||
Description: support edu-riscv64 board io configure
 | 
			
		||||
Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.c for references
 | 
			
		||||
                https://github.com/RT-Thread/rt-thread/tree/v4.0.2
 | 
			
		||||
History: 
 | 
			
		||||
1. Date: 2021-04-25
 | 
			
		||||
1. Date: 2022-10-25
 | 
			
		||||
Author: AIIT XUOS Lab
 | 
			
		||||
Modification: support aiit-riscv64-board io configure
 | 
			
		||||
Modification: support edu-riscv64 board io configure
 | 
			
		||||
*************************************************/
 | 
			
		||||
 | 
			
		||||
#include <xizi.h>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,21 +15,21 @@
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
* @file connect_lcd.h
 | 
			
		||||
* @brief define aiit-riscv64-board lcd function
 | 
			
		||||
* @brief define edu-riscv64 board lcd function
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
* @date 2022-10-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
File name: connect_lcd.h
 | 
			
		||||
Description: define aiit-riscv64-board lcd function
 | 
			
		||||
Description: define edu-riscv64 board lcd function
 | 
			
		||||
Others:  https://canaan-creative.com/developer
 | 
			
		||||
History: 
 | 
			
		||||
1. Date: 2021-04-25
 | 
			
		||||
1. Date: 2022-10-25
 | 
			
		||||
Author: AIIT XUOS Lab
 | 
			
		||||
Modification: 
 | 
			
		||||
1. add aiit-riscv64-board lcd function
 | 
			
		||||
1. add edu-riscv64 board lcd function
 | 
			
		||||
*************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef CONNECT_LCD_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,10 +12,10 @@
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
* @file connect_spi.h
 | 
			
		||||
* @brief define aiit-riscv64-board spi function and struct
 | 
			
		||||
* @brief define edu-riscv64 board spi function and struct
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
* @date 2022-10-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef CONNECT_SPI_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,21 +9,21 @@
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
* @file graphic.h
 | 
			
		||||
* @brief define aiit-riscv64-board lcd operation
 | 
			
		||||
* @brief define edu-riscv64 board lcd operation
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
* @date 2022-10-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
File name: graphic.h
 | 
			
		||||
Description: define aiit-riscv64-board lcd operation
 | 
			
		||||
Description: define edu-riscv64 board lcd operation
 | 
			
		||||
Others: take RT-Thread v4.0.2/include/rtdef.h for references
 | 
			
		||||
                https://github.com/RT-Thread/rt-thread/tree/v4.0.2
 | 
			
		||||
History: 
 | 
			
		||||
1. Date: 2021-04-25
 | 
			
		||||
1. Date: 2022-10-25
 | 
			
		||||
Author: AIIT XUOS Lab
 | 
			
		||||
Modification: add aiit-riscv64-board lcd configure and operation function
 | 
			
		||||
Modification: add edu-riscv64 board lcd configure and operation function
 | 
			
		||||
*************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef GRAPHIC_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@
 | 
			
		|||
*                https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
* @date 2022-10-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __HARDWARE_SPI_H__
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,233 @@
 | 
			
		|||
#
 | 
			
		||||
# Automatically generated file; DO NOT EDIT.
 | 
			
		||||
# XiZi_IIoT Project Configuration
 | 
			
		||||
#
 | 
			
		||||
CONFIG_BOARD_K210_EVB=y
 | 
			
		||||
CONFIG_KERNEL_CONSOLE_DEVICE_NAME="uarths"
 | 
			
		||||
CONFIG_LED0=24
 | 
			
		||||
CONFIG_LED1=25
 | 
			
		||||
CONFIG_ARCH_CPU_64BIT=y
 | 
			
		||||
CONFIG_ARCH_RISCV=y
 | 
			
		||||
CONFIG_ARCH_RISCV64=y
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# kd233 feature
 | 
			
		||||
#
 | 
			
		||||
# CONFIG_BSP_USING_AUDIO is not set
 | 
			
		||||
# CONFIG_BSP_USING_CAMERA is not set
 | 
			
		||||
# CONFIG_BSP_USING_SDIO is not set
 | 
			
		||||
CONFIG_BSP_USING_DMA=y
 | 
			
		||||
CONFIG_BSP_USING_GPIO=y
 | 
			
		||||
# CONFIG_BSP_USING_I2C is not set
 | 
			
		||||
# CONFIG_BSP_USING_I2S is not set
 | 
			
		||||
# CONFIG_BSP_USING_LCD is not set
 | 
			
		||||
# CONFIG_BSP_USING_RTC is not set
 | 
			
		||||
# CONFIG_BSP_USING_SECURITY is not set
 | 
			
		||||
# CONFIG_BSP_USING_SPI is not set
 | 
			
		||||
CONFIG_BSP_USING_UART=y
 | 
			
		||||
CONFIG_BSP_USING_UART_HS=y
 | 
			
		||||
# CONFIG_BSP_USING_VIDEO is not set
 | 
			
		||||
# CONFIG_BSP_USING_WDT is not set
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# General Purpose UARTs
 | 
			
		||||
#
 | 
			
		||||
CONFIG_BSP_USING_UART1=y
 | 
			
		||||
CONFIG_BSP_UART1_TXD_PIN=20
 | 
			
		||||
CONFIG_BSP_UART1_RXD_PIN=21
 | 
			
		||||
CONFIG_BSP_USING_UART2=y
 | 
			
		||||
CONFIG_BSP_UART2_TXD_PIN=28
 | 
			
		||||
CONFIG_BSP_UART2_RXD_PIN=27
 | 
			
		||||
CONFIG_BSP_USING_UART3=y
 | 
			
		||||
CONFIG_BSP_UART3_TXD_PIN=22
 | 
			
		||||
CONFIG_BSP_UART3_RXD_PIN=23
 | 
			
		||||
CONFIG___STACKSIZE__=4096
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Hardware feature
 | 
			
		||||
#
 | 
			
		||||
CONFIG_RESOURCES_SERIAL=y
 | 
			
		||||
# CONFIG_SERIAL_USING_DMA is not set
 | 
			
		||||
# CONFIG_SERIAL_RB_BUFSZ is not set
 | 
			
		||||
# CONFIG_RESOURCES_HWTIMER is not set
 | 
			
		||||
# CONFIG_RESOURCES_I2C is not set
 | 
			
		||||
# CONFIG_RESOURCES_LCD is not set
 | 
			
		||||
# CONFIG_RESOURCES_SDIO is not set
 | 
			
		||||
# CONFIG_RESOURCES_TOUCH is not set
 | 
			
		||||
CONFIG_RESOURCES_PIN=y
 | 
			
		||||
# CONFIG_RESOURCES_RTC is not set
 | 
			
		||||
# CONFIG_RESOURCES_SPI is not set
 | 
			
		||||
#CONFIG_RESOURCES_SPI_SD is not set
 | 
			
		||||
#CONFIG_RESOURCES_SPI_SFUD is not set
 | 
			
		||||
# SFUD_USING_SFDP is not set
 | 
			
		||||
# SFUD_USING_FLASH_INFO_TABLE is not set
 | 
			
		||||
# SFUD_DEBUG_LOG is not set
 | 
			
		||||
# CONFIG_RESOURCES_WDT is not set
 | 
			
		||||
# CONFIG_RESOURCES_USB is not set
 | 
			
		||||
# CONFIG_RESOURCES_USB_HOST is not set
 | 
			
		||||
# CONFIG_UDISK_MOUNTPOINT is not set
 | 
			
		||||
# CONFIG_USBH_MSTORAGE is not set
 | 
			
		||||
# CONFIG_RESOURCES_USB_DEVICE is not set
 | 
			
		||||
# CONFIG_USBD_THREAD_STACK_SZ is not set
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Kernel feature
 | 
			
		||||
#
 | 
			
		||||
# CONFIG_SEPARATE_COMPILE is not set
 | 
			
		||||
# CONFIG_COMPILER_APP is not set
 | 
			
		||||
# CONFIG_COMPILER_KERNEL is not set
 | 
			
		||||
#
 | 
			
		||||
# Kernel Device Object
 | 
			
		||||
#
 | 
			
		||||
CONFIG_KERNEL_DEVICE=y
 | 
			
		||||
CONFIG_KERNEL_CONSOLE=y
 | 
			
		||||
CONFIG_KERNEL_CONSOLEBUF_SIZE=128
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Task feature
 | 
			
		||||
#
 | 
			
		||||
CONFIG_SCHED_POLICY_RR_REMAINSLICE=y
 | 
			
		||||
# CONFIG_SCHED_POLICY_RR is not set
 | 
			
		||||
# CONFIG_SCHED_POLICY_FIFO is not set
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Inter-Task communication
 | 
			
		||||
#
 | 
			
		||||
CONFIG_KERNEL_SEMAPHORE=y
 | 
			
		||||
CONFIG_KERNEL_MUTEX=y
 | 
			
		||||
CONFIG_KERNEL_EVENT=y
 | 
			
		||||
CONFIG_KERNEL_MESSAGEQUEUE=y
 | 
			
		||||
# CONFIG_KTASK_PRIORITY_8 is not set
 | 
			
		||||
CONFIG_KTASK_PRIORITY_32=y
 | 
			
		||||
# CONFIG_KTASK_PRIORITY_256 is not set
 | 
			
		||||
CONFIG_KTASK_PRIORITY_MAX=32
 | 
			
		||||
CONFIG_TICK_PER_SECOND=100
 | 
			
		||||
CONFIG_KERNEL_STACK_OVERFLOW_CHECK=y
 | 
			
		||||
CONFIG_KERNEL_BANNER=y
 | 
			
		||||
# CONFIG_KERNEL_HOOK is not set
 | 
			
		||||
CONFIG_KERNEL_SOFTTIMER=y
 | 
			
		||||
CONFIG_KERNEL_IDLE_HOOK=y
 | 
			
		||||
CONFIG_IDEL_HOOK_LIST_SIZE=4
 | 
			
		||||
CONFIG_IDLE_KTASK_STACKSIZE=1024
 | 
			
		||||
CONFIG_USER_APPLICATION=y
 | 
			
		||||
# CONFIG_TASK_ISOLATION is not set
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Memory Management
 | 
			
		||||
#
 | 
			
		||||
# CONFIG_KERNEL_MEMBLOCK is not set
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Command shell
 | 
			
		||||
#
 | 
			
		||||
CONFIG_TOOL_SHELL=y
 | 
			
		||||
CONFIG_SHELL_TASK_PRIORITY=20
 | 
			
		||||
CONFIG_SHELL_TASK_STACK_SIZE=4096
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# User Control
 | 
			
		||||
#
 | 
			
		||||
CONFIG_SHELL_DEFAULT_USER="letter"
 | 
			
		||||
CONFIG_SHELL_DEFAULT_USER_PASSWORD=""
 | 
			
		||||
CONFIG_SHELL_LOCK_TIMEOUT=10000
 | 
			
		||||
CONFIG_SHELL_ENTER_CR_AND_LF=y
 | 
			
		||||
# CONFIG_SHELL_ENTER_CRLF is not set
 | 
			
		||||
CONFIG_SHELL_ENTER_CR=y
 | 
			
		||||
CONFIG_SHELL_ENTER_LF=y
 | 
			
		||||
CONFIG_SHELL_MAX_NUMBER=5
 | 
			
		||||
CONFIG_SHELL_PARAMETER_MAX_NUMBER=8
 | 
			
		||||
CONFIG_SHELL_HISTORY_MAX_NUMBER=5
 | 
			
		||||
CONFIG_SHELL_PRINT_BUFFER=128
 | 
			
		||||
CONFIG_SHELL_USING_CMD_EXPORT=y
 | 
			
		||||
# CONFIG_SHELL_HELP_LIST_USER is not set
 | 
			
		||||
CONFIG_SHELL_HELP_SHOW_PERMISSION=y
 | 
			
		||||
# CONFIG_SHELL_HELP_LIST_VAR is not set
 | 
			
		||||
# CONFIG_SHELL_HELP_LIST_KEY is not set
 | 
			
		||||
CONFIG_KERNEL_QUEUEMANAGE=y
 | 
			
		||||
CONFIG_KERNEL_WORKQUEUE=y
 | 
			
		||||
CONFIG_WORKQUEUE_KTASK_STACKSIZE=512
 | 
			
		||||
CONFIG_WORKQUEUE_KTASK_PRIORITY=23
 | 
			
		||||
CONFIG_KERNEL_WAITQUEUE=y
 | 
			
		||||
CONFIG_KERNEL_DATAQUEUE=y
 | 
			
		||||
# CONFIG_KERNEL_CIRCULAR_AREA is not set
 | 
			
		||||
# CONFIG_KERNEL_AVL_TREE is not set
 | 
			
		||||
CONFIG_NAME_MAX=32
 | 
			
		||||
CONFIG_ALIGN_SIZE=8
 | 
			
		||||
CONFIG_KERNEL_COMPONENTS_INIT=y
 | 
			
		||||
CONFIG_KERNEL_USER_MAIN=y
 | 
			
		||||
CONFIG_MAIN_KTASK_STACK_SIZE=2048
 | 
			
		||||
CONFIG_ENV_INIT_KTASK_STACK_SIZE=8192
 | 
			
		||||
CONFIG_MAIN_KTASK_PRIORITY=10
 | 
			
		||||
# CONFIG_USER_TEST is not set
 | 
			
		||||
# CONFIG_TOOL_TEST_SEM is not set
 | 
			
		||||
# CONFIG_TOOL_TEST_MUTEX is not set
 | 
			
		||||
# CONFIG_TOOL_TEST_EVENT is not set
 | 
			
		||||
# CONFIG_TOOL_TEST_MSG is not set
 | 
			
		||||
# CONFIG_TOOL_TEST_AVLTREE is not set
 | 
			
		||||
# CONFIG_TEST_CRICULAR_AREA is not set
 | 
			
		||||
# CONFIG_TOOL_TEST_MEM is not set
 | 
			
		||||
# CONFIG_TOOL_TEST_TIMER is not set
 | 
			
		||||
# CONFIG_TOOL_TEST_IWG is not set
 | 
			
		||||
# CONFIG_TOOL_TEST_REALTIME is not set
 | 
			
		||||
# CONFIG_TOOL_TEST_DBG is not set
 | 
			
		||||
# CONFIG_TOOL_TEST_SCHED is not set
 | 
			
		||||
# CONFIG_KERNEL_DEBUG is not set
 | 
			
		||||
CONFIG_DEBUG_INIT_CONFIG=y
 | 
			
		||||
CONFIG_DBG_INIT=1
 | 
			
		||||
CONFIG_ARCH_SMP=y
 | 
			
		||||
CONFIG_CPUS_NR=2
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# File system
 | 
			
		||||
#
 | 
			
		||||
CONFIG_FS_VFS=y
 | 
			
		||||
CONFIG_VFS_USING_WORKDIR=y
 | 
			
		||||
CONFIG_FS_VFS_DEVFS=y
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Fat filesystem 
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# IOT-Device File system
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Lwext4 filesystem 
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# APP Framework
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# connection
 | 
			
		||||
#
 | 
			
		||||
# CONFIG_CONNECTION_AT is not set
 | 
			
		||||
# CONFIG_CONNECTION_MQTT is not set
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# medium communication 
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Intelligence
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Control
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Lib
 | 
			
		||||
#
 | 
			
		||||
CONFIG_LIB=y
 | 
			
		||||
CONFIG_LIB_POSIX=y
 | 
			
		||||
CONFIG_LIB_NEWLIB=y
 | 
			
		||||
 | 
			
		||||
CONFIG_LITTLEVGL2RTT_USING_DEMO=y
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Security
 | 
			
		||||
#
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
mainmenu "XiZi_IIoT Project Configuration"
 | 
			
		||||
 | 
			
		||||
config BSP_DIR
 | 
			
		||||
    string
 | 
			
		||||
    option env="BSP_ROOT"
 | 
			
		||||
    default "."
 | 
			
		||||
 | 
			
		||||
config KERNEL_DIR
 | 
			
		||||
    string
 | 
			
		||||
    option env="KERNEL_ROOT"
 | 
			
		||||
    default "../.."
 | 
			
		||||
 | 
			
		||||
config BOARD_EDU_RISCV64_EVB
 | 
			
		||||
    bool
 | 
			
		||||
    select  ARCH_RISCV
 | 
			
		||||
    select ARCH_RISCV64
 | 
			
		||||
    select ARCH_CPU_64BIT
 | 
			
		||||
    default y 
 | 
			
		||||
 | 
			
		||||
source "$KERNEL_DIR/arch/Kconfig"
 | 
			
		||||
 | 
			
		||||
menu "edu-riscv64 feature"
 | 
			
		||||
    source "$BSP_DIR/third_party_driver/Kconfig"
 | 
			
		||||
 | 
			
		||||
    menu "config default board resources"
 | 
			
		||||
        menu "config board app name"
 | 
			
		||||
            config BOARD_APP_NAME
 | 
			
		||||
                string "config board app name"
 | 
			
		||||
                default "/XiUOS_edu_riscv64_app.bin"
 | 
			
		||||
        endmenu
 | 
			
		||||
 | 
			
		||||
        menu "config board service table"
 | 
			
		||||
            config SERVICE_TABLE_ADDRESS
 | 
			
		||||
                hex "board service table address"
 | 
			
		||||
                default 0x80100000
 | 
			
		||||
        endmenu
 | 
			
		||||
 | 
			
		||||
        menu "config board peripheral"
 | 
			
		||||
            config MOUNT_SDCARD
 | 
			
		||||
                bool "mount cd card"
 | 
			
		||||
                default n
 | 
			
		||||
            config MOUNT_USB
 | 
			
		||||
                bool "mount usb"
 | 
			
		||||
                default n
 | 
			
		||||
        endmenu
 | 
			
		||||
 | 
			
		||||
    endmenu
 | 
			
		||||
 | 
			
		||||
    config __STACKSIZE__
 | 
			
		||||
        int "stack size for interrupt"
 | 
			
		||||
        default 4096
 | 
			
		||||
 | 
			
		||||
endmenu
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
menu "Hardware feature"
 | 
			
		||||
source "$KERNEL_DIR/resources/Kconfig"
 | 
			
		||||
endmenu
 | 
			
		||||
 | 
			
		||||
source "$KERNEL_DIR/Kconfig"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
SRC_FILES := board.c
 | 
			
		||||
 | 
			
		||||
SRC_DIR := third_party_driver 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,187 @@
 | 
			
		|||
# 从零开始构建矽璓工业物联操作系统:使用risc-v架构的edu-riscv64开发板
 | 
			
		||||
 | 
			
		||||
[XiUOS](http://xuos.io/) (X Industrial Ubiquitous Operating System) 矽璓XiUOS是一款面向智慧车间的工业物联网操作系统,主要由一个极简的微型实时操作系统内核和其上的工业物联框架构成,通过高效管理工业物联网设备、支撑工业物联应用,在生产车间内实现智能化的“感知环境、联网传输、知悉识别、控制调整”,促进以工业设备和工业控制系统为核心的人、机、物深度互联,帮助提升生产线的数字化和智能化水平。
 | 
			
		||||
 | 
			
		||||
## 开发环境搭建
 | 
			
		||||
 | 
			
		||||
### 推荐使用:
 | 
			
		||||
 | 
			
		||||
**操作系统:** ubuntu18.04 [https://ubuntu.com/download/desktop](https://ubuntu.com/download/desktop)
 | 
			
		||||
**开发工具推荐使用 VSCode   ,VScode下载地址为:** VSCode  [https://code.visualstudio.com/](https://code.visualstudio.com/),推荐下载地址为 [http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb](http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb)
 | 
			
		||||
 | 
			
		||||
### 依赖包安装:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ sudo apt install build-essential pkg-config
 | 
			
		||||
$ sudo apt install gcc make libncurses5-dev openssl libssl-dev bison flex libelf-dev autoconf libtool gperf libc6-dev  git
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
**源码下载:** XiUOS [https://www.gitlink.org.cn/xuos/xiuos](https://www.gitlink.org.cn/xuos/xiuos)
 | 
			
		||||
新建一个空文件夹并进入文件夹中,并下载源码,具体命令如下:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
mkdir test  &&  cd test
 | 
			
		||||
git clone https://gitlink.org.cn/xuos/xiuos.git
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1、打开XiUOS源码文件包可以看到以下目录:
 | 
			
		||||
| 名称 | 说明 |
 | 
			
		||||
| -- | -- |
 | 
			
		||||
| APP_Framework | 应用代码 |
 | 
			
		||||
| Ubiquitous | 板级支持包,支持NuttX、RT-Thread和XiZi内核 |
 | 
			
		||||
 | 
			
		||||
2、打开XiZi内核源码文件包可以看到以下目录:
 | 
			
		||||
| 名称 | 说明 |
 | 
			
		||||
| -- | -- |
 | 
			
		||||
| arch | 架构代码 |
 | 
			
		||||
| board | 板级支持包 |
 | 
			
		||||
| fs | 文件系统 |
 | 
			
		||||
| kernel | 内核源码 |
 | 
			
		||||
| lib | 第三方库源码 |
 | 
			
		||||
| resources | 驱动文件 |
 | 
			
		||||
| tool | 系统工具 |
 | 
			
		||||
 | 
			
		||||
使用VScode打开代码,具体操作步骤为:在源码文件夹下打开系统终端,输入`code .`即可打开VScode开发环境,如下图所示:
 | 
			
		||||
 | 
			
		||||
<div align= "center"> 
 | 
			
		||||
<img src = img/vscode.jpg  width =1000>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
### 裁减配置工具的下载
 | 
			
		||||
**裁减配置工具:** kconfig-frontends [https://www.gitlink.org.cn/xuos/kconfig-frontends](https://www.gitlink.org.cn/xuos/kconfig-frontends)
 | 
			
		||||
执行以下命令下载配置工具:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
mkdir kfrontends  && cd kfrontends
 | 
			
		||||
git clone https://gitlink.org.cn/xuos/kconfig-frontends.git
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
下载源码后按以下步骤执行软件安装:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
cd kconfig-frontends
 | 
			
		||||
./xs_build.sh
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 编译工具链:
 | 
			
		||||
 | 
			
		||||
RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载网址 http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2](http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2)
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
$ tar -xjf gnu-mcu-eclipse.tar.bz2 -C /opt/
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
将上述解压的编译工具链的路径添加到board/edu-riscv64/config.mk文件当中,例如:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
export CROSS_COMPILE ?=/opt/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.1-20190425-1021/bin/riscv-none-embed-
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
若`CROSS_COMPILE `  变量定义语句已经存在,将它替换成上面的语句
 | 
			
		||||
 | 
			
		||||
# 在edu-riscv64上创建第一个应用 --helloworld
 | 
			
		||||
 | 
			
		||||
# edu-riscv64开发板简介
 | 
			
		||||
 | 
			
		||||
## 1. 微处理器简介
 | 
			
		||||
 | 
			
		||||
| 硬件 | 描述 |
 | 
			
		||||
| -- | -- |
 | 
			
		||||
|芯片型号| K210 |
 | 
			
		||||
|CPU| 双核RV64GC |
 | 
			
		||||
|主频| 400MHz |
 | 
			
		||||
|片内SRAM| 8MB |
 | 
			
		||||
| 外设 | DVP、JTAG、OTP、FPIOA、GPIO、UART、SPI、RTC、I²S、I²C、WDT、Timer与PWM |
 | 
			
		||||
 | 
			
		||||
XiUOS板级当前支持使用GPIO、I2C、LCD、RTC、SPI、Timer、UART、watchdog。
 | 
			
		||||
 | 
			
		||||
## 2. 代码编写与编译说明
 | 
			
		||||
 | 
			
		||||
编辑环境:`VScode`
 | 
			
		||||
 | 
			
		||||
编译工具链:`riscv-none-embed-gcc`
 | 
			
		||||
使用`VScode`打开工程的方法有多种,本文介绍一种快捷键,在项目目录下将`code .`输入终端即可打开目标项目
 | 
			
		||||
 | 
			
		||||
修改`APP_Framework/Applications`文件夹下`main.c`
 | 
			
		||||
在输出函数中写入  Hello, world!!!  \n完成代码编辑。
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
编译步骤:
 | 
			
		||||
 | 
			
		||||
1.在`VScode`的“命令终端”下执行以下命令,生成配置文件
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
cd ./Ubiquitous/XiZi
 | 
			
		||||
make BOARD=edu-riscv64 distclean
 | 
			
		||||
make BOARD=edu-riscv64 menuconfig
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2.在`menuconfig`界面配置需要关闭和开启的功能,按回车键进入下级菜单,按Y键选中需要开启的功能,按N键选中需要关闭的功能,配置结束后选择Exit保存并退出(本实验无需选择任何选项,所以双击ESC结束选择,继续操作即可)。
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
双击`ESC`键会出现如下图所示结果:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
选择`yes`键退出。
 | 
			
		||||
 | 
			
		||||
若执行 `make BOARD=edu-riscv64 menuconfig`后出现以下界面:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
解决的方法是将终端向上拉伸超过当前界面的三分之二以上,效果如下:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
3.继续在`VScode`的“命令终端”中执行以下命令,进行编译
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
make BOARD=edu-riscv64
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
4.如果编译正确无误,会在build文件夹下生成XiZi-edu-riscv64.elf、XiZi-edu-riscv64.bin文件。其中XiZi-edu-riscv64.bin需要烧写到设备中进行运行。
 | 
			
		||||
 | 
			
		||||
>注:最后可以执行以下命令,清除配置文件和编译生成的文件
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
make BOARD=edu-riscv64 distclean
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 3. 烧写及执行
 | 
			
		||||
 | 
			
		||||
连接开发板串口(即Type-C口)到USB接口,按住“boot”按键并按下“电源按钮”上电,观察电源指示灯点亮,此时表示已进入ISP模式,松开“boot”按键即可;然后使用K-Flash工具进行烧写bin文件。
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
执行以下命令安装K-Flash工具
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
sudo apt install python3 python3-pip
 | 
			
		||||
sudo pip3 install pyserial
 | 
			
		||||
sudo pip3 install pyelftools
 | 
			
		||||
sudo pip3 install kflash
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
如果最后一步安装kflash出现错误,可以尝试以下命令
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
sudo python -m pip install kflash
 | 
			
		||||
sudo python3 -m pip install kflash
 | 
			
		||||
sudo pip install kflash
 | 
			
		||||
sudo pip2 install kflash
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
代码根目录下执行K-Flash工具烧录,-p为USB端口号,视实际情况而定
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
sudo kflash -t build/XiZi-edu-riscv64.bin -p /dev/ttyUSB0
 | 
			
		||||
```
 | 
			
		||||
烧写完毕可以按下“reset”按键,系统即可启动。
 | 
			
		||||
 | 
			
		||||
### 3.1 运行结果
 | 
			
		||||
 | 
			
		||||
如果编译 & 烧写无误,将会在串口终端上看到信息打印输出。
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,242 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 board.c
 | 
			
		||||
* @brief support kd233-board init configure and start-up
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-07-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
File name: board.c
 | 
			
		||||
Description: support edu-riscv64-board init configure and driver/task/... init
 | 
			
		||||
Others: https://canaan-creative.com/developer
 | 
			
		||||
History: 
 | 
			
		||||
1. Date: 2022-07-25
 | 
			
		||||
Author: AIIT XUOS Lab
 | 
			
		||||
Modification: 
 | 
			
		||||
1. support edu-riscv64-board InitBoardHardware
 | 
			
		||||
2. support edu-riscv64-board Kd233Start
 | 
			
		||||
3. support edu-riscv64-board shell cmd, include reboot, shutdown
 | 
			
		||||
*************************************************/
 | 
			
		||||
 | 
			
		||||
#include <xizi.h>
 | 
			
		||||
#include <clint.h>
 | 
			
		||||
#include <sysctl.h>
 | 
			
		||||
#include "board.h"
 | 
			
		||||
#include "tick.h"
 | 
			
		||||
#include "connect_uart.h"
 | 
			
		||||
#include "encoding.h"
 | 
			
		||||
#include "fpioa.h"
 | 
			
		||||
#include "dmac.h"
 | 
			
		||||
#include "connect_gpio.h"
 | 
			
		||||
 | 
			
		||||
#if defined(FS_VFS)
 | 
			
		||||
#include <iot-vfs.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CPU0    (0)
 | 
			
		||||
#define CPU1    (1)
 | 
			
		||||
extern x_base cpu2_boot_flag;
 | 
			
		||||
extern void entry(void);
 | 
			
		||||
extern void SecondaryCpuCStart(void);
 | 
			
		||||
extern int IoConfigInit(void);
 | 
			
		||||
extern int HwI2cInit(void);
 | 
			
		||||
extern int HwTouchInit(void);
 | 
			
		||||
extern int HwCh376Init(void);
 | 
			
		||||
extern int HwLcdInit(void);
 | 
			
		||||
extern int HwSpiInit(void);
 | 
			
		||||
 | 
			
		||||
#ifdef FS_CH376
 | 
			
		||||
#include <iot-vfs.h>
 | 
			
		||||
#ifdef MOUNT_USB
 | 
			
		||||
/**
 | 
			
		||||
 * @description: Mount USB
 | 
			
		||||
 * @return 0
 | 
			
		||||
 */
 | 
			
		||||
int  MountUSB(void)
 | 
			
		||||
{
 | 
			
		||||
    if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, FSTYPE_CH376, "/") == 0)
 | 
			
		||||
        KPrintf("usb mount to '/'\n");
 | 
			
		||||
    else
 | 
			
		||||
        KPrintf("usb mount to '/' failed!\n");
 | 
			
		||||
    
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef MOUNT_SDCARD
 | 
			
		||||
/**
 | 
			
		||||
 * @description: Mount SD card
 | 
			
		||||
 * @return 0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int  MountSDCard(void)
 | 
			
		||||
{
 | 
			
		||||
    if (MountFilesystem(SDIO_BUS_NAME,SDIO_DEVICE_NAME ,SDIO_DRIVER_NAME , FSTYPE_CH376, "/") == 0)
 | 
			
		||||
        KPrintf("sd card mount to '/'\n");
 | 
			
		||||
    else
 | 
			
		||||
        KPrintf("sd card mount to '/' failed!\n");
 | 
			
		||||
    
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void InitBss(void)
 | 
			
		||||
{
 | 
			
		||||
    unsigned int *dst;
 | 
			
		||||
 | 
			
		||||
    dst = &__bss_start;
 | 
			
		||||
    while (dst < &__bss_end){
 | 
			
		||||
        *dst++ = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Kd233Start(uint32_t mhartid)
 | 
			
		||||
{
 | 
			
		||||
	switch(mhartid) {
 | 
			
		||||
		case CPU0:
 | 
			
		||||
    		InitBss();
 | 
			
		||||
 | 
			
		||||
			/*kernel start entry*/
 | 
			
		||||
    		entry();
 | 
			
		||||
			break;
 | 
			
		||||
		case CPU1:
 | 
			
		||||
			while(0x2018050420191010 != cpu2_boot_flag) { ///< waiting for boot flag ,then start cpu1 core
 | 
			
		||||
#ifndef ARCH_SMP
 | 
			
		||||
				asm volatile("wfi");
 | 
			
		||||
#endif
 | 
			
		||||
			}
 | 
			
		||||
#ifdef ARCH_SMP
 | 
			
		||||
			SecondaryCpuCStart();
 | 
			
		||||
#endif
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Freq(void)
 | 
			
		||||
{
 | 
			
		||||
    uint64 value = 0;
 | 
			
		||||
 | 
			
		||||
    value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL0);
 | 
			
		||||
    KPrintf("PLL0: %d\n", value);
 | 
			
		||||
    value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL1);
 | 
			
		||||
    KPrintf("PLL1: %d\n", value);
 | 
			
		||||
    value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL2);
 | 
			
		||||
    KPrintf("PLL2: %d\n", value);
 | 
			
		||||
    value = SysctlClockGetFreq(SYSCTL_CLOCK_CPU);
 | 
			
		||||
    KPrintf("CPU : %d\n", value);
 | 
			
		||||
    value = SysctlClockGetFreq(SYSCTL_CLOCK_APB0);
 | 
			
		||||
    KPrintf("APB0: %d\n", value);
 | 
			
		||||
    value = SysctlClockGetFreq(SYSCTL_CLOCK_APB1);
 | 
			
		||||
    KPrintf("APB1: %d\n", value);
 | 
			
		||||
    value = SysctlClockGetFreq(SYSCTL_CLOCK_APB2);
 | 
			
		||||
    KPrintf("APB2: %d\n", value);
 | 
			
		||||
    value = SysctlClockGetFreq(SYSCTL_CLOCK_HCLK);
 | 
			
		||||
    KPrintf("HCLK: %d\n", value);
 | 
			
		||||
 | 
			
		||||
    value = clint_get_time();
 | 
			
		||||
    KPrintf("mtime: %d\n", value);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),Freq, Freq, show frequency information );
 | 
			
		||||
 | 
			
		||||
#ifdef ARCH_SMP
 | 
			
		||||
extern int EnableHwclintIpi(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct InitSequenceDesc _board_init[] = 
 | 
			
		||||
{
 | 
			
		||||
#ifdef BSP_USING_GPIO
 | 
			
		||||
    { "hw_pin", HwGpioInit },
 | 
			
		||||
	{ "io_config", IoConfigInit },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_USING_I2C
 | 
			
		||||
    { "hw_i2c", HwI2cInit },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_USING_SPI
 | 
			
		||||
	{ "hw_spi", HwSpiInit },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_USING_LCD
 | 
			
		||||
	{ "hw_lcd", HwLcdInit },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_USING_USB
 | 
			
		||||
    { "hw_usb", HwCh376Init},
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_USING_TOUCH
 | 
			
		||||
    {"touch", HwTouchInit },
 | 
			
		||||
#endif
 | 
			
		||||
    { " NONE ",NONE },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void InitBoardHardware(void)
 | 
			
		||||
{
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	
 | 
			
		||||
    SysctlPllSetFreq(SYSCTL_PLL0, 800000000UL);
 | 
			
		||||
    SysctlPllSetFreq(SYSCTL_PLL1, 400000000UL);
 | 
			
		||||
#ifdef BSP_USING_GPIO
 | 
			
		||||
    /* Init FPIOA */
 | 
			
		||||
    FpioaInit();
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_USING_DMA
 | 
			
		||||
    /* Dmac init */
 | 
			
		||||
    DmacInit();
 | 
			
		||||
#endif
 | 
			
		||||
    /* initalize interrupt */
 | 
			
		||||
    InitHwinterrupt();
 | 
			
		||||
#ifdef BSP_USING_UART    
 | 
			
		||||
    HwUartInit();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* initialize memory system */
 | 
			
		||||
	InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS);
 | 
			
		||||
 | 
			
		||||
#ifdef KERNEL_CONSOLE
 | 
			
		||||
    /* set console device */
 | 
			
		||||
    InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME);
 | 
			
		||||
	KPrintf("\nconsole init completed.\n");
 | 
			
		||||
    KPrintf("board initialization......\n");
 | 
			
		||||
#endif /* KERNEL_CONSOLE */
 | 
			
		||||
 | 
			
		||||
    InitHwTick();
 | 
			
		||||
 | 
			
		||||
#ifdef ARCH_SMP
 | 
			
		||||
    EnableHwclintIpi();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef KERNEL_COMPONENTS_INIT
 | 
			
		||||
	for(i = 0; _board_init[i].fn != NONE; i++) {
 | 
			
		||||
		ret = _board_init[i].fn();
 | 
			
		||||
		KPrintf("initialize %s %s\n",_board_init[i].fn_name, ret == 0 ? "success" : "failed");
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	KPrintf("board init done.\n");
 | 
			
		||||
	KPrintf("start kernel...\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HwCpuReset(void)
 | 
			
		||||
{
 | 
			
		||||
    sysctl->soft_reset.soft_reset = 1;
 | 
			
		||||
    while(RET_TRUE);
 | 
			
		||||
}
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),Reboot, HwCpuReset,  reset machine );
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,91 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 board.h
 | 
			
		||||
* @brief define edu-riscv64-board init configure and start-up function
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-07-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
File name: board.h
 | 
			
		||||
Description: define edu-riscv64-board board init function and struct
 | 
			
		||||
Others: https://canaan-creative.com/developer
 | 
			
		||||
History: 
 | 
			
		||||
1. Date: 2022-07-25
 | 
			
		||||
Author: AIIT XUOS Lab
 | 
			
		||||
Modification: 
 | 
			
		||||
1. define edu-riscv64-board InitBoardHardware
 | 
			
		||||
2. define edu-riscv64-board data and bss struct
 | 
			
		||||
*************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef BOARD_H__
 | 
			
		||||
#define BOARD_H__
 | 
			
		||||
 | 
			
		||||
#include <xsconfig.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
// #include "../../kernel/include/xs_service.h"
 | 
			
		||||
 | 
			
		||||
extern unsigned int __bss_start;
 | 
			
		||||
extern unsigned int __bss_end;
 | 
			
		||||
extern unsigned int __stack_end__;
 | 
			
		||||
extern unsigned int g_service_table_start;
 | 
			
		||||
extern unsigned int g_service_table_end;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef SEPARATE_COMPILE
 | 
			
		||||
#define G_SERVICE_TABLE_LENGTH (0x1000)
 | 
			
		||||
 | 
			
		||||
#define MEMORY_START_ADDRESS    (void*)&__stack_end__
 | 
			
		||||
#define MEMORY_END_ADDRESS      (void*)((0x80000000 + 1 * 1024 * 1024)) /* 1M SRAM */
 | 
			
		||||
 | 
			
		||||
typedef int (*main_t)(int argc, char *argv[]);
 | 
			
		||||
typedef void (*exit_t)(void);
 | 
			
		||||
struct UserSpaceS
 | 
			
		||||
{
 | 
			
		||||
  main_t    us_entrypoint;
 | 
			
		||||
  exit_t    us_taskquit;
 | 
			
		||||
  uintptr_t us_textstart;
 | 
			
		||||
  uintptr_t us_textend;
 | 
			
		||||
  uintptr_t us_datasource;
 | 
			
		||||
  uintptr_t us_datastart;
 | 
			
		||||
  uintptr_t us_dataend;
 | 
			
		||||
  uintptr_t us_bssstart;
 | 
			
		||||
  uintptr_t us_bssend;
 | 
			
		||||
  uintptr_t us_heapend;
 | 
			
		||||
};
 | 
			
		||||
#define USERSPACE (( struct UserSpaceS *)(MEMORY_END_ADDRESS + G_SERVICE_TABLE_LENGTH))
 | 
			
		||||
 | 
			
		||||
#ifndef SERVICE_TABLE_ADDRESS
 | 
			
		||||
#define SERVICE_TABLE_ADDRESS    (0x80100000)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define USER_MEMORY_START_ADDRESS (USERSPACE->us_bssend)
 | 
			
		||||
 | 
			
		||||
#define USER_MEMORY_END_ADDRESS         (void*)((0x80000000 + 6 * 1024 * 1024) )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#define MEMORY_START_ADDRESS    (void*)&__stack_end__
 | 
			
		||||
#define MEMORY_END_ADDRESS      (void*)(0x80000000 + 6 * 1024 * 1024)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void InitBoardHardware(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
export CFLAGS := -mcmodel=medany -march=rv64imafdc -mabi=lp64d -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -O0 -ggdb -fgnu89-inline -Werror
 | 
			
		||||
export AFLAGS := -c -mcmodel=medany -march=rv64imafdc -mabi=lp64d -x assembler-with-cpp -ggdb
 | 
			
		||||
export LFLAGS := -mcmodel=medany -march=rv64imafdc -mabi=lp64d -nostartfiles -Wl,--gc-sections,-Map=XiZi-edu-riscv64.map,-cref,-u,_start -T $(BSP_ROOT)/link.lds
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_LIB_MUSLLIB), y)
 | 
			
		||||
export LFLAGS += -nostdlib -nostdinc # -fno-builtin -nodefaultlibs
 | 
			
		||||
export LIBCC := -lgcc
 | 
			
		||||
export LINK_MUSLLIB := $(KERNEL_ROOT)/lib/musllib/libmusl.a
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_RESOURCES_LWIP), y)
 | 
			
		||||
export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
export APPLFLAGS := -mcmodel=medany -march=rv64imafdc -mabi=lp64d -nostartfiles -Wl,--gc-sections,-Map=XiZi-edu-riscv64.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
 | 
			
		||||
 | 
			
		||||
export CXXFLAGS := -mcmodel=medany -march=rv64imafdc -mabi=lp64d -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -O0 -ggdb -Werror
 | 
			
		||||
 | 
			
		||||
export CROSS_COMPILE ?=/opt/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.1-20190425-1021/bin/riscv-none-embed-
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export DEFINES := -DHAVE_CCONFIG_H -DHAVE_SIGINFO
 | 
			
		||||
 | 
			
		||||
export ARCH = risc-v
 | 
			
		||||
export MCU =  k210
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
		 After Width: | Height: | Size: 984 KiB  | 
| 
		 After Width: | Height: | Size: 122 KiB  | 
| 
		 After Width: | Height: | Size: 35 KiB  | 
| 
		 After Width: | Height: | Size: 108 KiB  | 
| 
		 After Width: | Height: | Size: 24 KiB  | 
| 
		 After Width: | Height: | Size: 278 KiB  | 
| 
		 After Width: | Height: | Size: 177 KiB  | 
| 
		 After Width: | Height: | Size: 56 KiB  | 
| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 bsp.h
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _KENDRYTE_BSP_H
 | 
			
		||||
#define _KENDRYTE_BSP_H
 | 
			
		||||
#include "bsp_atomic.h"
 | 
			
		||||
#include "entry.h"
 | 
			
		||||
#include "sleep.h"
 | 
			
		||||
#include "encoding.h"
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,253 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 atomic.h
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _BSP_ATOMIC_H
 | 
			
		||||
#define _BSP_ATOMIC_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define SPINLOCK_INIT \
 | 
			
		||||
    {                 \
 | 
			
		||||
        0             \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define CORELOCK_INIT          \
 | 
			
		||||
    {                          \
 | 
			
		||||
        .lock = SPINLOCK_INIT, \
 | 
			
		||||
        .count = 0,            \
 | 
			
		||||
        .core = -1             \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Defination of memory barrier macro */
 | 
			
		||||
#define mb()                          \
 | 
			
		||||
    {                                 \
 | 
			
		||||
        asm volatile("fence" ::       \
 | 
			
		||||
                         : "memory"); \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define atomic_set(ptr, val) (*(volatile typeof(*(ptr))*)(ptr) = val)
 | 
			
		||||
#define atomic_read(ptr) (*(volatile typeof(*(ptr))*)(ptr))
 | 
			
		||||
 | 
			
		||||
#ifndef __riscv_atomic
 | 
			
		||||
#error "atomic extension is required."
 | 
			
		||||
#endif
 | 
			
		||||
#define atomic_add(ptr, inc) __sync_fetch_and_add(ptr, inc)
 | 
			
		||||
#define atomic_or(ptr, inc) __sync_fetch_and_or(ptr, inc)
 | 
			
		||||
#define atomic_swap(ptr, swp) __sync_lock_test_and_set(ptr, swp)
 | 
			
		||||
#define atomic_cas(ptr, cmp, swp) __sync_val_compare_and_swap(ptr, cmp, swp)
 | 
			
		||||
 | 
			
		||||
typedef struct _spinlock
 | 
			
		||||
{
 | 
			
		||||
    int lock;
 | 
			
		||||
} spinlock_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _semaphore
 | 
			
		||||
{
 | 
			
		||||
    spinlock_t lock;
 | 
			
		||||
    int count;
 | 
			
		||||
    int waiting;
 | 
			
		||||
} semaphore_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _corelock
 | 
			
		||||
{
 | 
			
		||||
    spinlock_t lock;
 | 
			
		||||
    int count;
 | 
			
		||||
    int core;
 | 
			
		||||
} corelock_t;
 | 
			
		||||
 | 
			
		||||
static inline int spinlock_trylock(spinlock_t *lock)
 | 
			
		||||
{
 | 
			
		||||
    int res = atomic_swap(&lock->lock, -1);
 | 
			
		||||
    /* Use memory barrier to keep coherency */
 | 
			
		||||
    mb();
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void spinlock_lock(spinlock_t *lock)
 | 
			
		||||
{
 | 
			
		||||
    while (spinlock_trylock(lock));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void spinlock_unlock(spinlock_t *lock)
 | 
			
		||||
{
 | 
			
		||||
    /* Use memory barrier to keep coherency */
 | 
			
		||||
    mb();
 | 
			
		||||
    atomic_set(&lock->lock, 0);
 | 
			
		||||
    asm volatile ("nop");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void semaphore_signal(semaphore_t *semaphore, int i)
 | 
			
		||||
{
 | 
			
		||||
    spinlock_lock(&(semaphore->lock));
 | 
			
		||||
    semaphore->count += i;
 | 
			
		||||
    spinlock_unlock(&(semaphore->lock));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void semaphore_wait(semaphore_t *semaphore, int i)
 | 
			
		||||
{
 | 
			
		||||
    atomic_add(&(semaphore->waiting), 1);
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
        spinlock_lock(&(semaphore->lock));
 | 
			
		||||
        if (semaphore->count >= i)
 | 
			
		||||
        {
 | 
			
		||||
            semaphore->count -= i;
 | 
			
		||||
            atomic_add(&(semaphore->waiting), -1);
 | 
			
		||||
            spinlock_unlock(&(semaphore->lock));
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        spinlock_unlock(&(semaphore->lock));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int semaphore_count(semaphore_t *semaphore)
 | 
			
		||||
{
 | 
			
		||||
    int res = 0;
 | 
			
		||||
 | 
			
		||||
    spinlock_lock(&(semaphore->lock));
 | 
			
		||||
    res = semaphore->count;
 | 
			
		||||
    spinlock_unlock(&(semaphore->lock));
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int semaphore_waiting(semaphore_t *semaphore)
 | 
			
		||||
{
 | 
			
		||||
    return atomic_read(&(semaphore->waiting));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int corelock_trylock(corelock_t *lock)
 | 
			
		||||
{
 | 
			
		||||
    int res = 0;
 | 
			
		||||
    unsigned long core;
 | 
			
		||||
 | 
			
		||||
    asm volatile("csrr %0, mhartid;"
 | 
			
		||||
                 : "=r"(core));
 | 
			
		||||
    if(spinlock_trylock(&lock->lock))
 | 
			
		||||
    {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (lock->count == 0)
 | 
			
		||||
    {
 | 
			
		||||
        /* First time get lock */
 | 
			
		||||
        lock->count++;
 | 
			
		||||
        lock->core = core;
 | 
			
		||||
        res = 0;
 | 
			
		||||
    }
 | 
			
		||||
    else if (lock->core == core)
 | 
			
		||||
    {
 | 
			
		||||
        /* Same core get lock */
 | 
			
		||||
        lock->count++;
 | 
			
		||||
        res = 0;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        /* Different core get lock */
 | 
			
		||||
        res = -1;
 | 
			
		||||
    }
 | 
			
		||||
    spinlock_unlock(&lock->lock);
 | 
			
		||||
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void corelock_lock(corelock_t *lock)
 | 
			
		||||
{
 | 
			
		||||
    unsigned long core;
 | 
			
		||||
 | 
			
		||||
    asm volatile("csrr %0, mhartid;"
 | 
			
		||||
                 : "=r"(core));
 | 
			
		||||
    spinlock_lock(&lock->lock);
 | 
			
		||||
 | 
			
		||||
    if (lock->count == 0)
 | 
			
		||||
    {
 | 
			
		||||
        /* First time get lock */
 | 
			
		||||
        lock->count++;
 | 
			
		||||
        lock->core = core;
 | 
			
		||||
    }
 | 
			
		||||
    else if (lock->core == core)
 | 
			
		||||
    {
 | 
			
		||||
        /* Same core get lock */
 | 
			
		||||
        lock->count++;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        /* Different core get lock */
 | 
			
		||||
        spinlock_unlock(&lock->lock);
 | 
			
		||||
 | 
			
		||||
        do
 | 
			
		||||
        {
 | 
			
		||||
            while (atomic_read(&lock->count))
 | 
			
		||||
                ;
 | 
			
		||||
        } while (corelock_trylock(lock));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    spinlock_unlock(&lock->lock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void corelock_unlock(corelock_t *lock)
 | 
			
		||||
{
 | 
			
		||||
    unsigned long core;
 | 
			
		||||
 | 
			
		||||
    asm volatile("csrr %0, mhartid;"
 | 
			
		||||
                 : "=r"(core));
 | 
			
		||||
    spinlock_lock(&lock->lock);
 | 
			
		||||
 | 
			
		||||
    if (lock->core == core)
 | 
			
		||||
    {
 | 
			
		||||
        /* Same core release lock */
 | 
			
		||||
        lock->count--;
 | 
			
		||||
        if (lock->count <= 0)
 | 
			
		||||
        {
 | 
			
		||||
            lock->core = -1;
 | 
			
		||||
            lock->count = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        /* Different core release lock */
 | 
			
		||||
        spinlock_unlock(&lock->lock);
 | 
			
		||||
 | 
			
		||||
        register unsigned long a7 asm("a7") = 93;
 | 
			
		||||
        register unsigned long a0 asm("a0") = 0;
 | 
			
		||||
        register unsigned long a1 asm("a1") = 0;
 | 
			
		||||
        register unsigned long a2 asm("a2") = 0;
 | 
			
		||||
 | 
			
		||||
        asm volatile("scall"
 | 
			
		||||
                     : "+r"(a0)
 | 
			
		||||
                     : "r"(a1), "r"(a2), "r"(a7));
 | 
			
		||||
    }
 | 
			
		||||
    spinlock_unlock(&lock->lock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* _BSP_ATOMIC_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,150 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 dump.h
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _BSP_DUMP_H
 | 
			
		||||
#define _BSP_DUMP_H
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "syslog.h"
 | 
			
		||||
#include "hardware_uarths.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DUMP_PRINTF printk
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
dump_core(const char *reason, uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32])
 | 
			
		||||
{
 | 
			
		||||
    static const char *const reg_usage[][2] =
 | 
			
		||||
    {
 | 
			
		||||
        {"zero ", "Hard-wired zero"},
 | 
			
		||||
        {"ra   ", "Return address"},
 | 
			
		||||
        {"sp   ", "Stack pointer"},
 | 
			
		||||
        {"gp   ", "Global pointer"},
 | 
			
		||||
        {"tp   ", "Task pointer"},
 | 
			
		||||
        {"t0   ", "Temporaries Caller"},
 | 
			
		||||
        {"t1   ", "Temporaries Caller"},
 | 
			
		||||
        {"t2   ", "Temporaries Caller"},
 | 
			
		||||
        {"s0/fp", "Saved register/frame pointer"},
 | 
			
		||||
        {"s1   ", "Saved register"},
 | 
			
		||||
        {"a0   ", "Function arguments/return values"},
 | 
			
		||||
        {"a1   ", "Function arguments/return values"},
 | 
			
		||||
        {"a2   ", "Function arguments values"},
 | 
			
		||||
        {"a3   ", "Function arguments values"},
 | 
			
		||||
        {"a4   ", "Function arguments values"},
 | 
			
		||||
        {"a5   ", "Function arguments values"},
 | 
			
		||||
        {"a6   ", "Function arguments values"},
 | 
			
		||||
        {"a7   ", "Function arguments values"},
 | 
			
		||||
        {"s2   ", "Saved registers"},
 | 
			
		||||
        {"s3   ", "Saved registers"},
 | 
			
		||||
        {"s4   ", "Saved registers"},
 | 
			
		||||
        {"s5   ", "Saved registers"},
 | 
			
		||||
        {"s6   ", "Saved registers"},
 | 
			
		||||
        {"s7   ", "Saved registers"},
 | 
			
		||||
        {"s8   ", "Saved registers"},
 | 
			
		||||
        {"s9   ", "Saved registers"},
 | 
			
		||||
        {"s10  ", "Saved registers"},
 | 
			
		||||
        {"s11  ", "Saved registers"},
 | 
			
		||||
        {"t3   ", "Temporaries Caller"},
 | 
			
		||||
        {"t4   ", "Temporaries Caller"},
 | 
			
		||||
        {"t5   ", "Temporaries Caller"},
 | 
			
		||||
        {"t6   ", "Temporaries Caller"},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static const char *const regf_usage[][2] =
 | 
			
		||||
    {
 | 
			
		||||
        {"ft0 ", "FP temporaries"},
 | 
			
		||||
        {"ft1 ", "FP temporaries"},
 | 
			
		||||
        {"ft2 ", "FP temporaries"},
 | 
			
		||||
        {"ft3 ", "FP temporaries"},
 | 
			
		||||
        {"ft4 ", "FP temporaries"},
 | 
			
		||||
        {"ft5 ", "FP temporaries"},
 | 
			
		||||
        {"ft6 ", "FP temporaries"},
 | 
			
		||||
        {"ft7 ", "FP temporaries"},
 | 
			
		||||
        {"fs0 ", "FP saved registers"},
 | 
			
		||||
        {"fs1 ", "FP saved registers"},
 | 
			
		||||
        {"fa0 ", "FP arguments/return values"},
 | 
			
		||||
        {"fa1 ", "FP arguments/return values"},
 | 
			
		||||
        {"fa2 ", "FP arguments values"},
 | 
			
		||||
        {"fa3 ", "FP arguments values"},
 | 
			
		||||
        {"fa4 ", "FP arguments values"},
 | 
			
		||||
        {"fa5 ", "FP arguments values"},
 | 
			
		||||
        {"fa6 ", "FP arguments values"},
 | 
			
		||||
        {"fa7 ", "FP arguments values"},
 | 
			
		||||
        {"fs2 ", "FP Saved registers"},
 | 
			
		||||
        {"fs3 ", "FP Saved registers"},
 | 
			
		||||
        {"fs4 ", "FP Saved registers"},
 | 
			
		||||
        {"fs5 ", "FP Saved registers"},
 | 
			
		||||
        {"fs6 ", "FP Saved registers"},
 | 
			
		||||
        {"fs7 ", "FP Saved registers"},
 | 
			
		||||
        {"fs8 ", "FP Saved registers"},
 | 
			
		||||
        {"fs9 ", "FP Saved registers"},
 | 
			
		||||
        {"fs10", "FP Saved registers"},
 | 
			
		||||
        {"fs11", "FP Saved registers"},
 | 
			
		||||
        {"ft8 ", "FP Temporaries Caller"},
 | 
			
		||||
        {"ft9 ", "FP Temporaries Caller"},
 | 
			
		||||
        {"ft10", "FP Temporaries Caller"},
 | 
			
		||||
        {"ft11", "FP Temporaries Caller"},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (CONFIG_LOG_LEVEL >= LOG_ERROR)
 | 
			
		||||
    {
 | 
			
		||||
        const char unknown_reason[] = "unknown";
 | 
			
		||||
 | 
			
		||||
        if (!reason)
 | 
			
		||||
            reason = unknown_reason;
 | 
			
		||||
 | 
			
		||||
        DUMP_PRINTF("core dump: %s\r\n", reason);
 | 
			
		||||
        DUMP_PRINTF("Cause 0x%016lx, EPC 0x%016lx\r\n", cause, epc);
 | 
			
		||||
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        for (i = 0; i < 32 / 2; i++)
 | 
			
		||||
        {
 | 
			
		||||
            DUMP_PRINTF(
 | 
			
		||||
                "reg[%02d](%s) = 0x%016lx, reg[%02d](%s) = 0x%016lx\r\n",
 | 
			
		||||
                i * 2, reg_usage[i * 2][0], regs[i * 2],
 | 
			
		||||
                i * 2 + 1, reg_usage[i * 2 + 1][0], regs[i * 2 + 1]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (i = 0; i < 32 / 2; i++)
 | 
			
		||||
        {
 | 
			
		||||
            DUMP_PRINTF(
 | 
			
		||||
                "freg[%02d](%s) = 0x%016lx(%f), freg[%02d](%s) = 0x%016lx(%f)\r\n",
 | 
			
		||||
                i * 2, regf_usage[i * 2][0], fregs[i * 2], (float)fregs[i * 2],
 | 
			
		||||
                i * 2 + 1, regf_usage[i * 2 + 1][0], fregs[i * 2 + 1], (float)fregs[i * 2 + 1]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef DUMP_PRINTF
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* _BSP_DUMP_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,90 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 entry.h
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _BSP_ENTRY_H
 | 
			
		||||
#define _BSP_ENTRY_H
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef int (*core_function)(void *ctx);
 | 
			
		||||
 | 
			
		||||
typedef struct _core_instance_t
 | 
			
		||||
{
 | 
			
		||||
    core_function callback;
 | 
			
		||||
    void *ctx;
 | 
			
		||||
} core_instance_t;
 | 
			
		||||
 | 
			
		||||
int register_core1(core_function func, void *ctx);
 | 
			
		||||
 | 
			
		||||
static inline void init_lma(void)
 | 
			
		||||
{
 | 
			
		||||
    extern unsigned int _data_lma;
 | 
			
		||||
    extern unsigned int _data;
 | 
			
		||||
    extern unsigned int _edata;
 | 
			
		||||
    unsigned int *src, *dst;
 | 
			
		||||
 | 
			
		||||
    src = &_data_lma;
 | 
			
		||||
    dst = &_data;
 | 
			
		||||
    while (dst < &_edata)
 | 
			
		||||
        *dst++ = *src++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void InitBss(void)
 | 
			
		||||
{
 | 
			
		||||
    extern unsigned int _bss;
 | 
			
		||||
    extern unsigned int _ebss;
 | 
			
		||||
    unsigned int *dst;
 | 
			
		||||
 | 
			
		||||
    dst = &_bss;
 | 
			
		||||
    while (dst < &_ebss)
 | 
			
		||||
        *dst++ = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void init_tls(void)
 | 
			
		||||
{
 | 
			
		||||
    register void *task_pointer asm("tp");
 | 
			
		||||
    extern char _tls_data;
 | 
			
		||||
 | 
			
		||||
    extern __thread char _tdata_begin, _tdata_end, _tbss_end;
 | 
			
		||||
 | 
			
		||||
    size_t tdata_size = &_tdata_end - &_tdata_begin;
 | 
			
		||||
 | 
			
		||||
    memcpy(task_pointer, &_tls_data, tdata_size);
 | 
			
		||||
 | 
			
		||||
    size_t tbss_size = &_tbss_end - &_tdata_end;
 | 
			
		||||
 | 
			
		||||
    memset(task_pointer + tdata_size, 0, tbss_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* _BSP_ENTRY_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 interrupt.h
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _BSP_INTERRUPT_H
 | 
			
		||||
#define _BSP_INTERRUPT_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
/* clang-format off */
 | 
			
		||||
/* Machine interrupt mask for 64 bit system, 0x8000 0000 0000 0000 */
 | 
			
		||||
#define CAUSE_MACHINE_IRQ_MASK            (0x1ULL << 63)
 | 
			
		||||
 | 
			
		||||
/* Machine interrupt reason mask for 64 bit system, 0x7FFF FFFF FFFF FFFF */
 | 
			
		||||
#define CAUSE_MACHINE_IRQ_REASON_MASK     (CAUSE_MACHINE_IRQ_MASK - 1)
 | 
			
		||||
 | 
			
		||||
/* Hypervisor interrupt mask for 64 bit system, 0x8000 0000 0000 0000 */
 | 
			
		||||
#define CAUSE_HYPERVISOR_IRQ_MASK         (0x1ULL << 63)
 | 
			
		||||
 | 
			
		||||
/* Hypervisor interrupt reason mask for 64 bit system, 0x7FFF FFFF FFFF FFFF */
 | 
			
		||||
#define CAUSE_HYPERVISOR_IRQ_REASON_MASK  (CAUSE_HYPERVISOR_IRQ_MASK - 1)
 | 
			
		||||
 | 
			
		||||
/* Supervisor interrupt mask for 64 bit system, 0x8000 0000 0000 0000 */
 | 
			
		||||
#define CAUSE_SUPERVISOR_IRQ_MASK         (0x1ULL << 63)
 | 
			
		||||
 | 
			
		||||
/* Supervisor interrupt reason mask for 64 bit system, 0x7FFF FFFF FFFF FFFF */
 | 
			
		||||
#define CAUSE_SUPERVISOR_IRQ_REASON_MASK  (CAUSE_SUPERVISOR_IRQ_MASK - 1)
 | 
			
		||||
/* clang-format on */
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* _BSP_INTERRUPT_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,108 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 platform.h
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _BSP_PLATFORM_H
 | 
			
		||||
#define _BSP_PLATFORM_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* clang-format off */
 | 
			
		||||
/* Register base address */
 | 
			
		||||
 | 
			
		||||
/* Under Coreplex */
 | 
			
		||||
#define CLINT_BASE_ADDR     (0x02000000U)
 | 
			
		||||
#define PLIC_BASE_ADDR      (0x0C000000U)
 | 
			
		||||
 | 
			
		||||
/* Under TileLink */
 | 
			
		||||
#define UARTHS_BASE_ADDR    (0x38000000U)
 | 
			
		||||
#define GPIOHS_BASE_ADDR    (0x38001000U)
 | 
			
		||||
 | 
			
		||||
/* Under AXI 64 bit */
 | 
			
		||||
#define RAM_BASE_ADDR       (0x80000000U)
 | 
			
		||||
#define RAM_SIZE            (6 * 1024 * 1024U)
 | 
			
		||||
 | 
			
		||||
#define IO_BASE_ADDR        (0x40000000U)
 | 
			
		||||
#define IO_SIZE             (6 * 1024 * 1024U)
 | 
			
		||||
 | 
			
		||||
#define AI_RAM_BASE_ADDR    (0x80600000U)
 | 
			
		||||
#define AI_RAM_SIZE         (2 * 1024 * 1024U)
 | 
			
		||||
 | 
			
		||||
#define AI_IO_BASE_ADDR     (0x40600000U)
 | 
			
		||||
#define AI_IO_SIZE          (2 * 1024 * 1024U)
 | 
			
		||||
 | 
			
		||||
#define AI_BASE_ADDR        (0x40800000U)
 | 
			
		||||
#define AI_SIZE             (12 * 1024 * 1024U)
 | 
			
		||||
 | 
			
		||||
#define FFT_BASE_ADDR       (0x42000000U)
 | 
			
		||||
#define FFT_SIZE            (4 * 1024 * 1024U)
 | 
			
		||||
 | 
			
		||||
#define ROM_BASE_ADDR       (0x88000000U)
 | 
			
		||||
#define ROM_SIZE            (128 * 1024U)
 | 
			
		||||
 | 
			
		||||
/* Under AHB 32 bit */
 | 
			
		||||
#define DMAC_BASE_ADDR      (0x50000000U)
 | 
			
		||||
 | 
			
		||||
/* Under APB1 32 bit */
 | 
			
		||||
#define GPIO_BASE_ADDR      (0x50200000U)
 | 
			
		||||
#define UART1_BASE_ADDR     (0x50210000U)
 | 
			
		||||
#define UART2_BASE_ADDR     (0x50220000U)
 | 
			
		||||
#define UART3_BASE_ADDR     (0x50230000U)
 | 
			
		||||
#define SPI_SLAVE_BASE_ADDR (0x50240000U)
 | 
			
		||||
#define I2S0_BASE_ADDR      (0x50250000U)
 | 
			
		||||
#define I2S1_BASE_ADDR      (0x50260000U)
 | 
			
		||||
#define I2S2_BASE_ADDR      (0x50270000U)
 | 
			
		||||
#define I2C0_BASE_ADDR      (0x50280000U)
 | 
			
		||||
#define I2C1_BASE_ADDR      (0x50290000U)
 | 
			
		||||
#define I2C2_BASE_ADDR      (0x502A0000U)
 | 
			
		||||
#define FPIOA_BASE_ADDR     (0x502B0000U)
 | 
			
		||||
#define SHA256_BASE_ADDR    (0x502C0000U)
 | 
			
		||||
#define TIMER0_BASE_ADDR    (0x502D0000U)
 | 
			
		||||
#define TIMER1_BASE_ADDR    (0x502E0000U)
 | 
			
		||||
#define TIMER2_BASE_ADDR    (0x502F0000U)
 | 
			
		||||
 | 
			
		||||
/* Under APB2 32 bit */
 | 
			
		||||
#define WDT0_BASE_ADDR      (0x50400000U)
 | 
			
		||||
#define WDT1_BASE_ADDR      (0x50410000U)
 | 
			
		||||
#define OTP_BASE_ADDR       (0x50420000U)
 | 
			
		||||
#define DVP_BASE_ADDR       (0x50430000U)
 | 
			
		||||
#define SYSCTL_BASE_ADDR    (0x50440000U)
 | 
			
		||||
#define AES_BASE_ADDR       (0x50450000U)
 | 
			
		||||
#define RTC_BASE_ADDR       (0x50460000U)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Under APB3 32 bit */
 | 
			
		||||
#define SPI0_BASE_ADDR      (0x52000000U)
 | 
			
		||||
#define SPI1_BASE_ADDR      (0x53000000U)
 | 
			
		||||
#define SPI3_BASE_ADDR      (0x54000000U)
 | 
			
		||||
 | 
			
		||||
/* clang-format on */
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* _BSP_PLATFORM_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,218 @@
 | 
			
		|||
/**
 | 
			
		||||
 * File: printf.h
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of Kustaa Nyholm or SpareTimeLabs nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 | 
			
		||||
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this library; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 *
 | 
			
		||||
 * This library is really just two files: 'tinyprintf.h' and 'tinyprintf.c'.
 | 
			
		||||
 *
 | 
			
		||||
 * They provide a simple and small (+400 loc) printf functionality to be used
 | 
			
		||||
 * in embedded systems.
 | 
			
		||||
 *
 | 
			
		||||
 * I've found them so useful in debugging that I do not bother with a debugger
 | 
			
		||||
 * at all.
 | 
			
		||||
 *
 | 
			
		||||
 * They are distributed in source form, so to use them, just compile them into
 | 
			
		||||
 * your project.
 | 
			
		||||
 *
 | 
			
		||||
 * Two printf variants are provided: printf and the 'sprintf' family of
 | 
			
		||||
 * functions ('snprintf', 'sprintf', 'vsnprintf', 'vsprintf').
 | 
			
		||||
 *
 | 
			
		||||
 * The formats supported by this implementation are: 'c' 'd' 'i' 'o' 'p' 'u'
 | 
			
		||||
 * 's' 'x' 'X'.
 | 
			
		||||
 *
 | 
			
		||||
 * Zero padding, field width, and precision are also supported.
 | 
			
		||||
 *
 | 
			
		||||
 * If the library is compiled with 'PRINTF_SUPPORT_LONG' defined, then the
 | 
			
		||||
 * long specifier is also supported. Note that this will pull in some long
 | 
			
		||||
 * math routines (pun intended!) and thus make your executable noticeably
 | 
			
		||||
 * longer. Likewise with 'PRINTF_LONG_LONG_SUPPORT' for the long long
 | 
			
		||||
 * specifier, and with 'PRINTF_SIZE_T_SUPPORT' for the size_t specifier.
 | 
			
		||||
 *
 | 
			
		||||
 * The memory footprint of course depends on the target CPU, compiler and
 | 
			
		||||
 * compiler options, but a rough guesstimate (based on a H8S target) is about
 | 
			
		||||
 * 1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack
 | 
			
		||||
 * space. Not too bad. Your mileage may vary. By hacking the source code you
 | 
			
		||||
 * can get rid of some hundred bytes, I'm sure, but personally I feel the
 | 
			
		||||
 * balance of functionality and flexibility versus  code size is close to
 | 
			
		||||
 * optimal for many embedded systems.
 | 
			
		||||
 *
 | 
			
		||||
 * To use the printf, you need to supply your own character output function,
 | 
			
		||||
 * something like :
 | 
			
		||||
 *
 | 
			
		||||
 * void putc ( void* p, char c) { while (!SERIAL_PORT_EMPTY) ;
 | 
			
		||||
 * SERIAL_PORT_TX_REGISTER = c; }
 | 
			
		||||
 *
 | 
			
		||||
 * Before you can call printf, you need to initialize it to use your character
 | 
			
		||||
 * output function with something like:
 | 
			
		||||
 *
 | 
			
		||||
 * init_printf(NULL,putc);
 | 
			
		||||
 *
 | 
			
		||||
 * Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc',
 | 
			
		||||
 * the NULL (or any pointer) you pass into the 'init_printf' will eventually
 | 
			
		||||
 * be passed to your 'putc' routine. This allows you to pass some storage
 | 
			
		||||
 * space (or anything really) to the character output function, if necessary.
 | 
			
		||||
 * This is not often needed but it was implemented like that because it made
 | 
			
		||||
 * implementing the sprintf function so neat (look at the source code).
 | 
			
		||||
 *
 | 
			
		||||
 * The code is re-entrant, except for the 'init_printf' function, so it is
 | 
			
		||||
 * safe to call it from interrupts too, although this may result in mixed
 | 
			
		||||
 * output. If you rely on re-entrancy, take care that your 'putc' function is
 | 
			
		||||
 * re-entrant!
 | 
			
		||||
 *
 | 
			
		||||
 * The printf and sprintf functions are actually macros that translate to
 | 
			
		||||
 * 'tfp_printf' and 'tfp_sprintf' when 'TINYPRINTF_OVERRIDE_LIBC' is set
 | 
			
		||||
 * (default). Setting it to 0 makes it possible to use them along with
 | 
			
		||||
 * 'stdio.h' printf's in a single source file. When 'TINYPRINTF_OVERRIDE_LIBC'
 | 
			
		||||
 * is set, please note that printf/sprintf are not function-like macros, so if
 | 
			
		||||
 * you have variables or struct members with these names, things will explode
 | 
			
		||||
 * in your face.  Without variadic macros this is the best we can do to wrap
 | 
			
		||||
 * these function. If it is a problem, just give up the macros and use the
 | 
			
		||||
 * functions directly, or rename them.
 | 
			
		||||
 *
 | 
			
		||||
 * It is also possible to avoid defining tfp_printf and/or tfp_sprintf by
 | 
			
		||||
 * clearing 'TINYPRINTF_DEFINE_TFP_PRINTF' and/or
 | 
			
		||||
 * 'TINYPRINTF_DEFINE_TFP_SPRINTF' to 0. This allows for example to export
 | 
			
		||||
 * only tfp_format, which is at the core of all the other functions.
 | 
			
		||||
 *
 | 
			
		||||
 * For further details see source code.
 | 
			
		||||
 *
 | 
			
		||||
 * regs Kusti, 23.10.2004
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @file printf.h
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _BSP_PRINTF_H
 | 
			
		||||
#define _BSP_PRINTF_H
 | 
			
		||||
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
/* Global configuration */
 | 
			
		||||
 | 
			
		||||
/* Set this to 0 if you do not want to provide tfp_printf */
 | 
			
		||||
#ifndef TINYPRINTF_DEFINE_TFP_PRINTF
 | 
			
		||||
#define TINYPRINTF_DEFINE_TFP_PRINTF 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set this to 0 if you do not want to provide
 | 
			
		||||
 * tfp_sprintf/snprintf/vsprintf/vsnprintf
 | 
			
		||||
 */
 | 
			
		||||
#ifndef TINYPRINTF_DEFINE_TFP_SPRINTF
 | 
			
		||||
#define TINYPRINTF_DEFINE_TFP_SPRINTF 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set this to 0 if you do not want tfp_printf and
 | 
			
		||||
 * tfp_{vsn,sn,vs,s}printf to be also available as
 | 
			
		||||
 * printf/{vsn,sn,vs,s}printf
 | 
			
		||||
 */
 | 
			
		||||
#ifndef TINYPRINTF_OVERRIDE_LIBC
 | 
			
		||||
#define TINYPRINTF_OVERRIDE_LIBC 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Optional external types dependencies */
 | 
			
		||||
 | 
			
		||||
/* Declarations */
 | 
			
		||||
 | 
			
		||||
#if defined(__GNUC__)
 | 
			
		||||
#define _TFP_SPECIFY_PRINTF_FMT(fmt_idx, arg1_idx) \
 | 
			
		||||
    __attribute__((format(printf, fmt_idx, arg1_idx)))
 | 
			
		||||
#else
 | 
			
		||||
#define _TFP_SPECIFY_PRINTF_FMT(fmt_idx, arg1_idx)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef void (*putcf)(void*, char);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 'tfp_format' really is the central function for all tinyprintf. For
 | 
			
		||||
 * each output character after formatting, the 'putf' callback is
 | 
			
		||||
 * called with 2 args:
 | 
			
		||||
 *   - an arbitrary void* 'putp' param defined by the user and
 | 
			
		||||
 *     passed unmodified from 'tfp_format',
 | 
			
		||||
 *   - the character.
 | 
			
		||||
 * The 'tfp_printf' and 'tfp_sprintf' functions simply define their own
 | 
			
		||||
 * callback and pass to it the right 'putp' it is expecting.
 | 
			
		||||
 */
 | 
			
		||||
void tfp_format(void *putp, putcf putf, const char *fmt, va_list va);
 | 
			
		||||
 | 
			
		||||
#if TINYPRINTF_DEFINE_TFP_SPRINTF
 | 
			
		||||
int tfp_vsnprintf(char *str, size_t size, const char *fmt, va_list ap);
 | 
			
		||||
int tfp_snprintf(char *str, size_t size, const char *fmt, ...)
 | 
			
		||||
    _TFP_SPECIFY_PRINTF_FMT(3, 4);
 | 
			
		||||
int tfp_vsprintf(char *str, const char *fmt, va_list ap);
 | 
			
		||||
int tfp_sprintf(char *str, const char *fmt, ...) _TFP_SPECIFY_PRINTF_FMT(2, 3);
 | 
			
		||||
#if TINYPRINTF_OVERRIDE_LIBC
 | 
			
		||||
#define vsnprintf tfp_vsnprintf
 | 
			
		||||
#define snprintf tfp_snprintf
 | 
			
		||||
#define vsprintf tfp_vsprintf
 | 
			
		||||
#define sprintf tfp_sprintf
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if TINYPRINTF_DEFINE_TFP_PRINTF
 | 
			
		||||
void init_printf(void *putp, putcf putf);
 | 
			
		||||
void tfp_printf(char *fmt, ...) _TFP_SPECIFY_PRINTF_FMT(1, 2);
 | 
			
		||||
#if TINYPRINTF_OVERRIDE_LIBC
 | 
			
		||||
#define printf tfp_printf
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
#include <forward_list>
 | 
			
		||||
namespace std
 | 
			
		||||
{
 | 
			
		||||
    template <typename... Args>
 | 
			
		||||
    auto tfp_printf(Args&&... args) -> decltype(::tfp_printf(std::forward<Args>(args)...))
 | 
			
		||||
    {
 | 
			
		||||
        return ::tfp_printf(std::forward<Args>(args)...);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int printk(const char *format, ...) _TFP_SPECIFY_PRINTF_FMT(1, 2);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* _BSP_PRINTF_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 sleep.h
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _BSP_SLEEP_H
 | 
			
		||||
#define _BSP_SLEEP_H
 | 
			
		||||
 | 
			
		||||
#include "encoding.h"
 | 
			
		||||
#include "clint.h"
 | 
			
		||||
#include "syscalls.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int usleep(uint64_t usec);
 | 
			
		||||
int msleep(uint64_t msec);
 | 
			
		||||
unsigned int sleep(unsigned int seconds);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* _BSP_SLEEP_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 syscalls.h
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _BSP_SYSCALLS_H
 | 
			
		||||
#define _BSP_SYSCALLS_H
 | 
			
		||||
 | 
			
		||||
#include <machine/syscall.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void __attribute__((noreturn)) sys_exit(int code);
 | 
			
		||||
 | 
			
		||||
void setStats(int enable);
 | 
			
		||||
 | 
			
		||||
#undef putchar
 | 
			
		||||
int putchar(int ch);
 | 
			
		||||
void printstr(const char *s);
 | 
			
		||||
 | 
			
		||||
void printhex(uint64_t x);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* _BSP_SYSCALLS_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,151 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 syslog.h
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _SYSLOG_H
 | 
			
		||||
#define _SYSLOG_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "printf.h"
 | 
			
		||||
#include "encoding.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Logging library
 | 
			
		||||
 *
 | 
			
		||||
 * Log library has two ways of managing log verbosity: compile time, set via
 | 
			
		||||
 * menuconfig
 | 
			
		||||
 *
 | 
			
		||||
 * At compile time, filtering is done using CONFIG_LOG_DEFAULT_LEVEL macro, set via
 | 
			
		||||
 * menuconfig. All logging statments for levels higher than CONFIG_LOG_DEFAULT_LEVEL
 | 
			
		||||
 * will be removed by the preprocessor.
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * How to use this library:
 | 
			
		||||
 *
 | 
			
		||||
 * In each C file which uses logging functionality, define TAG variable like this:
 | 
			
		||||
 *
 | 
			
		||||
 *      static const char *TAG = "MODULE_NAME";
 | 
			
		||||
 *
 | 
			
		||||
 * then use one of logging macros to produce output, e.g:
 | 
			
		||||
 *
 | 
			
		||||
 *      LOGW(TAG, "Interrupt error %d", error);
 | 
			
		||||
 *
 | 
			
		||||
 * Several macros are available for different verbosity levels:
 | 
			
		||||
 *
 | 
			
		||||
 *      LOGE - error
 | 
			
		||||
 *      LOGW - warning
 | 
			
		||||
 *      LOGI - info
 | 
			
		||||
 *      LOGD - debug
 | 
			
		||||
 *      LOGV - verbose
 | 
			
		||||
 *
 | 
			
		||||
 * To override default verbosity level at file or component scope, define LOG_LEVEL macro.
 | 
			
		||||
 * At file scope, define it before including esp_log.h, e.g.:
 | 
			
		||||
 *
 | 
			
		||||
 *      #define LOG_LEVEL LOG_VERBOSE
 | 
			
		||||
 *      #include "dxx_log.h"
 | 
			
		||||
 *
 | 
			
		||||
 * At component scope, define it in component makefile:
 | 
			
		||||
 *
 | 
			
		||||
 *      CFLAGS += -D LOG_LEVEL=LOG_DEBUG
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* clang-format off */
 | 
			
		||||
typedef enum _kendryte_log_level
 | 
			
		||||
{
 | 
			
		||||
    LOG_NONE,       /*!< No log output */
 | 
			
		||||
    LOG_ERROR,      /*!< Critical errors, software module can not recover on its own */
 | 
			
		||||
    LOG_WARN,       /*!< Error conditions from which recovery measures have been taken */
 | 
			
		||||
    LOG_INFO,       /*!< Information messages which describe normal flow of events */
 | 
			
		||||
    LOG_DEBUG,      /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */
 | 
			
		||||
    LOG_VERBOSE     /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */
 | 
			
		||||
} kendryte_log_level_t ;
 | 
			
		||||
/* clang-format on */
 | 
			
		||||
 | 
			
		||||
/* clang-format off */
 | 
			
		||||
#if CONFIG_LOG_COLORS
 | 
			
		||||
#define LOG_COLOR_BLACK   "30"
 | 
			
		||||
#define LOG_COLOR_RED     "31"
 | 
			
		||||
#define LOG_COLOR_GREEN   "32"
 | 
			
		||||
#define LOG_COLOR_BROWN   "33"
 | 
			
		||||
#define LOG_COLOR_BLUE    "34"
 | 
			
		||||
#define LOG_COLOR_PURPLE  "35"
 | 
			
		||||
#define LOG_COLOR_CYAN    "36"
 | 
			
		||||
#define LOG_COLOR(COLOR)  "\033[0;" COLOR "m"
 | 
			
		||||
#define LOG_BOLD(COLOR)   "\033[1;" COLOR "m"
 | 
			
		||||
#define LOG_RESET_COLOR   "\033[0m"
 | 
			
		||||
#define LOG_COLOR_E       LOG_COLOR(LOG_COLOR_RED)
 | 
			
		||||
#define LOG_COLOR_W       LOG_COLOR(LOG_COLOR_BROWN)
 | 
			
		||||
#define LOG_COLOR_I       LOG_COLOR(LOG_COLOR_GREEN)
 | 
			
		||||
#define LOG_COLOR_D
 | 
			
		||||
#define LOG_COLOR_V
 | 
			
		||||
#else /* CONFIG_LOG_COLORS */
 | 
			
		||||
#define LOG_COLOR_E
 | 
			
		||||
#define LOG_COLOR_W
 | 
			
		||||
#define LOG_COLOR_I
 | 
			
		||||
#define LOG_COLOR_D
 | 
			
		||||
#define LOG_COLOR_V
 | 
			
		||||
#define LOG_RESET_COLOR
 | 
			
		||||
#endif /* CONFIG_LOG_COLORS */
 | 
			
		||||
/* clang-format on */
 | 
			
		||||
 | 
			
		||||
#define LOG_FORMAT(letter, format)  LOG_COLOR_ ## letter #letter " (%lu) %s: " format LOG_RESET_COLOR "\n"
 | 
			
		||||
 | 
			
		||||
#ifdef LOG_LEVEL
 | 
			
		||||
#undef CONFIG_LOG_LEVEL
 | 
			
		||||
#define CONFIG_LOG_LEVEL LOG_LEVEL
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LOG_KERNEL
 | 
			
		||||
#define LOG_PRINTF printk
 | 
			
		||||
#else
 | 
			
		||||
#define LOG_PRINTF printf
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_LOG_ENABLE
 | 
			
		||||
#define LOGE(tag, format, ...)  do {if (CONFIG_LOG_LEVEL >= LOG_ERROR)   LOG_PRINTF(LOG_FORMAT(E, format), read_cycle(), tag, ##__VA_ARGS__); } while (0)
 | 
			
		||||
#define LOGW(tag, format, ...)  do {if (CONFIG_LOG_LEVEL >= LOG_WARN)    LOG_PRINTF(LOG_FORMAT(W, format), read_cycle(), tag, ##__VA_ARGS__); } while (0)
 | 
			
		||||
#define LOGI(tag, format, ...)  do {if (CONFIG_LOG_LEVEL >= LOG_INFO)    LOG_PRINTF(LOG_FORMAT(I, format), read_cycle(), tag, ##__VA_ARGS__); } while (0)
 | 
			
		||||
#define LOGD(tag, format, ...)  do {if (CONFIG_LOG_LEVEL >= LOG_DEBUG)   LOG_PRINTF(LOG_FORMAT(D, format), read_cycle(), tag, ##__VA_ARGS__); } while (0)
 | 
			
		||||
#define LOGV(tag, format, ...)  do {if (CONFIG_LOG_LEVEL >= LOG_VERBOSE) LOG_PRINTF(LOG_FORMAT(V, format), read_cycle(), tag, ##__VA_ARGS__); } while (0)
 | 
			
		||||
#else
 | 
			
		||||
#define LOGE(tag, format, ...)
 | 
			
		||||
#define LOGW(tag, format, ...)
 | 
			
		||||
#define LOGI(tag, format, ...)
 | 
			
		||||
#define LOGD(tag, format, ...)
 | 
			
		||||
#define LOGV(tag, format, ...)
 | 
			
		||||
#endif  /* LOG_ENABLE */
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* _SYSLOG_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,207 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 util.h
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _BSP_UTIL_H
 | 
			
		||||
#define _BSP_UTIL_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#if defined(__riscv)
 | 
			
		||||
#include "encoding.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__GNUC__)
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * --------------------------------------------------------------------------
 | 
			
		||||
 * Macros
 | 
			
		||||
 | 
			
		||||
 * Set HOST_DEBUG to 1 if you are going to compile this for a host
 | 
			
		||||
 * machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
 | 
			
		||||
 * to 0 if you are compiling with the smips-gcc toolchain.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef HOST_DEBUG
 | 
			
		||||
#define HOST_DEBUG 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set PREALLOCATE to 1 if you want to preallocate the benchmark
 | 
			
		||||
 * function before starting stats. If you have instruction/data
 | 
			
		||||
 * caches and you don't want to count the overhead of misses, then
 | 
			
		||||
 * you will need to use preallocation.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef PREALLOCATE
 | 
			
		||||
#define PREALLOCATE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define static_assert(cond)   \
 | 
			
		||||
    {                         \
 | 
			
		||||
        switch (0)            \
 | 
			
		||||
        {                     \
 | 
			
		||||
        case 0:               \
 | 
			
		||||
        case !!(long)(cond):; \
 | 
			
		||||
        }                     \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define stringify_1(s) #s
 | 
			
		||||
#define stringify(s) stringify_1(s)
 | 
			
		||||
#define stats(code, iter)                                                                         \
 | 
			
		||||
    do                                                                                            \
 | 
			
		||||
    {                                                                                             \
 | 
			
		||||
        unsigned long _c = -read_cycle(), _i = -READ_CSR(minstret);                           \
 | 
			
		||||
        code;                                                                                     \
 | 
			
		||||
        _c += read_cycle(), _i += READ_CSR(minstret);                                         \
 | 
			
		||||
        if (cid == 0)                                                                             \
 | 
			
		||||
            printf("\r\n%s: %ld cycles, %ld.%ld cycles/iter, %ld.%ld CPI\r\n",                        \
 | 
			
		||||
                stringify(code), _c, _c / iter, 10 * _c / iter % 10, _c / _i, 10 * _c / _i % 10); \
 | 
			
		||||
    } while (0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set SET_STATS to 1 if you want to carve out the piece that actually
 | 
			
		||||
 * does the computation.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if HOST_DEBUG
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
static void setStats(int enable) {}
 | 
			
		||||
#else
 | 
			
		||||
extern void setStats(int enable);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void printArray(const char name[], int n, const int arr[])
 | 
			
		||||
{
 | 
			
		||||
#if HOST_DEBUG
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    printf(" %10s :", name);
 | 
			
		||||
    for (i = 0; i < n; i++)
 | 
			
		||||
        printf(" %3d ", arr[i]);
 | 
			
		||||
    printf("\r\n");
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void printDoubleArray(const char name[], int n, const double arr[])
 | 
			
		||||
{
 | 
			
		||||
#if HOST_DEBUG
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    printf(" %10s :", name);
 | 
			
		||||
    for (i = 0; i < n; i++)
 | 
			
		||||
        printf(" %g ", arr[i]);
 | 
			
		||||
    printf("\r\n");
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int verify(int n, const volatile int *test, const int *verify)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    /* Unrolled for faster verification */
 | 
			
		||||
    for (i = 0; i < n / 2 * 2; i += 2)
 | 
			
		||||
    {
 | 
			
		||||
        int t0 = test[i], t1 = test[i + 1];
 | 
			
		||||
        int v0 = verify[i], v1 = verify[i + 1];
 | 
			
		||||
 | 
			
		||||
        if (t0 != v0)
 | 
			
		||||
            return i + 1;
 | 
			
		||||
        if (t1 != v1)
 | 
			
		||||
            return i + 2;
 | 
			
		||||
    }
 | 
			
		||||
    if (n % 2 != 0 && test[n - 1] != verify[n - 1])
 | 
			
		||||
        return n;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int verifyDouble(int n, const volatile double *test, const double *verify)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    /* Unrolled for faster verification */
 | 
			
		||||
    for (i = 0; i < n / 2 * 2; i += 2)
 | 
			
		||||
    {
 | 
			
		||||
        double t0 = test[i], t1 = test[i + 1];
 | 
			
		||||
        double v0 = verify[i], v1 = verify[i + 1];
 | 
			
		||||
        int eq1 = t0 == v0, eq2 = t1 == v1;
 | 
			
		||||
 | 
			
		||||
        if (!(eq1 & eq2))
 | 
			
		||||
            return i + 1 + eq1;
 | 
			
		||||
    }
 | 
			
		||||
    if (n % 2 != 0 && test[n - 1] != verify[n - 1])
 | 
			
		||||
        return n;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void __attribute__((noinline)) barrier(int ncores)
 | 
			
		||||
{
 | 
			
		||||
    static volatile int sense = 0;
 | 
			
		||||
    static volatile int count = 0;
 | 
			
		||||
 | 
			
		||||
    static __thread int threadsense;
 | 
			
		||||
 | 
			
		||||
    __sync_synchronize();
 | 
			
		||||
 | 
			
		||||
    threadsense = !threadsense;
 | 
			
		||||
    if (__sync_fetch_and_add(&count, 1) == ncores - 1)
 | 
			
		||||
    {
 | 
			
		||||
        count = 0;
 | 
			
		||||
        sense = threadsense;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        while (sense != threadsense)
 | 
			
		||||
            ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    __sync_synchronize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint64_t lfsr(uint64_t x)
 | 
			
		||||
{
 | 
			
		||||
    uint64_t bit = (x ^ (x >> 1)) & 1;
 | 
			
		||||
 | 
			
		||||
    return (x >> 1) | (bit << 62);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(__GNUC__)
 | 
			
		||||
#pragma GCC diagnostic warning "-Wunused-parameter"
 | 
			
		||||
#pragma GCC diagnostic warning "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* _BSP_UTIL_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,115 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) 2020 AIIT XUOS Lab
 | 
			
		||||
* XiUOS is licensed under Mulan PSL v2.
 | 
			
		||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
 | 
			
		||||
* You may obtain a copy of Mulan PSL v2 at:
 | 
			
		||||
*        http://license.coscl.org.cn/MulanPSL2
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the Mulan PSL v2 for more details.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
__STACKSIZE__ = 4096;
 | 
			
		||||
OUTPUT_ARCH( "riscv" )
 | 
			
		||||
MEMORY
 | 
			
		||||
{
 | 
			
		||||
   sram (wxa!ri):  ORIGIN = 0x80000000, LENGTH = ( 6 * 1024 * 1024 )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ENTRY(_begin)
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
    .start :
 | 
			
		||||
    {
 | 
			
		||||
        *(.start);
 | 
			
		||||
    } > sram
 | 
			
		||||
 | 
			
		||||
    . = ALIGN(8);
 | 
			
		||||
 | 
			
		||||
    .text : 
 | 
			
		||||
    {
 | 
			
		||||
        PROVIDE( _text = ABSOLUTE(.) );
 | 
			
		||||
 | 
			
		||||
        *(.text .text.*)                        /* Normal code */
 | 
			
		||||
        *(.rodata .rodata*)                     /* read-only data (constants) */
 | 
			
		||||
  
 | 
			
		||||
        /* section information for  shell */
 | 
			
		||||
        . = ALIGN(8);
 | 
			
		||||
        _shell_command_start = .;
 | 
			
		||||
        KEEP (*(shellCommand))
 | 
			
		||||
        _shell_command_end = .;
 | 
			
		||||
        . = ALIGN(8);
 | 
			
		||||
 | 
			
		||||
        PROVIDE(__ctors_start__ = .);
 | 
			
		||||
        KEEP (*(SORT(.init_array.*)))
 | 
			
		||||
        KEEP (*(.init_array))
 | 
			
		||||
        PROVIDE(__ctors_end__ = .);
 | 
			
		||||
 | 
			
		||||
        . = ALIGN(4);
 | 
			
		||||
        
 | 
			
		||||
        __isrtbl_idx_start = .;
 | 
			
		||||
        KEEP(*(.isrtbl.idx))
 | 
			
		||||
        __isrtbl_start = .;
 | 
			
		||||
        KEEP(*(.isrtbl))
 | 
			
		||||
        __isrtbl_end = .;
 | 
			
		||||
        . = ALIGN(8);
 | 
			
		||||
 | 
			
		||||
        PROVIDE(g_service_table_start = ABSOLUTE(.));
 | 
			
		||||
        KEEP(*(.g_service_table))
 | 
			
		||||
        PROVIDE(g_service_table_end = ABSOLUTE(.));
 | 
			
		||||
 | 
			
		||||
        PROVIDE( _etext = ABSOLUTE(.) );
 | 
			
		||||
    } > sram
 | 
			
		||||
 | 
			
		||||
    . = ALIGN(8);
 | 
			
		||||
 | 
			
		||||
    .data : 
 | 
			
		||||
    {
 | 
			
		||||
        PROVIDE( _sdata = ABSOLUTE(.) );
 | 
			
		||||
        
 | 
			
		||||
        /* Writable data segment */
 | 
			
		||||
        *(.data .data.*)       
 | 
			
		||||
 | 
			
		||||
        . = ALIGN(8);
 | 
			
		||||
        PROVIDE( __global_pointer$ = ABSOLUTE(.) + 0x800 );
 | 
			
		||||
 | 
			
		||||
        /* Writable small data segment (.sdata segment) */
 | 
			
		||||
        *(.sdata .sdata.*)
 | 
			
		||||
 | 
			
		||||
        PROVIDE( _edata = ABSOLUTE(.) );
 | 
			
		||||
    } > sram
 | 
			
		||||
 | 
			
		||||
    .bss : 
 | 
			
		||||
    {
 | 
			
		||||
        __bss_start = ABSOLUTE(.);
 | 
			
		||||
 | 
			
		||||
        /* Writable uninitialized small data segment (.sbss segment)*/
 | 
			
		||||
        *(.sbss .sbss.*)
 | 
			
		||||
        *(.scommon)
 | 
			
		||||
 | 
			
		||||
        /* Uninitialized writeable data section (.bss segment)*/
 | 
			
		||||
        *(.bss .bss.*)
 | 
			
		||||
        *(COMMON)
 | 
			
		||||
 | 
			
		||||
        . = ALIGN(8);
 | 
			
		||||
        __bss_end = ABSOLUTE(.);
 | 
			
		||||
    } > sram
 | 
			
		||||
 | 
			
		||||
    .stack :
 | 
			
		||||
    {
 | 
			
		||||
        . = ALIGN(64);
 | 
			
		||||
        PROVIDE(__stack_start__ = ABSOLUTE(.));
 | 
			
		||||
 | 
			
		||||
        /* cpu0 stack top site */
 | 
			
		||||
        . = . + __STACKSIZE__;
 | 
			
		||||
        __stack_tp0 = . ;
 | 
			
		||||
 | 
			
		||||
        /* cpu1 stack top site */
 | 
			
		||||
        . = . + __STACKSIZE__;
 | 
			
		||||
        __stack_tp1 = . ;
 | 
			
		||||
 | 
			
		||||
        PROVIDE( __stack_end__ = ABSOLUTE(.) );
 | 
			
		||||
    } > sram
 | 
			
		||||
    _end = ABSOLUTE(.);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,76 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) 2020 AIIT XUOS Lab
 | 
			
		||||
* XiUOS is licensed under Mulan PSL v2.
 | 
			
		||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
 | 
			
		||||
* You may obtain a copy of Mulan PSL v2 at:
 | 
			
		||||
*        http://license.coscl.org.cn/MulanPSL2
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the Mulan PSL v2 for more details.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
OUTPUT_ARCH("riscv")
 | 
			
		||||
MEMORY
 | 
			
		||||
{
 | 
			
		||||
    usram (rw)  : ORIGIN = 0x80101000, LENGTH =  ( 5 * 1024 * 1024 - 4 * 1024 )  /* 5M -4k usram */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
    .userspace : 
 | 
			
		||||
    {
 | 
			
		||||
        . = ALIGN(8);
 | 
			
		||||
        KEEP(*(.userspace))
 | 
			
		||||
    } > usram
 | 
			
		||||
 | 
			
		||||
    .text : 
 | 
			
		||||
    {
 | 
			
		||||
        _ustext = ABSOLUTE(.);
 | 
			
		||||
        *(.text .text.*)
 | 
			
		||||
        *(.rodata .rodata*)
 | 
			
		||||
        *(.glue_7)
 | 
			
		||||
        *(.glue_7t)
 | 
			
		||||
 | 
			
		||||
        PROVIDE(__ctors_start__ = .);
 | 
			
		||||
        KEEP (*(SORT(.init_array.*)))
 | 
			
		||||
        KEEP (*(.init_array))
 | 
			
		||||
        PROVIDE(__ctors_end__ = .);
 | 
			
		||||
        
 | 
			
		||||
        PROVIDE(_uetext = ABSOLUTE(.));
 | 
			
		||||
    } > usram
 | 
			
		||||
    
 | 
			
		||||
    .init_section : {
 | 
			
		||||
        _sinit = ABSOLUTE(.);
 | 
			
		||||
        KEEP(*(.init_array .init_array.*))
 | 
			
		||||
        _einit = ABSOLUTE(.);
 | 
			
		||||
    } > usram
 | 
			
		||||
 | 
			
		||||
    __uexidx_start = ABSOLUTE(.);
 | 
			
		||||
 | 
			
		||||
    .ARM.exidx :
 | 
			
		||||
    {
 | 
			
		||||
        PROVIDE(__uexidx_start = ABSOLUTE(.));
 | 
			
		||||
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
 | 
			
		||||
        PROVIDE(__uexidx_end = ABSOLUTE(.));
 | 
			
		||||
    } > usram
 | 
			
		||||
 | 
			
		||||
    _ueronly = ABSOLUTE(.);
 | 
			
		||||
 | 
			
		||||
    .data : AT(_ueronly)
 | 
			
		||||
    {
 | 
			
		||||
        _usdata = ABSOLUTE(.);
 | 
			
		||||
        *(.data .data.*)
 | 
			
		||||
        . = ALIGN(8);
 | 
			
		||||
        _uedata = ABSOLUTE(.);
 | 
			
		||||
    } > usram 
 | 
			
		||||
 | 
			
		||||
    .bss : {
 | 
			
		||||
        . = ALIGN(8);
 | 
			
		||||
        _usbss = ABSOLUTE(.);
 | 
			
		||||
        *(.bss .bss.*)
 | 
			
		||||
        *(.sbss .sbss.*)
 | 
			
		||||
        . = ALIGN(8);
 | 
			
		||||
        _uebss = ABSOLUTE(.);
 | 
			
		||||
    } > usram
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
menuconfig BSP_USING_CH376
 | 
			
		||||
    bool "Using CH376 device"
 | 
			
		||||
    default n
 | 
			
		||||
    select FS_VFS
 | 
			
		||||
    select FS_CH376
 | 
			
		||||
    if BSP_USING_CH376
 | 
			
		||||
        source "$BSP_DIR/third_party_driver/ch376/Kconfig"
 | 
			
		||||
    endif
 | 
			
		||||
 | 
			
		||||
menuconfig BSP_USING_SPI
 | 
			
		||||
    bool "Using SPI device"
 | 
			
		||||
    default n
 | 
			
		||||
    select RESOURCES_SPI
 | 
			
		||||
    select  BSP_USING_DMA
 | 
			
		||||
    if BSP_USING_SPI
 | 
			
		||||
        source "$BSP_DIR/third_party_driver/spi/Kconfig"
 | 
			
		||||
    endif
 | 
			
		||||
 | 
			
		||||
menuconfig BSP_USING_LCD
 | 
			
		||||
    bool "Using LCD device"
 | 
			
		||||
    default n
 | 
			
		||||
    select BSP_USING_SPI
 | 
			
		||||
    select RESOURCES_LCD
 | 
			
		||||
    if BSP_USING_LCD
 | 
			
		||||
        source "$BSP_DIR/third_party_driver/lcd/Kconfig"
 | 
			
		||||
    endif 
 | 
			
		||||
 | 
			
		||||
menuconfig BSP_USING_DMA
 | 
			
		||||
    bool "Using DMA device"
 | 
			
		||||
    default y
 | 
			
		||||
    if BSP_USING_DMA
 | 
			
		||||
        source "$BSP_DIR/third_party_driver/dma/Kconfig"
 | 
			
		||||
    endif 
 | 
			
		||||
 | 
			
		||||
menuconfig BSP_USING_GPIO
 | 
			
		||||
    bool "Using GPIO device"
 | 
			
		||||
    default y
 | 
			
		||||
    select RESOURCES_PIN
 | 
			
		||||
    if BSP_USING_GPIO
 | 
			
		||||
        source "$BSP_DIR/third_party_driver/gpio/Kconfig"
 | 
			
		||||
    endif
 | 
			
		||||
 | 
			
		||||
menuconfig BSP_USING_I2C
 | 
			
		||||
    bool "Using I2C device"
 | 
			
		||||
    default n
 | 
			
		||||
    select RESOURCES_I2C
 | 
			
		||||
    if BSP_USING_I2C
 | 
			
		||||
        source "$BSP_DIR/third_party_driver/i2c/Kconfig"
 | 
			
		||||
    endif
 | 
			
		||||
 | 
			
		||||
menuconfig BSP_USING_TOUCH
 | 
			
		||||
    bool "Using TOUCH device"
 | 
			
		||||
    default n
 | 
			
		||||
    select BSP_USING_I2C
 | 
			
		||||
    select RESOURCES_TOUCH
 | 
			
		||||
    if BSP_USING_TOUCH
 | 
			
		||||
        source "$BSP_DIR/third_party_driver/touch/Kconfig"
 | 
			
		||||
    endif
 | 
			
		||||
 | 
			
		||||
menuconfig BSP_USING_PLIC
 | 
			
		||||
    bool "Using PLIC device"
 | 
			
		||||
    default y
 | 
			
		||||
    if BSP_USING_PLIC
 | 
			
		||||
        source "$BSP_DIR/third_party_driver/plic/Kconfig"
 | 
			
		||||
    endif
 | 
			
		||||
 | 
			
		||||
menuconfig BSP_USING_SYSCLOCK
 | 
			
		||||
    bool "Using SYSCLOCK device"
 | 
			
		||||
    default y
 | 
			
		||||
    if BSP_USING_SYSCLOCK
 | 
			
		||||
        source "$BSP_DIR/third_party_driver/sys_clock/Kconfig"
 | 
			
		||||
    endif
 | 
			
		||||
 | 
			
		||||
menuconfig BSP_USING_UART
 | 
			
		||||
    bool "Using UART device"
 | 
			
		||||
    default y
 | 
			
		||||
    select RESOURCES_SERIAL
 | 
			
		||||
    if BSP_USING_UART
 | 
			
		||||
        source "$BSP_DIR/third_party_driver/uart/Kconfig"
 | 
			
		||||
    endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
SRC_FILES := sleep.c
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_BSP_USING_CH376),y)
 | 
			
		||||
  SRC_DIR += ch376
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_BSP_USING_DMA),y)
 | 
			
		||||
  SRC_DIR += dma
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_BSP_USING_GPIO),y)
 | 
			
		||||
  SRC_DIR += gpio
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_BSP_USING_SPI),y)
 | 
			
		||||
  SRC_DIR += spi
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_BSP_USING_I2C),y)
 | 
			
		||||
  SRC_DIR += i2c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_BSP_USING_TOUCH),y)
 | 
			
		||||
  SRC_DIR += touch
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_BSP_USING_PLIC),y)
 | 
			
		||||
  SRC_DIR += plic
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_BSP_USING_SYSCLOCK),y)
 | 
			
		||||
  SRC_DIR += sys_clock
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_BSP_USING_UART),y)
 | 
			
		||||
  SRC_DIR += uart
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_BSP_USING_LCD),y)
 | 
			
		||||
  SRC_DIR += lcd
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
menuconfig BSP_USING_SDIO
 | 
			
		||||
bool "Using CH376 SD card"
 | 
			
		||||
default n
 | 
			
		||||
select RESOURCES_SDIO
 | 
			
		||||
select MOUNT_SDCARD
 | 
			
		||||
if BSP_USING_SDIO
 | 
			
		||||
config SDIO_BUS_NAME
 | 
			
		||||
    string "sdio bus name"
 | 
			
		||||
    default "sdio"
 | 
			
		||||
 | 
			
		||||
config SDIO_DRIVER_NAME
 | 
			
		||||
    string "sdio driver name"
 | 
			
		||||
    default "sdio_drv"
 | 
			
		||||
 | 
			
		||||
config SDIO_DEVICE_NAME
 | 
			
		||||
    string "sdio device name"
 | 
			
		||||
    default "sdio_dev"
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
menuconfig BSP_USING_USB
 | 
			
		||||
bool "Using CH376 USB"
 | 
			
		||||
default n
 | 
			
		||||
select RESOURCES_USB
 | 
			
		||||
select MOUNT_USB
 | 
			
		||||
if BSP_USING_USB
 | 
			
		||||
config USB_BUS_NAME
 | 
			
		||||
    string "USB bus name"
 | 
			
		||||
    default "usb"
 | 
			
		||||
 | 
			
		||||
config USB_DRIVER_NAME
 | 
			
		||||
    string "USB driver name"
 | 
			
		||||
    default "usb_drv"
 | 
			
		||||
 | 
			
		||||
config USB_DEVICE_NAME
 | 
			
		||||
    string "USB device name"
 | 
			
		||||
    default "usb_dev"
 | 
			
		||||
endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
SRC_FILES := connect_ch376.c
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,224 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) 2020 AIIT XUOS Lab
 | 
			
		||||
* XiUOS is licensed under Mulan PSL v2.
 | 
			
		||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
 | 
			
		||||
* You may obtain a copy of Mulan PSL v2 at:
 | 
			
		||||
*        http://license.coscl.org.cn/MulanPSL2
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the Mulan PSL v2 for more details.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @file connect_ch376.c
 | 
			
		||||
* @brief support to register ch376 pointer and function
 | 
			
		||||
* @version 2.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <ch376fs.h>
 | 
			
		||||
#include <connect_ch376.h>
 | 
			
		||||
 | 
			
		||||
static struct HwCh376 ch376;
 | 
			
		||||
 | 
			
		||||
static uint32 Ch376Configure(void *drv, struct BusConfigureInfo *configure_info)
 | 
			
		||||
{
 | 
			
		||||
    NULL_PARAM_CHECK(drv);
 | 
			
		||||
    NULL_PARAM_CHECK(configure_info);
 | 
			
		||||
 | 
			
		||||
    uint8 temp[2];
 | 
			
		||||
    temp[0] = 0x57;
 | 
			
		||||
    temp[1] = 0xab;
 | 
			
		||||
    MdelayKTask(100);
 | 
			
		||||
 | 
			
		||||
    struct BusBlockWriteParam write_param;
 | 
			
		||||
    write_param.pos = 0;
 | 
			
		||||
    write_param.buffer = (void *)temp;
 | 
			
		||||
    write_param.size = 2;
 | 
			
		||||
    BusDevWriteData(ch376.dev, &write_param);
 | 
			
		||||
 | 
			
		||||
    write_param.pos = 0;
 | 
			
		||||
    write_param.buffer = &configure_info->configure_cmd;
 | 
			
		||||
    write_param.size = 1;
 | 
			
		||||
    BusDevWriteData(ch376.dev, &write_param);
 | 
			
		||||
 | 
			
		||||
    return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int HwCh376RxInd(void *dev, x_size_t length)
 | 
			
		||||
{
 | 
			
		||||
    ch376.msg_len += length;
 | 
			
		||||
    KSemaphoreAbandon(ch376.sem);
 | 
			
		||||
 | 
			
		||||
    return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 Ch376Open(void *dev)
 | 
			
		||||
{
 | 
			
		||||
    NULL_PARAM_CHECK(dev);
 | 
			
		||||
 | 
			
		||||
    ch376.sem = KSemaphoreCreate(0);
 | 
			
		||||
    if (ch376.sem < 0) {
 | 
			
		||||
        KPrintf("CH376 open fail\n");
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct Bus *bus = BusFind(SERIAL_BUS_NAME_3);
 | 
			
		||||
    struct Driver *bus_driver = BusFindDriver(bus, SERIAL_DRV_NAME_3);
 | 
			
		||||
    ch376.dev = BusFindDevice(bus, SERIAL_3_DEVICE_NAME_0);
 | 
			
		||||
    if (!ch376.dev) {
 | 
			
		||||
        KPrintf("CH376 open fail\n");
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct SerialCfgParam serial_cfg;
 | 
			
		||||
    memset(&serial_cfg, 0, sizeof(struct SerialCfgParam));
 | 
			
		||||
    serial_cfg.data_cfg.serial_buffer_size = 512;
 | 
			
		||||
    struct BusConfigureInfo cfg;
 | 
			
		||||
    cfg.configure_cmd = OPE_INT;
 | 
			
		||||
    cfg.private_data = &serial_cfg;
 | 
			
		||||
 | 
			
		||||
    BusDrvConfigure(bus_driver, &cfg);
 | 
			
		||||
 | 
			
		||||
    bus->match(bus_driver, ch376.dev);
 | 
			
		||||
 | 
			
		||||
    struct SerialDevParam *serial_dev_param = (struct SerialDevParam *)ch376.dev->private_data;
 | 
			
		||||
    serial_dev_param->serial_set_mode = SIGN_OPER_INT_RX;
 | 
			
		||||
    BusDevOpen(ch376.dev);
 | 
			
		||||
 | 
			
		||||
    BusDevRecvCallback(ch376.dev, HwCh376RxInd);
 | 
			
		||||
 | 
			
		||||
    KPrintf("CH376 open done\n");
 | 
			
		||||
 | 
			
		||||
    return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 Ch376Close(void *dev)
 | 
			
		||||
{
 | 
			
		||||
    BusDevClose(ch376.dev);
 | 
			
		||||
    KSemaphoreDelete(ch376.sem);
 | 
			
		||||
 | 
			
		||||
    return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 Ch376Write(void *dev, struct BusBlockWriteParam *write_param)
 | 
			
		||||
{
 | 
			
		||||
    if (EOK == BusDevWriteData(ch376.dev, write_param))
 | 
			
		||||
        return EOK;
 | 
			
		||||
 | 
			
		||||
    return -ERROR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 Ch376Read(void *dev, struct BusBlockReadParam *read_param)
 | 
			
		||||
{
 | 
			
		||||
    if (KSemaphoreObtain(ch376.sem, WAITING_FOREVER) == EOK) {
 | 
			
		||||
        while(KSemaphoreObtain(ch376.sem, TICK_PER_SECOND) != -ETIMEOUT);
 | 
			
		||||
        read_param->size = ch376.msg_len;
 | 
			
		||||
        BusDevReadData(ch376.dev, read_param);
 | 
			
		||||
        ch376.msg_len = 0;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return read_param->read_length;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef BSP_USING_SDIO
 | 
			
		||||
static struct SdioDevDone sdio_done = 
 | 
			
		||||
{
 | 
			
		||||
    Ch376Open,
 | 
			
		||||
    Ch376Close,
 | 
			
		||||
    Ch376Write,
 | 
			
		||||
    Ch376Read,
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BSP_USING_USB
 | 
			
		||||
static struct UsbDevDone usb_done = 
 | 
			
		||||
{
 | 
			
		||||
    Ch376Open,
 | 
			
		||||
    Ch376Close,
 | 
			
		||||
    Ch376Write,
 | 
			
		||||
    Ch376Read,
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int HwCh376Init(void)
 | 
			
		||||
{
 | 
			
		||||
    x_err_t ret = EOK;
 | 
			
		||||
 | 
			
		||||
#ifdef BSP_USING_SDIO
 | 
			
		||||
    static struct SdioBus sdio_bus;
 | 
			
		||||
    static struct SdioDriver sdio_drv;
 | 
			
		||||
    static struct SdioHardwareDevice sdio_dev;
 | 
			
		||||
 | 
			
		||||
    ret = SdioBusInit(&sdio_bus,SDIO_BUS_NAME );
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("Sdio bus init error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sdio_drv.configure = &Ch376Configure;
 | 
			
		||||
    ret = SdioDriverInit(&sdio_drv, SDIO_DRIVER_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("Sdio driver init error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ret = SdioDriverAttachToBus( SDIO_DRIVER_NAME, SDIO_BUS_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("Sdio driver attach error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sdio_dev.dev_done = &sdio_done;
 | 
			
		||||
    ret = SdioDeviceRegister(&sdio_dev, SDIO_DEVICE_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("Sdio device register error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ret = SdioDeviceAttachToBus(SDIO_DEVICE_NAME, SDIO_BUS_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("Sdio device register error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BSP_USING_USB
 | 
			
		||||
    static struct UsbBus usb_bus;
 | 
			
		||||
    static struct UsbDriver usb_drv;
 | 
			
		||||
    static struct UsbHardwareDevice usb_dev;
 | 
			
		||||
    
 | 
			
		||||
    ret = UsbBusInit(&usb_bus, USB_BUS_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("USB bus init error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    usb_drv.configure = &Ch376Configure;
 | 
			
		||||
    ret = UsbDriverInit(&usb_drv, USB_DRIVER_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("USB driver init error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    ret = UsbDriverAttachToBus(USB_DRIVER_NAME, USB_BUS_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("USB driver attach error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    usb_dev.dev_done = &usb_done;
 | 
			
		||||
    ret = USBDeviceRegister(&usb_dev, NONE, USB_DEVICE_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("USB device register error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    ret = USBDeviceAttachToBus(USB_DEVICE_NAME, USB_BUS_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("USB device register error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
SRC_FILES := dmac.c
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,802 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 dmac.c
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "dmac.h"
 | 
			
		||||
#include "sysctl.h"
 | 
			
		||||
#include "fpioa.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
#include "plic.h"
 | 
			
		||||
#include "stdlib.h"
 | 
			
		||||
 | 
			
		||||
volatile dmac_t *const dmac = (dmac_t *)DMAC_BASE_ADDR;
 | 
			
		||||
 | 
			
		||||
typedef struct _dmac_context
 | 
			
		||||
{
 | 
			
		||||
    dmac_channel_number_t dmac_channel;
 | 
			
		||||
    plic_irq_callback_t callback;
 | 
			
		||||
    void *ctx;
 | 
			
		||||
} dmac_context_t;
 | 
			
		||||
 | 
			
		||||
dmac_context_t dmac_context[6];
 | 
			
		||||
 | 
			
		||||
static int is_memory(uintptr_t address)
 | 
			
		||||
{
 | 
			
		||||
    enum {
 | 
			
		||||
        mem_len = 6 * 1024 * 1024,
 | 
			
		||||
        mem_no_cache_len = 8 * 1024 * 1024,
 | 
			
		||||
    };
 | 
			
		||||
    return ((address >= 0x80000000) && (address < 0x80000000 + mem_len)) || ((address >= 0x40000000) && (address < 0x40000000 + mem_no_cache_len)) || (address == 0x50450040);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64_t dmac_read_id(void)
 | 
			
		||||
{
 | 
			
		||||
    return dmac->id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64_t dmac_read_version(void)
 | 
			
		||||
{
 | 
			
		||||
    return dmac->compver;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64_t dmac_read_channel_id(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    return dmac->channel[channel_num].axi_id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dmac_enable(void)
 | 
			
		||||
{
 | 
			
		||||
    dmac_cfg_u_t  dmac_cfg;
 | 
			
		||||
 | 
			
		||||
    dmac_cfg.data = readq(&dmac->cfg);
 | 
			
		||||
    dmac_cfg.cfg.dmac_en = 1;
 | 
			
		||||
    dmac_cfg.cfg.int_en = 1;
 | 
			
		||||
    writeq(dmac_cfg.data, &dmac->cfg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_disable(void)
 | 
			
		||||
{
 | 
			
		||||
    dmac_cfg_u_t  dmac_cfg;
 | 
			
		||||
 | 
			
		||||
    dmac_cfg.data = readq(&dmac->cfg);
 | 
			
		||||
    dmac_cfg.cfg.dmac_en = 0;
 | 
			
		||||
    dmac_cfg.cfg.int_en = 0;
 | 
			
		||||
    writeq(dmac_cfg.data, &dmac->cfg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void src_transaction_complete_int_enable(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_intstatus_enable_u_t  ch_intstat;
 | 
			
		||||
 | 
			
		||||
    ch_intstat.data = readq(&dmac->channel[channel_num].intstatus_en);
 | 
			
		||||
    ch_intstat.ch_intstatus_enable.enable_src_transcomp_intstat = 1;
 | 
			
		||||
 | 
			
		||||
    writeq(ch_intstat.data, &dmac->channel[channel_num].intstatus_en);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_channel_enable(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    dmac_chen_u_t chen;
 | 
			
		||||
 | 
			
		||||
    chen.data = readq(&dmac->chen);
 | 
			
		||||
 | 
			
		||||
    switch (channel_num) {
 | 
			
		||||
    case DMAC_CHANNEL0:
 | 
			
		||||
        chen.dmac_chen.ch1_en = 1;
 | 
			
		||||
        chen.dmac_chen.ch1_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL1:
 | 
			
		||||
        chen.dmac_chen.ch2_en = 1;
 | 
			
		||||
        chen.dmac_chen.ch2_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL2:
 | 
			
		||||
        chen.dmac_chen.ch3_en = 1;
 | 
			
		||||
        chen.dmac_chen.ch3_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL3:
 | 
			
		||||
        chen.dmac_chen.ch4_en = 1;
 | 
			
		||||
        chen.dmac_chen.ch4_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL4:
 | 
			
		||||
        chen.dmac_chen.ch5_en = 1;
 | 
			
		||||
        chen.dmac_chen.ch5_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL5:
 | 
			
		||||
        chen.dmac_chen.ch6_en = 1;
 | 
			
		||||
        chen.dmac_chen.ch6_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    writeq(chen.data, &dmac->chen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_channel_disable(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    dmac_chen_u_t chen;
 | 
			
		||||
 | 
			
		||||
    chen.data = readq(&dmac->chen);
 | 
			
		||||
 | 
			
		||||
    switch (channel_num)
 | 
			
		||||
    {
 | 
			
		||||
    case DMAC_CHANNEL0:
 | 
			
		||||
        chen.dmac_chen.ch1_en = 0;
 | 
			
		||||
        chen.dmac_chen.ch1_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL1:
 | 
			
		||||
        chen.dmac_chen.ch2_en = 0;
 | 
			
		||||
        chen.dmac_chen.ch2_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL2:
 | 
			
		||||
        chen.dmac_chen.ch3_en = 0;
 | 
			
		||||
        chen.dmac_chen.ch3_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL3:
 | 
			
		||||
        chen.dmac_chen.ch4_en = 0;
 | 
			
		||||
        chen.dmac_chen.ch4_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL4:
 | 
			
		||||
        chen.dmac_chen.ch5_en = 0;
 | 
			
		||||
        chen.dmac_chen.ch5_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL5:
 | 
			
		||||
        chen.dmac_chen.ch6_en = 0;
 | 
			
		||||
        chen.dmac_chen.ch6_en_we = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    writeq(chen.data, &dmac->chen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32_t dmac_check_channel_busy(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    int32_t ret = 0;
 | 
			
		||||
    dmac_chen_u_t chen_u;
 | 
			
		||||
 | 
			
		||||
    chen_u.data = readq(&dmac->chen);
 | 
			
		||||
    switch (channel_num) {
 | 
			
		||||
    case DMAC_CHANNEL0:
 | 
			
		||||
        if (chen_u.dmac_chen.ch1_en == 1)
 | 
			
		||||
            ret = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL1:
 | 
			
		||||
        if (chen_u.dmac_chen.ch2_en == 1)
 | 
			
		||||
            ret = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL2:
 | 
			
		||||
        if (chen_u.dmac_chen.ch3_en == 1)
 | 
			
		||||
            ret = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL3:
 | 
			
		||||
        if (chen_u.dmac_chen.ch4_en == 1)
 | 
			
		||||
            ret = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL4:
 | 
			
		||||
        if (chen_u.dmac_chen.ch5_en == 1)
 | 
			
		||||
            ret = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case DMAC_CHANNEL5:
 | 
			
		||||
        if (chen_u.dmac_chen.ch6_en == 1)
 | 
			
		||||
            ret = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    writeq(chen_u.data, &dmac->chen);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32_t dmac_set_list_master_select(dmac_channel_number_t channel_num,
 | 
			
		||||
    dmac_src_dst_select_t sd_sel, dmac_master_number_t  mst_num)
 | 
			
		||||
{
 | 
			
		||||
    int32_t ret = 0;
 | 
			
		||||
    uint64_t tmp = 0;
 | 
			
		||||
    dmac_ch_ctl_u_t ctl;
 | 
			
		||||
 | 
			
		||||
    ctl.data = readq(&dmac->channel[channel_num].ctl);
 | 
			
		||||
    ret = dmac_check_channel_busy(channel_num);
 | 
			
		||||
    if (ret == 0) {
 | 
			
		||||
        if (sd_sel == DMAC_SRC || sd_sel == DMAC_SRC_DST)
 | 
			
		||||
            ctl.ch_ctl.sms = mst_num;
 | 
			
		||||
 | 
			
		||||
        if (sd_sel == DMAC_DST || sd_sel == DMAC_SRC_DST)
 | 
			
		||||
            ctl.ch_ctl.dms = mst_num;
 | 
			
		||||
        tmp |= *(uint64_t *)&dmac->channel[channel_num].ctl;
 | 
			
		||||
        writeq(ctl.data, &dmac->channel[channel_num].ctl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_enable_common_interrupt_status(void)
 | 
			
		||||
{
 | 
			
		||||
    dmac_commonreg_intstatus_enable_u_t intstatus;
 | 
			
		||||
 | 
			
		||||
    intstatus.data = readq(&dmac->com_intstatus_en);
 | 
			
		||||
    intstatus.intstatus_enable.enable_slvif_dec_err_intstat = 1;
 | 
			
		||||
    intstatus.intstatus_enable.enable_slvif_wr2ro_err_intstat = 1;
 | 
			
		||||
    intstatus.intstatus_enable.enable_slvif_rd2wo_err_intstat = 1;
 | 
			
		||||
    intstatus.intstatus_enable.enable_slvif_wronhold_err_intstat = 1;
 | 
			
		||||
    intstatus.intstatus_enable.enable_slvif_undefinedreg_dec_err_intstat = 1;
 | 
			
		||||
 | 
			
		||||
    writeq(intstatus.data, &dmac->com_intstatus_en);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_enable_common_interrupt_signal(void)
 | 
			
		||||
{
 | 
			
		||||
    dmac_commonreg_intsignal_enable_u_t intsignal;
 | 
			
		||||
 | 
			
		||||
    intsignal.data = readq(&dmac->com_intsignal_en);
 | 
			
		||||
    intsignal.intsignal_enable.enable_slvif_dec_err_intsignal = 1;
 | 
			
		||||
    intsignal.intsignal_enable.enable_slvif_wr2ro_err_intsignal = 1;
 | 
			
		||||
    intsignal.intsignal_enable.enable_slvif_rd2wo_err_intsignal = 1;
 | 
			
		||||
    intsignal.intsignal_enable.enable_slvif_wronhold_err_intsignal = 1;
 | 
			
		||||
    intsignal.intsignal_enable.enable_slvif_undefinedreg_dec_err_intsignal = 1;
 | 
			
		||||
 | 
			
		||||
    writeq(intsignal.data, &dmac->com_intsignal_en);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dmac_enable_channel_interrupt(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    writeq(0xffffffff, &dmac->channel[channel_num].intclear);
 | 
			
		||||
    writeq(0x2, &dmac->channel[channel_num].intstatus_en);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_disable_channel_interrupt(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    writeq(0, &dmac->channel[channel_num].intstatus_en);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dmac_chanel_interrupt_clear(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    writeq(0xffffffff, &dmac->channel[channel_num].intclear);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dmac_set_channel_config(dmac_channel_number_t channel_num,
 | 
			
		||||
        dmac_channel_config_t *cfg_param)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_ctl_u_t  ctl;
 | 
			
		||||
    dmac_ch_cfg_u_t cfg;
 | 
			
		||||
    dmac_ch_llp_u_t ch_llp;
 | 
			
		||||
 | 
			
		||||
    if (cfg_param->ctl_sms > DMAC_MASTER2)
 | 
			
		||||
        return -1;
 | 
			
		||||
    if (cfg_param->ctl_dms > DMAC_MASTER2)
 | 
			
		||||
        return -1;
 | 
			
		||||
    if (cfg_param->ctl_src_msize > DMAC_MSIZE_256)
 | 
			
		||||
        return -1;
 | 
			
		||||
    if (cfg_param->ctl_drc_msize > DMAC_MSIZE_256)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * cfg register must configure before ts_block and
 | 
			
		||||
     * sar dar register
 | 
			
		||||
     */
 | 
			
		||||
    cfg.data = readq(&dmac->channel[channel_num].cfg);
 | 
			
		||||
 | 
			
		||||
    cfg.ch_cfg.hs_sel_src = cfg_param->cfg_hs_sel_src;
 | 
			
		||||
    cfg.ch_cfg.hs_sel_dst = cfg_param->cfg_hs_sel_dst;
 | 
			
		||||
    cfg.ch_cfg.src_hwhs_pol = cfg_param->cfg_src_hs_pol;
 | 
			
		||||
    cfg.ch_cfg.dst_hwhs_pol  = cfg_param->cfg_dst_hs_pol;
 | 
			
		||||
    cfg.ch_cfg.src_per = cfg_param->cfg_src_per;
 | 
			
		||||
    cfg.ch_cfg.dst_per = cfg_param->cfg_dst_per;
 | 
			
		||||
    cfg.ch_cfg.ch_prior = cfg_param->cfg_ch_prior;
 | 
			
		||||
    cfg.ch_cfg.tt_fc = cfg_param->ctl_tt_fc;
 | 
			
		||||
 | 
			
		||||
    cfg.ch_cfg.src_multblk_type = cfg_param->cfg_src_multblk_type;
 | 
			
		||||
    cfg.ch_cfg.dst_multblk_type = cfg_param->cfg_dst_multblk_type;
 | 
			
		||||
 | 
			
		||||
    writeq(cfg.data, &dmac->channel[channel_num].cfg);
 | 
			
		||||
 | 
			
		||||
    ctl.data = readq(&dmac->channel[channel_num].ctl);
 | 
			
		||||
    ctl.ch_ctl.sms = cfg_param->ctl_sms;
 | 
			
		||||
    ctl.ch_ctl.dms = cfg_param->ctl_dms;
 | 
			
		||||
    /* master select */
 | 
			
		||||
    ctl.ch_ctl.sinc = cfg_param->ctl_sinc;
 | 
			
		||||
    ctl.ch_ctl.dinc = cfg_param->ctl_dinc;
 | 
			
		||||
    /* address incrememt */
 | 
			
		||||
    ctl.ch_ctl.src_tr_width = cfg_param->ctl_src_tr_width;
 | 
			
		||||
    ctl.ch_ctl.dst_tr_width  = cfg_param->ctl_dst_tr_width;
 | 
			
		||||
    /* transfer width */
 | 
			
		||||
    ctl.ch_ctl.src_msize = cfg_param->ctl_src_msize;
 | 
			
		||||
    ctl.ch_ctl.dst_msize = cfg_param->ctl_drc_msize;
 | 
			
		||||
    /* Burst transaction length */
 | 
			
		||||
    ctl.ch_ctl.ioc_blktfr = cfg_param->ctl_ioc_blktfr;
 | 
			
		||||
    /* interrupt on completion of block transfer */
 | 
			
		||||
    /* 0x1 enable BLOCK_TFR_DONE_IntStat field */
 | 
			
		||||
 | 
			
		||||
    writeq(cfg_param->ctl_block_ts, &dmac->channel[channel_num].block_ts);
 | 
			
		||||
    /* the number of (blcok_ts +1) data of width SRC_TR_WIDTF to be */
 | 
			
		||||
    /* transferred in a dma block transfer */
 | 
			
		||||
 | 
			
		||||
    dmac->channel[channel_num].sar = cfg_param->sar;
 | 
			
		||||
    dmac->channel[channel_num].dar = cfg_param->dar;
 | 
			
		||||
 | 
			
		||||
    ch_llp.data = readq(&dmac->channel[channel_num].llp);
 | 
			
		||||
    ch_llp.llp.loc = cfg_param->llp_loc;
 | 
			
		||||
    ch_llp.llp.lms = cfg_param->llp_lms;
 | 
			
		||||
    writeq(ch_llp.data, &dmac->channel[channel_num].llp);
 | 
			
		||||
    writeq(ctl.data, &dmac->channel[channel_num].ctl);
 | 
			
		||||
    readq(&dmac->channel[channel_num].swhssrc);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dmac_set_channel_param(dmac_channel_number_t channel_num,
 | 
			
		||||
    const void *src, void *dest, dmac_address_increment_t src_inc, dmac_address_increment_t dest_inc,
 | 
			
		||||
    dmac_burst_trans_length_t dmac_burst_size,
 | 
			
		||||
    dmac_transfer_width_t dmac_trans_width,
 | 
			
		||||
    uint32_t blockSize)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_ctl_u_t  ctl;
 | 
			
		||||
    dmac_ch_cfg_u_t cfg_u;
 | 
			
		||||
 | 
			
		||||
    int mem_type_src = is_memory((uintptr_t)src), mem_type_dest = is_memory((uintptr_t)dest);
 | 
			
		||||
    dmac_transfer_flow_t flow_control;
 | 
			
		||||
    if (mem_type_src == 0 && mem_type_dest == 0)
 | 
			
		||||
    {
 | 
			
		||||
        flow_control = DMAC_PRF2PRF_DMA;
 | 
			
		||||
    }else if (mem_type_src == 1 && mem_type_dest == 0)
 | 
			
		||||
        flow_control = DMAC_MEM2PRF_DMA;
 | 
			
		||||
    else if (mem_type_src == 0 && mem_type_dest == 1)
 | 
			
		||||
        flow_control = DMAC_PRF2MEM_DMA;
 | 
			
		||||
    else
 | 
			
		||||
        flow_control = DMAC_MEM2MEM_DMA;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * cfg register must configure before ts_block and
 | 
			
		||||
     * sar dar register
 | 
			
		||||
     */
 | 
			
		||||
    cfg_u.data = readq(&dmac->channel[channel_num].cfg);
 | 
			
		||||
 | 
			
		||||
    cfg_u.ch_cfg.tt_fc = flow_control;
 | 
			
		||||
    cfg_u.ch_cfg.hs_sel_src = mem_type_src ? DMAC_HS_SOFTWARE : DMAC_HS_HARDWARE;
 | 
			
		||||
    cfg_u.ch_cfg.hs_sel_dst = mem_type_dest ? DMAC_HS_SOFTWARE : DMAC_HS_HARDWARE;
 | 
			
		||||
    cfg_u.ch_cfg.src_per = channel_num;
 | 
			
		||||
    cfg_u.ch_cfg.dst_per = channel_num;
 | 
			
		||||
    cfg_u.ch_cfg.src_multblk_type = 0;
 | 
			
		||||
    cfg_u.ch_cfg.dst_multblk_type = 0;
 | 
			
		||||
 | 
			
		||||
    writeq(cfg_u.data, &dmac->channel[channel_num].cfg);
 | 
			
		||||
 | 
			
		||||
    dmac->channel[channel_num].sar = (uint64_t)src;
 | 
			
		||||
    dmac->channel[channel_num].dar = (uint64_t)dest;
 | 
			
		||||
 | 
			
		||||
    ctl.data = readq(&dmac->channel[channel_num].ctl);
 | 
			
		||||
    ctl.ch_ctl.sms = DMAC_MASTER1;
 | 
			
		||||
    ctl.ch_ctl.dms = DMAC_MASTER2;
 | 
			
		||||
    /* master select */
 | 
			
		||||
    ctl.ch_ctl.sinc = src_inc;
 | 
			
		||||
    ctl.ch_ctl.dinc = dest_inc;
 | 
			
		||||
    /* address incrememt */
 | 
			
		||||
    ctl.ch_ctl.src_tr_width = dmac_trans_width;
 | 
			
		||||
    ctl.ch_ctl.dst_tr_width  = dmac_trans_width;
 | 
			
		||||
    /* transfer width */
 | 
			
		||||
    ctl.ch_ctl.src_msize = dmac_burst_size;
 | 
			
		||||
    ctl.ch_ctl.dst_msize = dmac_burst_size;
 | 
			
		||||
 | 
			
		||||
    writeq(ctl.data, &dmac->channel[channel_num].ctl);
 | 
			
		||||
 | 
			
		||||
    writeq(blockSize - 1, &dmac->channel[channel_num].block_ts);
 | 
			
		||||
    /*the number of (blcok_ts +1) data of width SRC_TR_WIDTF to be */
 | 
			
		||||
    /* transferred in a dma block transfer */
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dmac_get_channel_config(dmac_channel_number_t channel_num,
 | 
			
		||||
        dmac_channel_config_t *cfg_param)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_ctl_u_t  ctl;
 | 
			
		||||
    dmac_ch_cfg_u_t cfg;
 | 
			
		||||
    dmac_ch_llp_u_t ch_llp;
 | 
			
		||||
 | 
			
		||||
    if (cfg_param == 0)
 | 
			
		||||
        return -1;
 | 
			
		||||
    if (channel_num < DMAC_CHANNEL0 ||
 | 
			
		||||
        channel_num > DMAC_CHANNEL3)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
    ctl.data = readq(&dmac->channel[channel_num].ctl);
 | 
			
		||||
 | 
			
		||||
    cfg_param->ctl_sms = ctl.ch_ctl.sms;
 | 
			
		||||
    cfg_param->ctl_dms = ctl.ch_ctl.dms;
 | 
			
		||||
    cfg_param->ctl_sinc = ctl.ch_ctl.sinc;
 | 
			
		||||
    cfg_param->ctl_dinc = ctl.ch_ctl.dinc;
 | 
			
		||||
    cfg_param->ctl_src_tr_width = ctl.ch_ctl.src_tr_width;
 | 
			
		||||
    cfg_param->ctl_dst_tr_width = ctl.ch_ctl.dst_tr_width;
 | 
			
		||||
    cfg_param->ctl_src_msize = ctl.ch_ctl.src_msize;
 | 
			
		||||
    cfg_param->ctl_drc_msize = ctl.ch_ctl.dst_msize;
 | 
			
		||||
    cfg_param->ctl_ioc_blktfr = ctl.ch_ctl.ioc_blktfr;
 | 
			
		||||
 | 
			
		||||
    cfg.data = readq(&dmac->channel[channel_num].cfg);
 | 
			
		||||
    cfg_param->cfg_hs_sel_src = cfg.ch_cfg.hs_sel_src;
 | 
			
		||||
    cfg_param->cfg_hs_sel_dst = cfg.ch_cfg.hs_sel_dst;
 | 
			
		||||
    cfg_param->cfg_src_hs_pol = cfg.ch_cfg.src_hwhs_pol;
 | 
			
		||||
    cfg_param->cfg_dst_hs_pol =  cfg.ch_cfg.dst_hwhs_pol;
 | 
			
		||||
    cfg_param->cfg_src_per = cfg.ch_cfg.src_per;
 | 
			
		||||
    cfg_param->cfg_dst_per = cfg.ch_cfg.dst_per;
 | 
			
		||||
    cfg_param->cfg_ch_prior = cfg.ch_cfg.ch_prior;
 | 
			
		||||
    cfg_param->cfg_src_multblk_type = cfg.ch_cfg.src_multblk_type;
 | 
			
		||||
    cfg_param->cfg_dst_multblk_type = cfg.ch_cfg.dst_multblk_type;
 | 
			
		||||
 | 
			
		||||
    cfg_param->sar = dmac->channel[channel_num].sar;
 | 
			
		||||
    cfg_param->dar = dmac->channel[channel_num].dar;
 | 
			
		||||
 | 
			
		||||
    ch_llp.data = readq(&dmac->channel[channel_num].llp);
 | 
			
		||||
    cfg_param->llp_loc = ch_llp.llp.loc;
 | 
			
		||||
    cfg_param->llp_lms = ch_llp.llp.lms;
 | 
			
		||||
 | 
			
		||||
    cfg_param->ctl_block_ts = readq(&dmac->channel[channel_num].block_ts);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_set_address(dmac_channel_number_t channel_num, uint64_t src_addr,
 | 
			
		||||
        uint64_t dst_addr)
 | 
			
		||||
{
 | 
			
		||||
    writeq(src_addr, &dmac->channel[channel_num].sar);
 | 
			
		||||
    writeq(dst_addr, &dmac->channel[channel_num].dar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_set_block_ts(dmac_channel_number_t channel_num,
 | 
			
		||||
        uint32_t BlockSize)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t block_ts;
 | 
			
		||||
 | 
			
		||||
    block_ts = BlockSize & 0x3fffff;
 | 
			
		||||
    writeq(block_ts, &dmac->channel[channel_num].block_ts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_source_control(dmac_channel_number_t channel_num,
 | 
			
		||||
        dmac_master_number_t master_select,
 | 
			
		||||
        dmac_address_increment_t address_mode,
 | 
			
		||||
        dmac_transfer_width_t tr_width,
 | 
			
		||||
        dmac_burst_trans_length_t burst_length)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_ctl_u_t ctl_u;
 | 
			
		||||
 | 
			
		||||
    ctl_u.data = readq(&dmac->channel[channel_num].ctl);
 | 
			
		||||
    ctl_u.ch_ctl.sms = master_select;
 | 
			
		||||
    ctl_u.ch_ctl.sinc = address_mode;
 | 
			
		||||
    ctl_u.ch_ctl.src_tr_width = tr_width;
 | 
			
		||||
    ctl_u.ch_ctl.src_msize = burst_length;
 | 
			
		||||
 | 
			
		||||
    writeq(ctl_u.data, &dmac->channel[channel_num].ctl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_master_control(dmac_channel_number_t channel_num,
 | 
			
		||||
        dmac_master_number_t master_select,
 | 
			
		||||
        dmac_address_increment_t address_mode,
 | 
			
		||||
        dmac_transfer_width_t tr_width,
 | 
			
		||||
        dmac_burst_trans_length_t burst_length)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_ctl_u_t ctl_u;
 | 
			
		||||
 | 
			
		||||
    ctl_u.data = readq(&dmac->channel[channel_num].ctl);
 | 
			
		||||
    ctl_u.ch_ctl.dms = master_select;
 | 
			
		||||
    ctl_u.ch_ctl.dinc = address_mode;
 | 
			
		||||
    ctl_u.ch_ctl.dst_tr_width = tr_width;
 | 
			
		||||
    ctl_u.ch_ctl.dst_msize = burst_length;
 | 
			
		||||
 | 
			
		||||
    writeq(ctl_u.data, &dmac->channel[channel_num].ctl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_set_source_transfer_control(dmac_channel_number_t channel_num,
 | 
			
		||||
                dmac_multiblk_transfer_type_t transfer_type,
 | 
			
		||||
                dmac_sw_hw_hs_select_t handshak_select)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_cfg_u_t cfg_u;
 | 
			
		||||
 | 
			
		||||
    cfg_u.data = readq(&dmac->channel[channel_num].cfg);
 | 
			
		||||
    cfg_u.ch_cfg.src_multblk_type = transfer_type;
 | 
			
		||||
    cfg_u.ch_cfg.hs_sel_src = handshak_select;
 | 
			
		||||
 | 
			
		||||
    writeq(cfg_u.data, &dmac->channel[channel_num].cfg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_set_destination_transfer_control(dmac_channel_number_t channel_num,
 | 
			
		||||
                dmac_multiblk_transfer_type_t transfer_type,
 | 
			
		||||
                dmac_sw_hw_hs_select_t handshak_select)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_cfg_u_t cfg_u;
 | 
			
		||||
 | 
			
		||||
    cfg_u.data = readq(&dmac->channel[channel_num].cfg);
 | 
			
		||||
    cfg_u.ch_cfg.dst_multblk_type = transfer_type;
 | 
			
		||||
    cfg_u.ch_cfg.hs_sel_dst = handshak_select;
 | 
			
		||||
 | 
			
		||||
    writeq(cfg_u.data, &dmac->channel[channel_num].cfg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_set_flow_control(dmac_channel_number_t channel_num,
 | 
			
		||||
            dmac_transfer_flow_t flow_control)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_cfg_u_t cfg_u;
 | 
			
		||||
 | 
			
		||||
    cfg_u.data = readq(&dmac->channel[channel_num].cfg);
 | 
			
		||||
    cfg_u.ch_cfg.tt_fc = flow_control;
 | 
			
		||||
 | 
			
		||||
    writeq(cfg_u.data, &dmac->channel[channel_num].cfg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_set_linked_list_addr_point(dmac_channel_number_t channel_num,
 | 
			
		||||
            uint64_t *addr)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_llp_u_t llp_u;
 | 
			
		||||
 | 
			
		||||
    llp_u.data = readq(&dmac->channel[channel_num].llp);
 | 
			
		||||
    /* Cast pointer to uint64_t */
 | 
			
		||||
    llp_u.llp.loc = (uint64_t)addr;
 | 
			
		||||
    writeq(llp_u.data, &dmac->channel[channel_num].llp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DmacInit(void)
 | 
			
		||||
{
 | 
			
		||||
    uint64_t tmp;
 | 
			
		||||
    dmac_commonreg_intclear_u_t intclear;
 | 
			
		||||
    dmac_cfg_u_t dmac_cfg;
 | 
			
		||||
    dmac_reset_u_t dmac_reset;
 | 
			
		||||
 | 
			
		||||
    sysctl_clock_enable(SYSCTL_CLOCK_DMA);
 | 
			
		||||
 | 
			
		||||
    dmac_reset.data = readq(&dmac->reset);
 | 
			
		||||
    dmac_reset.reset.rst = 1;
 | 
			
		||||
    writeq(dmac_reset.data, &dmac->reset);
 | 
			
		||||
    while (dmac_reset.reset.rst)
 | 
			
		||||
        dmac_reset.data = readq(&dmac->reset);
 | 
			
		||||
 | 
			
		||||
    /*reset dmac */
 | 
			
		||||
 | 
			
		||||
    intclear.data = readq(&dmac->com_intclear);
 | 
			
		||||
    intclear.com_intclear.cear_slvif_dec_err_intstat = 1;
 | 
			
		||||
    intclear.com_intclear.clear_slvif_wr2ro_err_intstat = 1;
 | 
			
		||||
    intclear.com_intclear.clear_slvif_rd2wo_err_intstat = 1;
 | 
			
		||||
    intclear.com_intclear.clear_slvif_wronhold_err_intstat = 1;
 | 
			
		||||
    intclear.com_intclear.clear_slvif_undefinedreg_dec_err_intstat = 1;
 | 
			
		||||
    writeq(intclear.data, &dmac->com_intclear);
 | 
			
		||||
    /* clear common register interrupt */
 | 
			
		||||
 | 
			
		||||
    dmac_cfg.data = readq(&dmac->cfg);
 | 
			
		||||
    dmac_cfg.cfg.dmac_en = 0;
 | 
			
		||||
    dmac_cfg.cfg.int_en = 0;
 | 
			
		||||
    writeq(dmac_cfg.data, &dmac->cfg);
 | 
			
		||||
    /* disable dmac and disable interrupt */
 | 
			
		||||
 | 
			
		||||
    while (readq(&dmac->cfg))
 | 
			
		||||
        ;
 | 
			
		||||
    tmp = readq(&dmac->chen);
 | 
			
		||||
    tmp &= ~0xf;
 | 
			
		||||
    writeq(tmp, &dmac->chen);
 | 
			
		||||
    /* disable all channel before configure */
 | 
			
		||||
    dmac_enable();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void list_add(struct list_head_t *new, struct list_head_t *prev,
 | 
			
		||||
        struct list_head_t *next)
 | 
			
		||||
{
 | 
			
		||||
    next->prev = new;
 | 
			
		||||
    new->next = next;
 | 
			
		||||
    new->prev = prev;
 | 
			
		||||
    prev->next = new;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void list_add_tail(struct list_head_t *new, struct list_head_t *head)
 | 
			
		||||
{
 | 
			
		||||
    list_add(new, head->prev, head);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void INIT_LIST_HEAD(struct list_head_t *list)
 | 
			
		||||
{
 | 
			
		||||
    list->next = list;
 | 
			
		||||
    list->prev = list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_link_list_item(dmac_channel_number_t channel_num,
 | 
			
		||||
    uint8_t LLI_row_num, int8_t LLI_last_row,
 | 
			
		||||
    dmac_lli_item_t *lli_item,
 | 
			
		||||
    dmac_channel_config_t *cfg_param)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_ctl_u_t ctl;
 | 
			
		||||
    dmac_ch_llp_u_t  llp_u;
 | 
			
		||||
 | 
			
		||||
    lli_item[LLI_row_num].sar = cfg_param->sar;
 | 
			
		||||
    lli_item[LLI_row_num].dar = cfg_param->dar;
 | 
			
		||||
 | 
			
		||||
    ctl.data = readq(&dmac->channel[channel_num].ctl);
 | 
			
		||||
    ctl.ch_ctl.sms = cfg_param->ctl_sms;
 | 
			
		||||
    ctl.ch_ctl.dms = cfg_param->ctl_dms;
 | 
			
		||||
    ctl.ch_ctl.sinc = cfg_param->ctl_sinc;
 | 
			
		||||
    ctl.ch_ctl.dinc = cfg_param->ctl_dinc;
 | 
			
		||||
    ctl.ch_ctl.src_tr_width = cfg_param->ctl_src_tr_width;
 | 
			
		||||
    ctl.ch_ctl.dst_tr_width = cfg_param->ctl_dst_tr_width;
 | 
			
		||||
    ctl.ch_ctl.src_msize = cfg_param->ctl_src_msize;
 | 
			
		||||
    ctl.ch_ctl.dst_msize = cfg_param->ctl_drc_msize;
 | 
			
		||||
    ctl.ch_ctl.src_stat_en = cfg_param->ctl_src_stat_en;
 | 
			
		||||
    ctl.ch_ctl.dst_stat_en = cfg_param->ctl_dst_stat_en;
 | 
			
		||||
 | 
			
		||||
    if (LLI_last_row != LAST_ROW) {
 | 
			
		||||
        ctl.ch_ctl.shadowreg_or_lli_valid = 1;
 | 
			
		||||
        ctl.ch_ctl.shadowreg_or_lli_last = 0;
 | 
			
		||||
    } else {
 | 
			
		||||
        ctl.ch_ctl.shadowreg_or_lli_valid = 1;
 | 
			
		||||
        ctl.ch_ctl.shadowreg_or_lli_last = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lli_item[LLI_row_num].ctl = ctl.data;
 | 
			
		||||
 | 
			
		||||
    lli_item[LLI_row_num].ch_block_ts = cfg_param->ctl_block_ts;
 | 
			
		||||
    lli_item[LLI_row_num].sstat = 0;
 | 
			
		||||
    lli_item[LLI_row_num].dstat = 0;
 | 
			
		||||
 | 
			
		||||
    llp_u.data = readq(&dmac->channel[channel_num].llp);
 | 
			
		||||
 | 
			
		||||
    if (LLI_last_row != LAST_ROW)
 | 
			
		||||
        llp_u.llp.loc = ((uint64_t)&lli_item[LLI_row_num + 1]) >> 6;
 | 
			
		||||
    else
 | 
			
		||||
        llp_u.llp.loc = 0;
 | 
			
		||||
 | 
			
		||||
    lli_item[LLI_row_num].llp = llp_u.data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_update_shandow_register(dmac_channel_number_t channel_num,
 | 
			
		||||
        int8_t last_block, dmac_channel_config_t *cfg_param)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_ctl_u_t ctl_u;
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
        ctl_u.data = readq(&dmac->channel[channel_num].ctl);
 | 
			
		||||
    } while (ctl_u.ch_ctl.shadowreg_or_lli_valid);
 | 
			
		||||
 | 
			
		||||
    writeq(cfg_param->sar, &dmac->channel[channel_num].sar);
 | 
			
		||||
    writeq(cfg_param->dar, &dmac->channel[channel_num].dar);
 | 
			
		||||
    writeq(cfg_param->ctl_block_ts, &dmac->channel[channel_num].block_ts);
 | 
			
		||||
 | 
			
		||||
    ctl_u.ch_ctl.sms = cfg_param->ctl_sms;
 | 
			
		||||
    ctl_u.ch_ctl.dms = cfg_param->ctl_dms;
 | 
			
		||||
    ctl_u.ch_ctl.sinc = cfg_param->ctl_sinc;
 | 
			
		||||
    ctl_u.ch_ctl.dinc = cfg_param->ctl_dinc;
 | 
			
		||||
    ctl_u.ch_ctl.src_tr_width = cfg_param->ctl_src_tr_width;
 | 
			
		||||
    ctl_u.ch_ctl.dst_tr_width = cfg_param->ctl_dst_tr_width;
 | 
			
		||||
    ctl_u.ch_ctl.src_msize = cfg_param->ctl_src_msize;
 | 
			
		||||
    ctl_u.ch_ctl.dst_msize = cfg_param->ctl_drc_msize;
 | 
			
		||||
    ctl_u.ch_ctl.src_stat_en = cfg_param->ctl_src_stat_en;
 | 
			
		||||
    ctl_u.ch_ctl.dst_stat_en = cfg_param->ctl_dst_stat_en;
 | 
			
		||||
    if (last_block != LAST_ROW)
 | 
			
		||||
    {
 | 
			
		||||
        ctl_u.ch_ctl.shadowreg_or_lli_valid = 1;
 | 
			
		||||
        ctl_u.ch_ctl.shadowreg_or_lli_last = 0;
 | 
			
		||||
    } else {
 | 
			
		||||
        ctl_u.ch_ctl.shadowreg_or_lli_valid = 1;
 | 
			
		||||
        ctl_u.ch_ctl.shadowreg_or_lli_last = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    writeq(ctl_u.data, &dmac->channel[channel_num].ctl);
 | 
			
		||||
    writeq(0, &dmac->channel[channel_num].blk_tfr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_set_shadow_invalid_flag(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    dmac_ch_ctl_u_t ctl_u;
 | 
			
		||||
 | 
			
		||||
    ctl_u.data = readq(&dmac->channel[channel_num].ctl);
 | 
			
		||||
    ctl_u.ch_ctl.shadowreg_or_lli_valid = 1;
 | 
			
		||||
    ctl_u.ch_ctl.shadowreg_or_lli_last = 0;
 | 
			
		||||
    writeq(ctl_u.data, &dmac->channel[channel_num].ctl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_set_single_mode(dmac_channel_number_t channel_num,
 | 
			
		||||
                          const void *src, void *dest, dmac_address_increment_t src_inc,
 | 
			
		||||
                          dmac_address_increment_t dest_inc,
 | 
			
		||||
                          dmac_burst_trans_length_t dmac_burst_size,
 | 
			
		||||
                          dmac_transfer_width_t dmac_trans_width,
 | 
			
		||||
                          size_t BlockSize) {
 | 
			
		||||
    dmac_chanel_interrupt_clear(channel_num);
 | 
			
		||||
    dmac_channel_disable(channel_num);
 | 
			
		||||
    dmac_wait_idle(channel_num);
 | 
			
		||||
    dmac_set_channel_param(channel_num, src, dest, src_inc, dest_inc,
 | 
			
		||||
                           dmac_burst_size, dmac_trans_width, BlockSize);
 | 
			
		||||
    dmac_enable();
 | 
			
		||||
    dmac_channel_enable(channel_num);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dmac_is_done(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    if(readq(&dmac->channel[channel_num].intstatus) & 0x2)
 | 
			
		||||
        return 1;
 | 
			
		||||
    else
 | 
			
		||||
        return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_wait_done(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    dmac_wait_idle(channel_num);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dmac_is_idle(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    dmac_chen_u_t chen;
 | 
			
		||||
    chen.data = readq(&dmac->chen);
 | 
			
		||||
    if((chen.data >> channel_num) & 0x1UL)
 | 
			
		||||
        return 0;
 | 
			
		||||
    else
 | 
			
		||||
        return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_wait_idle(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    while(!dmac_is_idle(channel_num));
 | 
			
		||||
    dmac_chanel_interrupt_clear(channel_num); /* clear interrupt */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_set_src_dest_length(dmac_channel_number_t channel_num, const void *src, void *dest, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    if(src != NULL)
 | 
			
		||||
        dmac->channel[channel_num].sar = (uint64_t)src;
 | 
			
		||||
    if(dest != NULL)
 | 
			
		||||
        dmac->channel[channel_num].dar = (uint64_t)dest;
 | 
			
		||||
    if(len > 0)
 | 
			
		||||
        dmac_set_block_ts(channel_num, len - 1);
 | 
			
		||||
    dmac_channel_enable(channel_num);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dmac_irq_callback(void *ctx)
 | 
			
		||||
{
 | 
			
		||||
    dmac_context_t *v_dmac_context = (dmac_context_t *)(ctx);
 | 
			
		||||
    dmac_channel_number_t v_dmac_channel = v_dmac_context->dmac_channel;
 | 
			
		||||
    dmac_chanel_interrupt_clear(v_dmac_channel);
 | 
			
		||||
    if(v_dmac_context->callback != NULL)
 | 
			
		||||
        v_dmac_context->callback(v_dmac_context->ctx);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmac_irq_register(dmac_channel_number_t channel_num , plic_irq_callback_t dmac_callback, void *ctx, uint32_t priority)
 | 
			
		||||
{
 | 
			
		||||
    dmac_context[channel_num].dmac_channel = channel_num;
 | 
			
		||||
    dmac_context[channel_num].callback = dmac_callback;
 | 
			
		||||
    dmac_context[channel_num].ctx = ctx;
 | 
			
		||||
    dmac_enable_channel_interrupt(channel_num);
 | 
			
		||||
    plic_set_priority(IRQN_DMA0_INTERRUPT + channel_num, priority);
 | 
			
		||||
    plic_irq_enable(IRQN_DMA0_INTERRUPT + channel_num);
 | 
			
		||||
    plic_irq_register(IRQN_DMA0_INTERRUPT + channel_num, dmac_irq_callback, &dmac_context[channel_num]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void __attribute__((weak, alias("dmac_irq_register"))) dmac_set_irq(dmac_channel_number_t channel_num , plic_irq_callback_t dmac_callback, void *ctx, uint32_t priority);
 | 
			
		||||
 | 
			
		||||
void dmac_irq_unregister(dmac_channel_number_t channel_num)
 | 
			
		||||
{
 | 
			
		||||
    dmac_context[channel_num].callback = NULL;
 | 
			
		||||
    dmac_context[channel_num].ctx = NULL;
 | 
			
		||||
    dmac_disable_channel_interrupt(channel_num);
 | 
			
		||||
    plic_irq_unregister(IRQN_DMA0_INTERRUPT + channel_num);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void __attribute__((weak, alias("dmac_irq_unregister"))) dmac_free_irq(dmac_channel_number_t channel_num);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
config PIN_BUS_NAME
 | 
			
		||||
    string "pin bus name"
 | 
			
		||||
    default "pin"
 | 
			
		||||
 | 
			
		||||
config PIN_DRIVER_NAME
 | 
			
		||||
    string "pin driver name"
 | 
			
		||||
    default "pin_drv"
 | 
			
		||||
 | 
			
		||||
config PIN_DEVICE_NAME
 | 
			
		||||
    string "pin device name"
 | 
			
		||||
    default "pin_dev"
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
SRC_FILES := connect_gpio.c drv_io_config.c fpioa.c gpio.c gpiohs.c utils.c
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,331 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2006-2018, RT-Thread Development Team
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Change Logs:
 | 
			
		||||
 * Date           Author       Notes
 | 
			
		||||
 * 2019-03-19     ZYH          first version
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @file connect_gpio.c
 | 
			
		||||
* @brief support gpio function using bus driver framework
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
File name: connect_gpio.c
 | 
			
		||||
Description: support  gpio configure and register to bus framework
 | 
			
		||||
Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_gpio.c for references
 | 
			
		||||
                https://github.com/RT-Thread/rt-thread/tree/v4.0.2
 | 
			
		||||
History: 
 | 
			
		||||
1. Date: 2022-10-17
 | 
			
		||||
Author: AIIT XUOS Lab
 | 
			
		||||
Modification: add bus driver framework support for gpio
 | 
			
		||||
*************************************************/
 | 
			
		||||
 | 
			
		||||
#include <xizi.h>
 | 
			
		||||
#include <device.h>
 | 
			
		||||
#include <fpioa.h>
 | 
			
		||||
#include <gpiohs.h>
 | 
			
		||||
#include "drv_io_config.h"
 | 
			
		||||
#include <plic.h>
 | 
			
		||||
#include <utils.h>
 | 
			
		||||
#include "connect_gpio.h"
 | 
			
		||||
 | 
			
		||||
#define FUNC_GPIOHS(n) (FUNC_GPIOHS0 + n)
 | 
			
		||||
 | 
			
		||||
static int pin_alloc_table[FPIOA_NUM_IO];
 | 
			
		||||
static uint32_t free_pin = 0;
 | 
			
		||||
 | 
			
		||||
static int AllocPinChannel(x_base pin_index)
 | 
			
		||||
{
 | 
			
		||||
    if (free_pin == 31) {
 | 
			
		||||
        SYS_ERR("no free gpiohs channel to alloc");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (pin_alloc_table[pin_index] != -1) {
 | 
			
		||||
        SYS_WARN("already alloc gpiohs channel for pin %d", pin_index);
 | 
			
		||||
        return pin_alloc_table[pin_index];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pin_alloc_table[pin_index] = free_pin;
 | 
			
		||||
    free_pin++;
 | 
			
		||||
 | 
			
		||||
    FpioaSetFunction(pin_index, FUNC_GPIOHS(pin_alloc_table[pin_index]));
 | 
			
		||||
    return pin_alloc_table[pin_index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int GetPinChannel(x_base pin_index)
 | 
			
		||||
{
 | 
			
		||||
    return pin_alloc_table[pin_index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 GpioConfigMode(int mode, uint8_t pin_channel)
 | 
			
		||||
{
 | 
			
		||||
    switch (mode)
 | 
			
		||||
    {
 | 
			
		||||
        case GPIO_CFG_OUTPUT:
 | 
			
		||||
            gpiohs_set_drive_mode(pin_channel, GPIO_DM_OUTPUT);
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_CFG_INPUT:
 | 
			
		||||
            gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT);
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_CFG_INPUT_PULLUP:
 | 
			
		||||
            gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT_PULL_UP);
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_CFG_INPUT_PULLDOWN:
 | 
			
		||||
            gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT_PULL_DOWN);
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_CFG_OUTPUT_OD:
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    return EOK;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct 
 | 
			
		||||
{
 | 
			
		||||
    void (*hdr)(void *args);
 | 
			
		||||
    void *args;
 | 
			
		||||
    GpioPinEdgeT edge;
 | 
			
		||||
} IrqTable[32];
 | 
			
		||||
 | 
			
		||||
static void pin_irq(int vector, void *param)
 | 
			
		||||
{
 | 
			
		||||
    int pin_channel = vector - IRQN_GPIOHS0_INTERRUPT;
 | 
			
		||||
    if (IrqTable[pin_channel].edge & GPIO_PE_FALLING) {
 | 
			
		||||
        set_gpio_bit(gpiohs->fall_ie.u32, pin_channel, 0);
 | 
			
		||||
        set_gpio_bit(gpiohs->fall_ip.u32, pin_channel, 1);
 | 
			
		||||
        set_gpio_bit(gpiohs->fall_ie.u32, pin_channel, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (IrqTable[pin_channel].edge & GPIO_PE_RISING) {
 | 
			
		||||
        set_gpio_bit(gpiohs->rise_ie.u32, pin_channel, 0);
 | 
			
		||||
        set_gpio_bit(gpiohs->rise_ip.u32, pin_channel, 1);
 | 
			
		||||
        set_gpio_bit(gpiohs->rise_ie.u32, pin_channel, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (IrqTable[pin_channel].edge & GPIO_PE_LOW) {
 | 
			
		||||
        set_gpio_bit(gpiohs->low_ie.u32, pin_channel, 0);
 | 
			
		||||
        set_gpio_bit(gpiohs->low_ip.u32, pin_channel, 1);
 | 
			
		||||
        set_gpio_bit(gpiohs->low_ie.u32, pin_channel, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (IrqTable[pin_channel].edge & GPIO_PE_HIGH) {
 | 
			
		||||
        set_gpio_bit(gpiohs->high_ie.u32, pin_channel, 0);
 | 
			
		||||
        set_gpio_bit(gpiohs->high_ip.u32, pin_channel, 1);
 | 
			
		||||
        set_gpio_bit(gpiohs->high_ie.u32, pin_channel, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (IrqTable[pin_channel].hdr) {
 | 
			
		||||
        IrqTable[pin_channel].hdr(IrqTable[pin_channel].args);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 GpioIrqRegister(int32 pin_channel, int32 mode, void (*hdr)(void *args), void *args)
 | 
			
		||||
{
 | 
			
		||||
    IrqTable[pin_channel].hdr = hdr;
 | 
			
		||||
    IrqTable[pin_channel].args = args;
 | 
			
		||||
    switch (mode)
 | 
			
		||||
    {
 | 
			
		||||
        case GPIO_IRQ_EDGE_RISING:
 | 
			
		||||
            IrqTable[pin_channel].edge = GPIO_PE_RISING;
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_IRQ_EDGE_FALLING:
 | 
			
		||||
            IrqTable[pin_channel].edge = GPIO_PE_FALLING;
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_IRQ_EDGE_BOTH:
 | 
			
		||||
            IrqTable[pin_channel].edge = GPIO_PE_BOTH;
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_IRQ_LEVEL_HIGH:
 | 
			
		||||
            IrqTable[pin_channel].edge = GPIO_PE_LOW;
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_IRQ_LEVEL_LOW:
 | 
			
		||||
            IrqTable[pin_channel].edge = GPIO_PE_HIGH;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    gpiohs_set_pin_edge(pin_channel, IrqTable[pin_channel].edge);
 | 
			
		||||
 | 
			
		||||
    isrManager.done->registerIrq(IRQN_GPIOHS0_INTERRUPT + pin_channel, pin_irq, NONE);
 | 
			
		||||
 
 | 
			
		||||
    return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 GpioIrqFree(int32 pin_channel)
 | 
			
		||||
{
 | 
			
		||||
    IrqTable[pin_channel].hdr = NONE;
 | 
			
		||||
    IrqTable[pin_channel].args = NONE;
 | 
			
		||||
    return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 GpioIrqEnable(int32 pin_channel)
 | 
			
		||||
{
 | 
			
		||||
    isrManager.done->enableIrq(IRQN_GPIOHS0_INTERRUPT + pin_channel);
 | 
			
		||||
    
 | 
			
		||||
    return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 GpioIrqDisable(int32 pin_channel)
 | 
			
		||||
{
 | 
			
		||||
     isrManager.done->disableIrq(IRQN_GPIOHS0_INTERRUPT + pin_channel);
 | 
			
		||||
     return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 PinConfigure(struct PinParam *param)
 | 
			
		||||
{
 | 
			
		||||
    NULL_PARAM_CHECK(param);
 | 
			
		||||
    int ret = EOK;
 | 
			
		||||
 | 
			
		||||
    int pin_channel = GetPinChannel(param->pin);
 | 
			
		||||
    if (pin_channel == -1) {
 | 
			
		||||
        pin_channel = AllocPinChannel(param->pin);
 | 
			
		||||
        if (pin_channel == -1) {
 | 
			
		||||
            return ERROR;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (param->cmd)
 | 
			
		||||
    {
 | 
			
		||||
        case GPIO_CONFIG_MODE:
 | 
			
		||||
            GpioConfigMode(param->mode, pin_channel);
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_IRQ_REGISTER:
 | 
			
		||||
            ret = GpioIrqRegister(pin_channel,param->irq_set.irq_mode,param->irq_set.hdr,param->irq_set.args);
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_IRQ_FREE:
 | 
			
		||||
            ret = GpioIrqFree(pin_channel);
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_IRQ_ENABLE:
 | 
			
		||||
            ret = GpioIrqEnable(pin_channel);
 | 
			
		||||
            break;
 | 
			
		||||
        case GPIO_IRQ_DISABLE:
 | 
			
		||||
            ret = GpioIrqDisable(pin_channel);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            ret = -EINVALED;
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 GpioDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
 | 
			
		||||
{
 | 
			
		||||
    NULL_PARAM_CHECK(drv);
 | 
			
		||||
    NULL_PARAM_CHECK(configure_info);
 | 
			
		||||
 | 
			
		||||
    x_err_t ret = EOK;
 | 
			
		||||
    struct PinParam *param;
 | 
			
		||||
 | 
			
		||||
    switch (configure_info->configure_cmd)
 | 
			
		||||
    {
 | 
			
		||||
        case OPE_CFG:
 | 
			
		||||
            param = (struct PinParam *)configure_info->private_data;
 | 
			
		||||
            ret = PinConfigure(param);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32 PinWrite(void *dev, struct BusBlockWriteParam *write_param)
 | 
			
		||||
{
 | 
			
		||||
    NULL_PARAM_CHECK(dev);
 | 
			
		||||
    NULL_PARAM_CHECK(write_param);
 | 
			
		||||
    struct PinStat *pinstat = (struct PinStat *)write_param->buffer;
 | 
			
		||||
    
 | 
			
		||||
    int pin_channel = GetPinChannel(pinstat->pin);
 | 
			
		||||
    if (pin_channel == -1) {
 | 
			
		||||
        SYS_ERR("pin %d not set mode", pinstat->pin);
 | 
			
		||||
        return ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    gpiohs_set_pin(pin_channel, pinstat->val == GPIO_HIGH ? GPIO_PV_HIGH : GPIO_PV_LOW);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32 PinRead(void *dev, struct BusBlockReadParam *read_param)
 | 
			
		||||
{
 | 
			
		||||
    NULL_PARAM_CHECK(dev);
 | 
			
		||||
    NULL_PARAM_CHECK(read_param);
 | 
			
		||||
    struct PinStat *pinstat = (struct PinStat *)read_param->buffer;
 | 
			
		||||
    
 | 
			
		||||
    int pin_channel = GetPinChannel(pinstat->pin);
 | 
			
		||||
    if (pin_channel == -1) {
 | 
			
		||||
        SYS_ERR("pin %d not set mode", pinstat->pin);
 | 
			
		||||
        return ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (gpiohs_get_pin(pin_channel) == GPIO_PV_HIGH){
 | 
			
		||||
        pinstat->val = GPIO_HIGH;
 | 
			
		||||
        return GPIO_HIGH;
 | 
			
		||||
    } else {
 | 
			
		||||
        pinstat->val = GPIO_LOW;
 | 
			
		||||
        return GPIO_LOW;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct PinDevDone dev_done =
 | 
			
		||||
{
 | 
			
		||||
    .open  = NONE,
 | 
			
		||||
    .close = NONE,
 | 
			
		||||
    .write = PinWrite,
 | 
			
		||||
    .read  = PinRead,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int HwGpioInit(void)
 | 
			
		||||
{
 | 
			
		||||
    x_err_t ret = EOK;
 | 
			
		||||
 | 
			
		||||
    static struct PinBus pin;
 | 
			
		||||
 | 
			
		||||
    memset(pin_alloc_table, -1, sizeof pin_alloc_table);
 | 
			
		||||
    free_pin = GPIO_ALLOC_START;
 | 
			
		||||
 | 
			
		||||
    ret = PinBusInit(&pin, PIN_BUS_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("gpio bus init error %d\n", ret);
 | 
			
		||||
        return ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static struct PinDriver drv;
 | 
			
		||||
    drv.configure = &GpioDrvConfigure;
 | 
			
		||||
    
 | 
			
		||||
    ret = PinDriverInit(&drv, PIN_DRIVER_NAME, NONE);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("pin driver init error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ret = PinDriverAttachToBus(PIN_DRIVER_NAME, PIN_BUS_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("pin driver attach error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static struct PinHardwareDevice dev;
 | 
			
		||||
    dev.dev_done = &dev_done;
 | 
			
		||||
 | 
			
		||||
    ret = PinDeviceRegister(&dev, NONE, PIN_DEVICE_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("pin device register error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ret = PinDeviceAttachToBus(PIN_DEVICE_NAME, PIN_BUS_NAME);
 | 
			
		||||
    if (ret != EOK) {
 | 
			
		||||
        KPrintf("pin device register error %d\n", ret);
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,146 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2006-2018, RT-Thread Development Team
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Change Logs:
 | 
			
		||||
 * Date           Author       Notes
 | 
			
		||||
 * 2019-03-19     ZYH          first version
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @file drv_io_config.c
 | 
			
		||||
* @brief support edu-riscv64-board io configure
 | 
			
		||||
* @version 2.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
File name: drv_io_config.c
 | 
			
		||||
Description: support kd233-board io configure
 | 
			
		||||
Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.c for references
 | 
			
		||||
                https://github.com/RT-Thread/rt-thread/tree/v4.0.2
 | 
			
		||||
History: 
 | 
			
		||||
1. Date: 2022-10-17
 | 
			
		||||
Author: AIIT XUOS Lab
 | 
			
		||||
Modification: support kd233-board io configure
 | 
			
		||||
*************************************************/
 | 
			
		||||
 | 
			
		||||
#include <xizi.h>
 | 
			
		||||
#include <fpioa.h>
 | 
			
		||||
#include "drv_io_config.h"
 | 
			
		||||
#include <sysctl.h>           
 | 
			
		||||
 | 
			
		||||
#define HS_GPIO(n) (FUNC_GPIOHS0 + n)
 | 
			
		||||
 | 
			
		||||
#define IOCONFIG(pin,func)  {pin, func, #func}
 | 
			
		||||
 | 
			
		||||
static struct io_config
 | 
			
		||||
{
 | 
			
		||||
    int io_num;
 | 
			
		||||
    fpioa_function_t func;
 | 
			
		||||
    const char * FuncName;
 | 
			
		||||
} io_config[] = 
 | 
			
		||||
{
 | 
			
		||||
#ifdef BSP_USING_LCD
 | 
			
		||||
    IOCONFIG(BSP_LCD_CS_PIN, FUNC_SPI0_SS0),                
 | 
			
		||||
    IOCONFIG(BSP_LCD_WR_PIN, FUNC_SPI0_SCLK),                
 | 
			
		||||
    IOCONFIG(BSP_LCD_DC_PIN, HS_GPIO(FPIOA_LCD_DC)),
 | 
			
		||||
    IOCONFIG(BSP_LCD_RST_PIN, HS_GPIO(FPIOA_LCD_RST)),     
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BSP_USING_SPI1
 | 
			
		||||
    IOCONFIG(BSP_SPI1_CLK_PIN, FUNC_SPI1_SCLK),
 | 
			
		||||
    IOCONFIG(BSP_SPI1_D0_PIN, FUNC_SPI1_D0),
 | 
			
		||||
    IOCONFIG(BSP_SPI1_D1_PIN, FUNC_SPI1_D1),
 | 
			
		||||
#ifdef BSP_USING_SPI1_AS_QSPI
 | 
			
		||||
    IOCONFIG(BSP_SPI1_D2_PIN, FUNC_SPI1_D2),
 | 
			
		||||
    IOCONFIG(BSP_SPI1_D3_PIN, FUNC_SPI1_D3),
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_SPI1_USING_SS0
 | 
			
		||||
    IOCONFIG(BSP_SPI1_SS0_PIN, HS_GPIO(SPI1_CS0_PIN)),
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BSP_USING_UART1
 | 
			
		||||
    IOCONFIG(BSP_UART1_TXD_PIN, FUNC_UART1_TX),
 | 
			
		||||
    IOCONFIG(BSP_UART1_RXD_PIN, FUNC_UART1_RX),
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_USING_UART2
 | 
			
		||||
    IOCONFIG(BSP_UART2_TXD_PIN, FUNC_UART2_TX),
 | 
			
		||||
    IOCONFIG(BSP_UART2_RXD_PIN, FUNC_UART2_RX),
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_USING_UART3
 | 
			
		||||
    IOCONFIG(BSP_UART3_TXD_PIN, FUNC_UART3_RX),
 | 
			
		||||
    IOCONFIG(BSP_UART3_RXD_PIN, FUNC_UART3_TX),
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_USING_I2C1
 | 
			
		||||
    IOCONFIG(BSP_I2C_SDA, FUNC_GPIO3),
 | 
			
		||||
    IOCONFIG(BSP_I2C_SCL, FUNC_GPIO4),
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_USING_TOUCH
 | 
			
		||||
    IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FPIOA_TOUCH_TP_INT)),
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BSP_USING_CH438
 | 
			
		||||
    IOCONFIG(BSP_CH438_ALE_PIN,  HS_GPIO(FPIOA_CH438_ALE)),      
 | 
			
		||||
    IOCONFIG(BSP_CH438_NWR_PIN,  HS_GPIO(FPIOA_CH438_NWR)),      
 | 
			
		||||
    IOCONFIG(BSP_CH438_NRD_PIN,  HS_GPIO(FPIOA_CH438_NRD)),      
 | 
			
		||||
    IOCONFIG(BSP_CH438_INT_PIN,  HS_GPIO(FPIOA_CH438_INT)),      
 | 
			
		||||
    IOCONFIG(BSP_CH438_D0_PIN,  HS_GPIO(FPIOA_CH438_D0)),      
 | 
			
		||||
    IOCONFIG(BSP_CH438_D1_PIN,  HS_GPIO(FPIOA_CH438_D1)),      
 | 
			
		||||
    IOCONFIG(BSP_CH438_D2_PIN,  HS_GPIO(FPIOA_CH438_D2)),      
 | 
			
		||||
    IOCONFIG(BSP_CH438_D3_PIN,  HS_GPIO(FPIOA_CH438_D3)),      
 | 
			
		||||
    IOCONFIG(BSP_CH438_D4_PIN,  HS_GPIO(FPIOA_CH438_D4)),      
 | 
			
		||||
    IOCONFIG(BSP_CH438_D5_PIN,  HS_GPIO(FPIOA_CH438_D5)),      
 | 
			
		||||
    IOCONFIG(BSP_CH438_D6_PIN,  HS_GPIO(FPIOA_CH438_D6)),      
 | 
			
		||||
    IOCONFIG(BSP_CH438_D7_PIN,  HS_GPIO(FPIOA_CH438_D7))
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int PrintIoConfig()
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    KPrintf("IO Configuration Table\n");
 | 
			
		||||
    KPrintf("┌───────┬────────────────────────┐\n");
 | 
			
		||||
    KPrintf("│Pin    │Function                │\n");
 | 
			
		||||
    KPrintf("├───────┼────────────────────────┤\n");
 | 
			
		||||
    for(i = 0; i < sizeof io_config / sizeof io_config[0]; i++)
 | 
			
		||||
    {
 | 
			
		||||
        KPrintf("│%-2d     │%-24.24s│\n", io_config[i].io_num, io_config[i].FuncName);
 | 
			
		||||
    }
 | 
			
		||||
    KPrintf("└───────┴────────────────────────┘\n");
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),
 | 
			
		||||
                                                io,PrintIoConfig,print io config);
 | 
			
		||||
 | 
			
		||||
int IoConfigInit(void)
 | 
			
		||||
{
 | 
			
		||||
    int count = sizeof(io_config) / sizeof(io_config[0]);
 | 
			
		||||
    int i;
 | 
			
		||||
    int ret = 0;
 | 
			
		||||
 | 
			
		||||
    sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V18);
 | 
			
		||||
    sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18);
 | 
			
		||||
    sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18);
 | 
			
		||||
#ifdef BSP_USING_UART2
 | 
			
		||||
    // for IO-27/28
 | 
			
		||||
    sysctl_set_power_mode(SYSCTL_POWER_BANK4, SYSCTL_POWER_V33);
 | 
			
		||||
#endif
 | 
			
		||||
#if  defined(BSP_USING_UART1) || defined(BSP_USING_UART3)
 | 
			
		||||
    // for IO-20~23
 | 
			
		||||
    sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    for(i = 0; i < count; i++)
 | 
			
		||||
    {
 | 
			
		||||
        ret = FpioaSetFunction(io_config[i].io_num, io_config[i].func);
 | 
			
		||||
        if(ret != 0)
 | 
			
		||||
            return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,89 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 gpio.c
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "gpio.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
#include "fpioa.h"
 | 
			
		||||
#include "sysctl.h"
 | 
			
		||||
#define GPIO_MAX_PINNO 8
 | 
			
		||||
 | 
			
		||||
volatile gpio_t* const gpio = (volatile gpio_t*)GPIO_BASE_ADDR;
 | 
			
		||||
 | 
			
		||||
int gpio_init(void)
 | 
			
		||||
{
 | 
			
		||||
    return sysctl_clock_enable(SYSCTL_CLOCK_GPIO);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(pin < GPIO_MAX_PINNO);
 | 
			
		||||
    int io_number = fpioa_get_io_by_function(FUNC_GPIO0 + pin);
 | 
			
		||||
    configASSERT(io_number >= 0);
 | 
			
		||||
 | 
			
		||||
    fpioa_pull_t pull;
 | 
			
		||||
    uint32_t dir;
 | 
			
		||||
 | 
			
		||||
    switch (mode)
 | 
			
		||||
    {
 | 
			
		||||
    case GPIO_DM_INPUT:
 | 
			
		||||
        pull = FPIOA_PULL_NONE;
 | 
			
		||||
        dir = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case GPIO_DM_INPUT_PULL_DOWN:
 | 
			
		||||
        pull = FPIOA_PULL_DOWN;
 | 
			
		||||
        dir = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case GPIO_DM_INPUT_PULL_UP:
 | 
			
		||||
        pull = FPIOA_PULL_UP;
 | 
			
		||||
        dir = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case GPIO_DM_OUTPUT:
 | 
			
		||||
        pull = FPIOA_PULL_DOWN;
 | 
			
		||||
        dir = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        configASSERT(!"GPIO drive mode is not supported.") break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fpioa_set_io_pull(io_number, pull);
 | 
			
		||||
    set_gpio_bit(gpio->direction.u32, pin, dir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gpio_pin_value_t gpio_get_pin(uint8_t pin)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(pin < GPIO_MAX_PINNO);
 | 
			
		||||
    uint32_t dir = get_gpio_bit(gpio->direction.u32, pin);
 | 
			
		||||
    volatile uint32_t *reg = dir ? gpio->data_output.u32 : gpio->data_input.u32;
 | 
			
		||||
    return get_gpio_bit(reg, pin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void gpio_set_pin(uint8_t pin, gpio_pin_value_t value)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(pin < GPIO_MAX_PINNO);
 | 
			
		||||
    uint32_t dir = get_gpio_bit(gpio->direction.u32, pin);
 | 
			
		||||
    volatile uint32_t *reg = dir ? gpio->data_output.u32 : gpio->data_input.u32;
 | 
			
		||||
    configASSERT(dir == 1);
 | 
			
		||||
    set_gpio_bit(reg, pin, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,228 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 gpiohs.c
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "gpiohs.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
#include "fpioa.h"
 | 
			
		||||
#include "sysctl.h"
 | 
			
		||||
#define GPIOHS_MAX_PINNO 32
 | 
			
		||||
 | 
			
		||||
volatile gpiohs_t* const gpiohs = (volatile gpiohs_t*)GPIOHS_BASE_ADDR;
 | 
			
		||||
 | 
			
		||||
typedef struct _gpiohs_pin_instance
 | 
			
		||||
{
 | 
			
		||||
    size_t pin;
 | 
			
		||||
    GpioPinEdgeT edge;
 | 
			
		||||
    void (*callback)();
 | 
			
		||||
    plic_irq_callback_t gpiohs_callback;
 | 
			
		||||
    void *context;
 | 
			
		||||
} gpiohs_pin_instance_t;
 | 
			
		||||
 | 
			
		||||
static gpiohs_pin_instance_t pin_instance[32];
 | 
			
		||||
 | 
			
		||||
void gpiohs_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(pin < GPIOHS_MAX_PINNO);
 | 
			
		||||
    int io_number = fpioa_get_io_by_function(FUNC_GPIOHS0 + pin);
 | 
			
		||||
    configASSERT(io_number >= 0);
 | 
			
		||||
 | 
			
		||||
    fpioa_pull_t pull;
 | 
			
		||||
    uint32_t dir;
 | 
			
		||||
 | 
			
		||||
    switch (mode)
 | 
			
		||||
    {
 | 
			
		||||
    case GPIO_DM_INPUT:
 | 
			
		||||
        pull = FPIOA_PULL_NONE;
 | 
			
		||||
        dir = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case GPIO_DM_INPUT_PULL_DOWN:
 | 
			
		||||
        pull = FPIOA_PULL_DOWN;
 | 
			
		||||
        dir = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case GPIO_DM_INPUT_PULL_UP:
 | 
			
		||||
        pull = FPIOA_PULL_UP;
 | 
			
		||||
        dir = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case GPIO_DM_OUTPUT:
 | 
			
		||||
        pull = FPIOA_PULL_DOWN;
 | 
			
		||||
        dir = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        configASSERT(!"GPIO drive mode is not supported.") break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fpioa_set_io_pull(io_number, pull);
 | 
			
		||||
    volatile uint32_t *reg = dir ? gpiohs->output_en.u32 : gpiohs->input_en.u32;
 | 
			
		||||
    volatile uint32_t *reg_d = !dir ? gpiohs->output_en.u32 : gpiohs->input_en.u32;
 | 
			
		||||
    set_gpio_bit(reg_d, pin, 0);
 | 
			
		||||
    set_gpio_bit(reg, pin, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gpio_pin_value_t gpiohs_get_pin(uint8_t pin)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(pin < GPIOHS_MAX_PINNO);
 | 
			
		||||
    return get_gpio_bit(gpiohs->input_val.u32, pin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void gpiohs_set_pin(uint8_t pin, gpio_pin_value_t value)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(pin < GPIOHS_MAX_PINNO);
 | 
			
		||||
    set_gpio_bit(gpiohs->output_val.u32, pin, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void gpiohs_set_pin_edge(uint8_t pin, GpioPinEdgeT edge)
 | 
			
		||||
{
 | 
			
		||||
    set_gpio_bit(gpiohs->rise_ie.u32, pin, 0);
 | 
			
		||||
    set_gpio_bit(gpiohs->rise_ip.u32, pin, 1);
 | 
			
		||||
 | 
			
		||||
    set_gpio_bit(gpiohs->fall_ie.u32, pin, 0);
 | 
			
		||||
    set_gpio_bit(gpiohs->fall_ip.u32, pin, 1);
 | 
			
		||||
 | 
			
		||||
    set_gpio_bit(gpiohs->low_ie.u32, pin, 0);
 | 
			
		||||
    set_gpio_bit(gpiohs->low_ip.u32, pin, 1);
 | 
			
		||||
 | 
			
		||||
    set_gpio_bit(gpiohs->high_ie.u32, pin, 0);
 | 
			
		||||
    set_gpio_bit(gpiohs->high_ip.u32, pin, 1);
 | 
			
		||||
 | 
			
		||||
    if(edge & GPIO_PE_FALLING)
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->fall_ie.u32, pin, 1);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->fall_ie.u32, pin, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(edge & GPIO_PE_RISING)
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->rise_ie.u32, pin, 1);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->rise_ie.u32, pin, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(edge & GPIO_PE_LOW)
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->low_ie.u32, pin, 1);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->low_ie.u32, pin, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(edge & GPIO_PE_HIGH)
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->high_ie.u32, pin, 1);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->high_ie.u32, pin, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pin_instance[pin].edge = edge;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int gpiohs_pin_onchange_isr(void *userdata)
 | 
			
		||||
{
 | 
			
		||||
    gpiohs_pin_instance_t *ctx = (gpiohs_pin_instance_t *)userdata;
 | 
			
		||||
    size_t pin = ctx->pin;
 | 
			
		||||
 | 
			
		||||
    if(ctx->edge & GPIO_PE_FALLING)
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->fall_ie.u32, pin, 0);
 | 
			
		||||
        set_gpio_bit(gpiohs->fall_ip.u32, pin, 1);
 | 
			
		||||
        set_gpio_bit(gpiohs->fall_ie.u32, pin, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(ctx->edge & GPIO_PE_RISING)
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->rise_ie.u32, pin, 0);
 | 
			
		||||
        set_gpio_bit(gpiohs->rise_ip.u32, pin, 1);
 | 
			
		||||
        set_gpio_bit(gpiohs->rise_ie.u32, pin, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(ctx->edge & GPIO_PE_LOW)
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->low_ie.u32, pin, 0);
 | 
			
		||||
        set_gpio_bit(gpiohs->low_ip.u32, pin, 1);
 | 
			
		||||
        set_gpio_bit(gpiohs->low_ie.u32, pin, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(ctx->edge & GPIO_PE_HIGH)
 | 
			
		||||
    {
 | 
			
		||||
        set_gpio_bit(gpiohs->high_ie.u32, pin, 0);
 | 
			
		||||
        set_gpio_bit(gpiohs->high_ip.u32, pin, 1);
 | 
			
		||||
        set_gpio_bit(gpiohs->high_ie.u32, pin, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ctx->callback)
 | 
			
		||||
        ctx->callback();
 | 
			
		||||
    if(ctx->gpiohs_callback)
 | 
			
		||||
        ctx->gpiohs_callback(ctx->context);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void gpiohs_set_irq(uint8_t pin, uint32_t priority, void (*func)())
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    pin_instance[pin].pin = pin;
 | 
			
		||||
    pin_instance[pin].callback = func;
 | 
			
		||||
 | 
			
		||||
    plic_set_priority(IRQN_GPIOHS0_INTERRUPT + pin, priority);
 | 
			
		||||
    plic_irq_register(IRQN_GPIOHS0_INTERRUPT + pin, gpiohs_pin_onchange_isr, &(pin_instance[pin]));
 | 
			
		||||
    plic_irq_enable(IRQN_GPIOHS0_INTERRUPT + pin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void gpiohs_irq_register(uint8_t pin, uint32_t priority, plic_irq_callback_t callback, void *ctx)
 | 
			
		||||
{
 | 
			
		||||
    pin_instance[pin].pin = pin;
 | 
			
		||||
    pin_instance[pin].gpiohs_callback = callback;
 | 
			
		||||
    pin_instance[pin].context = ctx;
 | 
			
		||||
 | 
			
		||||
    plic_set_priority(IRQN_GPIOHS0_INTERRUPT + pin, priority);
 | 
			
		||||
    plic_irq_register(IRQN_GPIOHS0_INTERRUPT + pin, gpiohs_pin_onchange_isr, &(pin_instance[pin]));
 | 
			
		||||
    plic_irq_enable(IRQN_GPIOHS0_INTERRUPT + pin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void gpiohs_irq_unregister(uint8_t pin)
 | 
			
		||||
{
 | 
			
		||||
    pin_instance[pin] = (gpiohs_pin_instance_t){
 | 
			
		||||
        .callback = NULL,
 | 
			
		||||
        .gpiohs_callback = NULL,
 | 
			
		||||
        .context = NULL,
 | 
			
		||||
    };
 | 
			
		||||
    set_gpio_bit(gpiohs->rise_ie.u32, pin, 0);
 | 
			
		||||
    set_gpio_bit(gpiohs->fall_ie.u32, pin, 0);
 | 
			
		||||
    set_gpio_bit(gpiohs->low_ie.u32, pin, 0);
 | 
			
		||||
    set_gpio_bit(gpiohs->high_ie.u32, pin, 0);
 | 
			
		||||
    plic_irq_unregister(IRQN_GPIOHS0_INTERRUPT + pin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void gpiohs_irq_disable(size_t pin)
 | 
			
		||||
{
 | 
			
		||||
    plic_irq_disable(IRQN_GPIOHS0_INTERRUPT + pin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 utils.c
 | 
			
		||||
* @brief add from Canaan K210 SDK
 | 
			
		||||
*               https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-07-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "encoding.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
void set_bit(volatile uint32_t *bits, uint32_t mask, uint32_t value)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t org = (*bits) & ~mask;
 | 
			
		||||
    *bits = org | (value & mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value)
 | 
			
		||||
{
 | 
			
		||||
    set_bit(bits, mask << offset, value << offset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_gpio_bit(volatile uint32_t *bits, size_t offset, uint32_t value)
 | 
			
		||||
{
 | 
			
		||||
    set_bit_offset(bits, 1, offset, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t get_bit(volatile uint32_t *bits, uint32_t mask, size_t offset)
 | 
			
		||||
{
 | 
			
		||||
    return ((*bits) & (mask << offset)) >> offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t get_gpio_bit(volatile uint32_t *bits, size_t offset)
 | 
			
		||||
{
 | 
			
		||||
    return get_bit(bits, 1, offset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
if BSP_USING_I2C
 | 
			
		||||
    config BSP_I2C_SDA
 | 
			
		||||
        int "SDA pin number for I2C"
 | 
			
		||||
        default 15
 | 
			
		||||
    config BSP_I2C_SCL
 | 
			
		||||
        int "SCLK pin number for I2C"
 | 
			
		||||
        default 17
 | 
			
		||||
    config I2C_BUS_NAME_1
 | 
			
		||||
        string "i2c bus 1 name"
 | 
			
		||||
        default "i2c1"
 | 
			
		||||
    config I2C_DRV_NAME_1
 | 
			
		||||
        string "i2c bus 1 driver name"
 | 
			
		||||
        default "i2c1_drv"
 | 
			
		||||
    config I2C_1_DEVICE_NAME_0
 | 
			
		||||
            string "i2c bus 1 device 0 name"
 | 
			
		||||
            default "i2c1_dev0"     
 | 
			
		||||
endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
SRC_FILES := connect_i2c.c hardware_i2c.c
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,633 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2020 RT-Thread Development Team
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Change Logs:
 | 
			
		||||
 * Date           Author        Notes
 | 
			
		||||
 * 2012-04-25     weety         first version
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @file connect_i2c.c
 | 
			
		||||
* @brief support kd233-board i2c function and register to bus framework
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
File name: connect_i2c.c
 | 
			
		||||
Description: support edu-riscv64-board i2c configure and i2c bus register function
 | 
			
		||||
Others: take RT-Thread v4.0.2/components/drivers/i2c/i2c-bit-ops.c for references
 | 
			
		||||
                https://github.com/RT-Thread/rt-thread/tree/v4.0.2
 | 
			
		||||
History: 
 | 
			
		||||
1. Date: 2022-10-17
 | 
			
		||||
Author: AIIT XUOS Lab
 | 
			
		||||
Modification: 
 | 
			
		||||
1. support edu-riscv64-board i2c bit configure, write and read
 | 
			
		||||
2. support edu-riscv64-board i2c bus device and driver register
 | 
			
		||||
*************************************************/
 | 
			
		||||
 | 
			
		||||
#include <board.h>
 | 
			
		||||
 #include "gpio_common.h"
 | 
			
		||||
 #include"fpioa.h"
 | 
			
		||||
#include "connect_i2c.h"
 | 
			
		||||
#include <sleep.h>
 | 
			
		||||
#include "sysctl.h"
 | 
			
		||||
#include "gpio.h"
 | 
			
		||||
 | 
			
		||||
#ifndef BSP_USING_I2C1
 | 
			
		||||
#define BSP_USING_I2C1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define I2C_SDA_FUNC_GPIO 3
 | 
			
		||||
#define I2C_SCL_FUNC_GPIO 4
 | 
			
		||||
 | 
			
		||||
static I2cBusParam i2c_bus_param =
 | 
			
		||||
{
 | 
			
		||||
    I2C_SDA_FUNC_GPIO,
 | 
			
		||||
    I2C_SCL_FUNC_GPIO,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define SET_SDA(done, val)   done->SetSdaState(done->data, val)
 | 
			
		||||
#define SET_SCL(done, val)   done->SetSclState(done->data, val)
 | 
			
		||||
#define GET_SDA(done)          done->GetSdaState(done->data)
 | 
			
		||||
#define GET_SCL(done)          done->GetSclState(done->data)
 | 
			
		||||
#define SdaLow(done)            SET_SDA(done, 0)
 | 
			
		||||
#define SdaHigh(done)           SET_SDA(done, 1)
 | 
			
		||||
#define SclLow(done)              SET_SCL(done, 0)
 | 
			
		||||
 | 
			
		||||
void I2cGpioInit(const I2cBusParam *bus_param)
 | 
			
		||||
{
 | 
			
		||||
    gpio_init ();
 | 
			
		||||
    FpioaSetFunction(BSP_I2C_SDA , FUNC_GPIO3 );//RISC-V FPIOA CFG
 | 
			
		||||
    FpioaSetFunction(BSP_I2C_SCL , FUNC_GPIO4 );//RISC-V FPIOA CFG
 | 
			
		||||
    gpio_set_drive_mode(bus_param->i2c_sda_pin , GPIO_DM_OUTPUT );
 | 
			
		||||
    gpio_set_drive_mode(bus_param->i2c_scl_pin, GPIO_DM_OUTPUT );
 | 
			
		||||
    gpio_set_pin(bus_param->i2c_sda_pin , GPIO_PV_HIGH );
 | 
			
		||||
    gpio_set_pin(bus_param->i2c_scl_pin , GPIO_PV_HIGH );    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void SetSdaState(void *data, uint8 sda_state)
 | 
			
		||||
{
 | 
			
		||||
    I2cBusParam *bus_param = (I2cBusParam *)data;
 | 
			
		||||
    if (sda_state) {
 | 
			
		||||
       gpio_set_drive_mode(bus_param->i2c_sda_pin, GPIO_DM_OUTPUT );
 | 
			
		||||
       gpio_set_pin(bus_param->i2c_sda_pin , GPIO_PV_HIGH );  
 | 
			
		||||
    } else {
 | 
			
		||||
       gpio_set_drive_mode(bus_param->i2c_sda_pin, GPIO_DM_OUTPUT );
 | 
			
		||||
       gpio_set_pin(bus_param->i2c_sda_pin , GPIO_PV_LOW );  
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void SetSclState(void *data, uint8 scl_state)
 | 
			
		||||
{
 | 
			
		||||
    I2cBusParam *bus_param = (I2cBusParam *)data;
 | 
			
		||||
    if (scl_state) {
 | 
			
		||||
        gpio_set_drive_mode(bus_param->i2c_scl_pin, GPIO_DM_OUTPUT );
 | 
			
		||||
        gpio_set_pin(bus_param->i2c_scl_pin , GPIO_PV_HIGH ); 
 | 
			
		||||
    } else {
 | 
			
		||||
        gpio_set_drive_mode(bus_param->i2c_scl_pin, GPIO_DM_OUTPUT );
 | 
			
		||||
        gpio_set_pin(bus_param->i2c_scl_pin , GPIO_PV_LOW ); 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint8 GetSdaState(void *data)
 | 
			
		||||
{
 | 
			
		||||
    I2cBusParam *bus_param = (I2cBusParam *)data;
 | 
			
		||||
    gpio_set_drive_mode (bus_param->i2c_sda_pin, GPIO_DM_INPUT_PULL_UP );  
 | 
			
		||||
    return gpio_get_pin(bus_param->i2c_sda_pin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint8 GetSclState(void *data)
 | 
			
		||||
{
 | 
			
		||||
    I2cBusParam *bus_param = (I2cBusParam *)data;
 | 
			
		||||
    gpio_set_drive_mode (bus_param->i2c_scl_pin, GPIO_DM_INPUT_PULL_UP );
 | 
			
		||||
    return gpio_get_pin(bus_param->i2c_scl_pin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct I2cHalDrvDone I2cDrvDone =
 | 
			
		||||
{
 | 
			
		||||
    .data = (&i2c_bus_param),
 | 
			
		||||
    .SetSdaState = SetSdaState,
 | 
			
		||||
    .SetSclState = SetSclState,
 | 
			
		||||
    .GetSdaState = GetSdaState,
 | 
			
		||||
    .GetSclState = GetSclState,
 | 
			
		||||
    .udelay = usleep,
 | 
			
		||||
    .delay_us = 1,
 | 
			
		||||
    .timeout = 100
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static x_err_t I2cBusReset(const I2cBusParam *bus_param)
 | 
			
		||||
{
 | 
			
		||||
    int32 i = 0;
 | 
			
		||||
    gpio_set_drive_mode(bus_param->i2c_sda_pin, GPIO_DM_INPUT_PULL_UP );   
 | 
			
		||||
    if (GPIO_LOW == gpio_get_pin(bus_param->i2c_sda_pin)) {
 | 
			
		||||
        while (i++ < 9) {
 | 
			
		||||
            gpio_set_drive_mode(bus_param->i2c_scl_pin, GPIO_DM_OUTPUT );
 | 
			
		||||
            gpio_set_pin(bus_param->i2c_scl_pin , GPIO_PV_HIGH ); 
 | 
			
		||||
            usleep(100);
 | 
			
		||||
            gpio_set_pin(bus_param->i2c_scl_pin , GPIO_PV_LOW ); 
 | 
			
		||||
            usleep(100);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    gpio_set_drive_mode(bus_param->i2c_sda_pin, GPIO_DM_INPUT_PULL_UP );   
 | 
			
		||||
    if (GPIO_LOW == gpio_get_pin(bus_param->i2c_sda_pin)) {
 | 
			
		||||
        return -ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline void I2cDelay(struct I2cHalDrvDone *done)
 | 
			
		||||
{
 | 
			
		||||
    done->udelay((done->delay_us + 1) >> 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline void I2cDelay2(struct I2cHalDrvDone *done)
 | 
			
		||||
{
 | 
			
		||||
    done->udelay(done->delay_us);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static x_err_t SclHigh(struct I2cHalDrvDone *done)
 | 
			
		||||
{
 | 
			
		||||
    x_ticks_t start;
 | 
			
		||||
 | 
			
		||||
    SET_SCL(done, 1);
 | 
			
		||||
 | 
			
		||||
    if (!done->GetSclState)
 | 
			
		||||
        goto done;
 | 
			
		||||
 | 
			
		||||
    start = CurrentTicksGain();
 | 
			
		||||
    while (!GET_SCL(done)) {
 | 
			
		||||
        if ((CurrentTicksGain() - start) > done->timeout)
 | 
			
		||||
            return -ETIMEOUT;
 | 
			
		||||
        DelayKTask((done->timeout + 1) >> 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
done:
 | 
			
		||||
    I2cDelay(done);
 | 
			
		||||
 | 
			
		||||
    return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void I2cStart(struct I2cHalDrvDone *done)
 | 
			
		||||
{
 | 
			
		||||
    SdaLow(done);
 | 
			
		||||
    I2cDelay(done);
 | 
			
		||||
    SclLow(done);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void I2cRestart(struct I2cHalDrvDone *done)
 | 
			
		||||
{
 | 
			
		||||
    SdaHigh(done);
 | 
			
		||||
    SclHigh(done);
 | 
			
		||||
    I2cDelay(done);
 | 
			
		||||
    SdaLow(done);
 | 
			
		||||
    I2cDelay(done);
 | 
			
		||||
    SclLow(done);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void I2cStop(struct I2cHalDrvDone *done)
 | 
			
		||||
{
 | 
			
		||||
    SdaLow(done);
 | 
			
		||||
    I2cDelay(done);
 | 
			
		||||
    SclHigh(done);
 | 
			
		||||
    I2cDelay(done);
 | 
			
		||||
    SdaHigh(done);
 | 
			
		||||
    I2cDelay2(done);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline x_bool I2cWaitack(struct I2cHalDrvDone *done)
 | 
			
		||||
{
 | 
			
		||||
    x_bool ack;
 | 
			
		||||
 | 
			
		||||
    SdaHigh(done);
 | 
			
		||||
     GET_SDA(done);    
 | 
			
		||||
    I2cDelay(done);
 | 
			
		||||
 | 
			
		||||
    if (SclHigh(done) < 0) {
 | 
			
		||||
        KPrintf("wait ack timeout");
 | 
			
		||||
        return -ETIMEOUT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ack = !GET_SDA(done);
 | 
			
		||||
 | 
			
		||||
    SclLow(done);
 | 
			
		||||
 | 
			
		||||
    return ack;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32 I2cWriteb(struct I2cBus *bus, uint8 data)
 | 
			
		||||
{
 | 
			
		||||
    int32 i;
 | 
			
		||||
    uint8 bit;
 | 
			
		||||
 | 
			
		||||
    struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data;
 | 
			
		||||
 | 
			
		||||
    for (i = 7; i >= 0; i--) {
 | 
			
		||||
        SclLow(done);
 | 
			
		||||
        bit = (data >> i) & 1;
 | 
			
		||||
        SET_SDA(done, bit);
 | 
			
		||||
        I2cDelay(done);
 | 
			
		||||
        if (SclHigh(done) < 0) {
 | 
			
		||||
            KPrintf("I2cWriteb: 0x%02x, "
 | 
			
		||||
                    "wait scl pin high timeout at bit %d",
 | 
			
		||||
                    data, i);
 | 
			
		||||
 | 
			
		||||
            return -ETIMEOUT;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    SclLow(done);
 | 
			
		||||
    I2cDelay(done);
 | 
			
		||||
 | 
			
		||||
    return I2cWaitack(done);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32 I2cReadb(struct I2cBus *bus)
 | 
			
		||||
{
 | 
			
		||||
    uint8 i;
 | 
			
		||||
    uint8 data = 0;
 | 
			
		||||
    struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data;
 | 
			
		||||
 | 
			
		||||
    SdaHigh(done);
 | 
			
		||||
    GET_SDA(done);
 | 
			
		||||
    I2cDelay(done);
 | 
			
		||||
    for (i = 0; i < 8; i++) {
 | 
			
		||||
        data <<= 1;
 | 
			
		||||
 | 
			
		||||
        if (SclHigh(done) < 0) {
 | 
			
		||||
            KPrintf("I2cReadb: wait scl pin high "
 | 
			
		||||
                    "timeout at bit %d", 7 - i);
 | 
			
		||||
 | 
			
		||||
            return -ETIMEOUT;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (GET_SDA(done))
 | 
			
		||||
            data |= 1;
 | 
			
		||||
        SclLow(done);
 | 
			
		||||
        I2cDelay2(done);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static x_size_t I2cSendBytes(struct I2cBus *bus, struct I2cDataStandard *msg)
 | 
			
		||||
{
 | 
			
		||||
    int32 ret;
 | 
			
		||||
    x_size_t bytes = 0;
 | 
			
		||||
    const uint8 *ptr = msg->buf;
 | 
			
		||||
    int32 count = msg->len;
 | 
			
		||||
    uint16 ignore_nack = msg->flags & I2C_IGNORE_NACK;
 | 
			
		||||
 | 
			
		||||
    while (count > 0) {
 | 
			
		||||
        ret = I2cWriteb(bus, *ptr);
 | 
			
		||||
 | 
			
		||||
        if ((ret > 0) || (ignore_nack && (ret == 0))) {
 | 
			
		||||
            count --;
 | 
			
		||||
            ptr ++;
 | 
			
		||||
            bytes ++;
 | 
			
		||||
        } else if (ret == 0) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        } else {
 | 
			
		||||
            KPrintf("send bytes: error %d", ret);
 | 
			
		||||
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return bytes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static x_err_t I2cSendAckOrNack(struct I2cBus *bus, int ack)
 | 
			
		||||
{
 | 
			
		||||
    struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data;
 | 
			
		||||
 | 
			
		||||
    if (ack)
 | 
			
		||||
        SET_SDA(done, 0);
 | 
			
		||||
    I2cDelay(done);
 | 
			
		||||
    if (SclHigh(done) < 0) {
 | 
			
		||||
        KPrintf("ACK or NACK timeout.");
 | 
			
		||||
 | 
			
		||||
        return -ETIMEOUT;
 | 
			
		||||
    }
 | 
			
		||||
    SclLow(done);
 | 
			
		||||
 | 
			
		||||
    return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static x_size_t I2cRecvBytes(struct I2cBus *bus, struct I2cDataStandard *msg)
 | 
			
		||||
{
 | 
			
		||||
    int32 val;
 | 
			
		||||
    int32 bytes = 0;
 | 
			
		||||
    uint8 *ptr = msg->buf;
 | 
			
		||||
    int32 count = msg->len;
 | 
			
		||||
    const uint32 flags = msg->flags;
 | 
			
		||||
 | 
			
		||||
    while (count > 0) {
 | 
			
		||||
        val = I2cReadb(bus);
 | 
			
		||||
        if (val >= 0) {
 | 
			
		||||
            *ptr = val;
 | 
			
		||||
            bytes ++;
 | 
			
		||||
        } else {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ptr ++;
 | 
			
		||||
        count --;
 | 
			
		||||
 | 
			
		||||
        if (!(flags & I2C_NO_READ_ACK)) {
 | 
			
		||||
            val = I2cSendAckOrNack(bus, count);
 | 
			
		||||
            if (val < 0)
 | 
			
		||||
                return val;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return bytes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32 I2cSendAddress(struct I2cBus *bus, uint8 addr, int32 retries)
 | 
			
		||||
{
 | 
			
		||||
    struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data;
 | 
			
		||||
    int32 i;
 | 
			
		||||
    x_err_t ret = 0;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i <= retries; i++) {
 | 
			
		||||
        ret = I2cWriteb(bus, addr);
 | 
			
		||||
        if (ret == 1 || i == retries)
 | 
			
		||||
            break;
 | 
			
		||||
        I2cStop(done);
 | 
			
		||||
        I2cDelay2(done);
 | 
			
		||||
        I2cStart(done);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static x_err_t I2cBitSendAddress(struct I2cBus *bus, struct I2cDataStandard *msg)
 | 
			
		||||
{
 | 
			
		||||
    uint16 flags = msg->flags;
 | 
			
		||||
    uint16 ignore_nack = msg->flags & I2C_IGNORE_NACK;
 | 
			
		||||
    struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data;
 | 
			
		||||
 | 
			
		||||
    uint8 addr1, addr2;
 | 
			
		||||
    int32 retries;
 | 
			
		||||
    x_err_t ret;
 | 
			
		||||
 | 
			
		||||
    retries = ignore_nack ? 0 : msg->retries;
 | 
			
		||||
 | 
			
		||||
    if (flags & I2C_ADDR_10BIT) {
 | 
			
		||||
        addr1 = 0xf0 | ((msg->addr >> 7) & 0x06);
 | 
			
		||||
        addr2 = msg->addr & 0xff;
 | 
			
		||||
 | 
			
		||||
        ret = I2cSendAddress(bus, addr1, retries);
 | 
			
		||||
        if ((ret != 1) && !ignore_nack) {
 | 
			
		||||
 | 
			
		||||
            return -EPIO;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ret = I2cWriteb(bus, addr2);
 | 
			
		||||
        if ((ret != 1) && !ignore_nack) {
 | 
			
		||||
 | 
			
		||||
            return -EPIO;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (flags & I2C_RD) {
 | 
			
		||||
            I2cRestart(done);
 | 
			
		||||
            addr1 |= 0x01;
 | 
			
		||||
            ret = I2cSendAddress(bus, addr1, retries);
 | 
			
		||||
            if ((ret != 1) && !ignore_nack) {
 | 
			
		||||
 | 
			
		||||
                return -EPIO;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        addr1 = msg->addr << 1;
 | 
			
		||||
        if (flags & I2C_RD)
 | 
			
		||||
            addr1 |= 1;
 | 
			
		||||
        ret = I2cSendAddress(bus, addr1, retries);
 | 
			
		||||
        if ((ret != 1) && !ignore_nack)
 | 
			
		||||
            return -EPIO;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 I2cWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
 | 
			
		||||
{
 | 
			
		||||
    struct I2cBus *bus = (struct I2cBus *)i2c_dev->haldev.owner_bus;
 | 
			
		||||
    bus->private_data = i2c_dev->haldev.owner_bus->private_data;
 | 
			
		||||
    struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data;
 | 
			
		||||
    int32 ret;
 | 
			
		||||
    int32 i = 0;
 | 
			
		||||
    uint16 ignore_nack;
 | 
			
		||||
 | 
			
		||||
    I2cStart(done);
 | 
			
		||||
    while (NONE != msg) {
 | 
			
		||||
        ignore_nack = msg->flags & I2C_IGNORE_NACK;
 | 
			
		||||
        if (!(msg->flags & I2C_NO_START)) {
 | 
			
		||||
            if (i) {
 | 
			
		||||
                I2cRestart(done);
 | 
			
		||||
            }
 | 
			
		||||
            ret = I2cBitSendAddress(bus, msg);
 | 
			
		||||
            if ((ret != EOK) && !ignore_nack) {
 | 
			
		||||
                goto out;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (msg->flags == I2C_WR) {
 | 
			
		||||
            ret = I2cSendBytes(bus, msg);
 | 
			
		||||
            if (ret >= 1)
 | 
			
		||||
                //KPrintf("write %d byte%s", ret, ret == 1 ? "" : "s");
 | 
			
		||||
            if (ret < msg->len) {
 | 
			
		||||
                if (ret >= 0)
 | 
			
		||||
                    ret = -ERROR;
 | 
			
		||||
                goto out;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        msg = msg->next;
 | 
			
		||||
        i++;
 | 
			
		||||
    }
 | 
			
		||||
    ret = i;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    I2cStop(done);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 I2cReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
 | 
			
		||||
{
 | 
			
		||||
    struct I2cBus *bus = (struct I2cBus *)i2c_dev->haldev.owner_bus;
 | 
			
		||||
    bus->private_data = i2c_dev->haldev.owner_bus->private_data;
 | 
			
		||||
    struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data;
 | 
			
		||||
    int32 ret;
 | 
			
		||||
    int32 i = 0;
 | 
			
		||||
    uint16 ignore_nack;
 | 
			
		||||
 | 
			
		||||
    I2cStart(done);
 | 
			
		||||
    while (NONE != msg) {
 | 
			
		||||
        ignore_nack = msg->flags & I2C_IGNORE_NACK;
 | 
			
		||||
        if (!(msg->flags & I2C_NO_START)) {
 | 
			
		||||
            if (i) {
 | 
			
		||||
                I2cRestart(done);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ret = I2cBitSendAddress(bus, msg);
 | 
			
		||||
            if ((ret != EOK) && !ignore_nack) {
 | 
			
		||||
                goto out;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (msg->flags & I2C_RD) {
 | 
			
		||||
            ret = I2cRecvBytes(bus, msg);
 | 
			
		||||
            if (ret >= 1)
 | 
			
		||||
                //KPrintf("read %d byte%s", ret, ret == 1 ? "" : "s");
 | 
			
		||||
            if (ret < msg->len) {
 | 
			
		||||
                if (ret >= 0)
 | 
			
		||||
                    ret = -EPIO;
 | 
			
		||||
                goto out;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        msg = msg->next;
 | 
			
		||||
        i++;
 | 
			
		||||
    }
 | 
			
		||||
    ret = i;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    I2cStop(done);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 I2cInit(struct I2cDriver *i2c_drv, struct BusConfigureInfo *configure_info)
 | 
			
		||||
{
 | 
			
		||||
    NULL_PARAM_CHECK(i2c_drv);
 | 
			
		||||
 | 
			
		||||
    struct I2cHardwareDevice *i2c_dev = (struct I2cHardwareDevice *)i2c_drv->driver.owner_bus->owner_haldev;
 | 
			
		||||
 | 
			
		||||
    if (configure_info->private_data) {
 | 
			
		||||
        i2c_dev->i2c_dev_addr = *((uint16 *)configure_info->private_data);
 | 
			
		||||
        return EOK;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    KPrintf("I2cInit need set i2c dev addr\n");
 | 
			
		||||
    return ERROR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32 I2cDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
 | 
			
		||||
{
 | 
			
		||||
    NULL_PARAM_CHECK(drv);
 | 
			
		||||
    NULL_PARAM_CHECK(configure_info);
 | 
			
		||||
 | 
			
		||||
    x_err_t ret = EOK;
 | 
			
		||||
    struct I2cDriver *i2c_drv = (struct I2cDriver *)drv;
 | 
			
		||||
 | 
			
		||||
    switch (configure_info->configure_cmd)
 | 
			
		||||
    {
 | 
			
		||||
        case OPE_INT:
 | 
			
		||||
            ret = I2cInit(i2c_drv, configure_info);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*manage the i2c device operations*/
 | 
			
		||||
static const struct I2cDevDone i2c_dev_done =
 | 
			
		||||
{
 | 
			
		||||
    .dev_open = NONE,
 | 
			
		||||
    .dev_close = NONE,
 | 
			
		||||
    .dev_write = I2cWriteData,
 | 
			
		||||
    .dev_read = I2cReadData,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*Init i2c bus*/
 | 
			
		||||
static int BoardI2cBusInit(struct I2cBus *i2c_bus, struct I2cDriver *i2c_driver)
 | 
			
		||||
{
 | 
			
		||||
    x_err_t ret = EOK;
 | 
			
		||||
 | 
			
		||||
    /*Init the i2c bus */
 | 
			
		||||
    i2c_bus->private_data = (void *)&I2cDrvDone;
 | 
			
		||||
    ret = I2cBusInit(i2c_bus, I2C_BUS_NAME_1);
 | 
			
		||||
    if (EOK != ret) {
 | 
			
		||||
        KPrintf("board_i2c_init I2cBusInit error %d\n", ret);
 | 
			
		||||
        return ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*Init the i2c driver*/
 | 
			
		||||
    i2c_driver->private_data = (void *)&I2cDrvDone;
 | 
			
		||||
    ret = I2cDriverInit(i2c_driver, I2C_DRV_NAME_1);
 | 
			
		||||
    if (EOK != ret) {
 | 
			
		||||
        KPrintf("board_i2c_init I2cDriverInit error %d\n", ret);
 | 
			
		||||
        return ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*Attach the i2c driver to the i2c bus*/
 | 
			
		||||
    ret = I2cDriverAttachToBus(I2C_DRV_NAME_1, I2C_BUS_NAME_1);
 | 
			
		||||
    if (EOK != ret) {
 | 
			
		||||
        KPrintf("board_i2c_init I2cDriverAttachToBus error %d\n", ret);
 | 
			
		||||
        return ERROR;
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*Attach the i2c device to the i2c bus*/
 | 
			
		||||
static int BoardI2cDevBend(void)
 | 
			
		||||
{
 | 
			
		||||
    x_err_t ret = EOK;
 | 
			
		||||
    static struct I2cHardwareDevice i2c_device0;
 | 
			
		||||
    memset(&i2c_device0, 0, sizeof(struct I2cHardwareDevice));
 | 
			
		||||
 | 
			
		||||
    i2c_device0.i2c_dev_done = &i2c_dev_done;
 | 
			
		||||
 | 
			
		||||
    ret = I2cDeviceRegister(&i2c_device0, NONE, I2C_1_DEVICE_NAME_0);
 | 
			
		||||
    if (EOK != ret) {
 | 
			
		||||
        KPrintf("board_i2c_init I2cDeviceInit device %s error %d\n", I2C_1_DEVICE_NAME_0, ret);
 | 
			
		||||
        return ERROR;
 | 
			
		||||
    }  
 | 
			
		||||
 | 
			
		||||
    ret = I2cDeviceAttachToBus(I2C_1_DEVICE_NAME_0, I2C_BUS_NAME_1);
 | 
			
		||||
    if (EOK != ret) {
 | 
			
		||||
        KPrintf("board_i2c_init I2cDeviceAttachToBus device %s error %d\n", I2C_1_DEVICE_NAME_0, ret);
 | 
			
		||||
        return ERROR;
 | 
			
		||||
    }  
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*KD233 BOARD I2C INIT*/
 | 
			
		||||
int HwI2cInit(void)
 | 
			
		||||
{
 | 
			
		||||
    x_err_t ret = EOK;
 | 
			
		||||
    static struct I2cBus i2c_bus;
 | 
			
		||||
    memset(&i2c_bus, 0, sizeof(struct I2cBus));
 | 
			
		||||
 | 
			
		||||
    static struct I2cDriver i2c_driver;
 | 
			
		||||
    memset(&i2c_driver, 0, sizeof(struct I2cDriver));
 | 
			
		||||
 | 
			
		||||
#ifdef  BSP_USING_I2C1
 | 
			
		||||
    I2cGpioInit(&i2c_bus_param);
 | 
			
		||||
 | 
			
		||||
    i2c_driver.configure = I2cDrvConfigure;
 | 
			
		||||
 | 
			
		||||
    ret = BoardI2cBusInit(&i2c_bus, &i2c_driver);
 | 
			
		||||
    if (EOK != ret) {
 | 
			
		||||
        KPrintf("board_i2c_Init error ret %u\n", ret);
 | 
			
		||||
        return ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ret = BoardI2cDevBend();
 | 
			
		||||
    if (EOK != ret) {
 | 
			
		||||
        KPrintf("board_i2c_Init error ret %u\n", ret);
 | 
			
		||||
        return ERROR;
 | 
			
		||||
    }   
 | 
			
		||||
 | 
			
		||||
    I2cBusReset(&i2c_bus_param);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,371 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 hardware_i2c.c
 | 
			
		||||
* @brief add from Canaan k210 SDK
 | 
			
		||||
*                https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "hardware_i2c.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
#include "fpioa.h"
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "stdlib.h"
 | 
			
		||||
#include "string.h"
 | 
			
		||||
#include "sysctl.h"
 | 
			
		||||
#include "bsp.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _i2c_slave_instance
 | 
			
		||||
{
 | 
			
		||||
    uint32_t i2c_num;
 | 
			
		||||
    const i2c_slave_handler_t *slave_handler;
 | 
			
		||||
} i2c_slave_instance_t;
 | 
			
		||||
 | 
			
		||||
static i2c_slave_instance_t slave_instance[I2C_MAX_NUM];
 | 
			
		||||
 | 
			
		||||
typedef struct _i2c_instance
 | 
			
		||||
{
 | 
			
		||||
    i2c_device_number_t i2c_num;
 | 
			
		||||
    i2c_transfer_mode_t TransferMode;
 | 
			
		||||
    dmac_channel_number_t dmac_channel;
 | 
			
		||||
    plic_instance_t i2c_int_instance;
 | 
			
		||||
    spinlock_t lock;
 | 
			
		||||
} i2c_instance_t;
 | 
			
		||||
 | 
			
		||||
static i2c_instance_t g_i2c_instance[3];
 | 
			
		||||
 | 
			
		||||
volatile i2c_t* const i2c[3] =
 | 
			
		||||
{
 | 
			
		||||
    (volatile i2c_t*)I2C0_BASE_ADDR,
 | 
			
		||||
    (volatile i2c_t*)I2C1_BASE_ADDR,
 | 
			
		||||
    (volatile i2c_t*)I2C2_BASE_ADDR
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void i2c_clk_init(i2c_device_number_t i2c_num)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(i2c_num < I2C_MAX_NUM);
 | 
			
		||||
    sysctl_clock_enable(SYSCTL_CLOCK_I2C0 + i2c_num);
 | 
			
		||||
    sysctl_clock_set_threshold(SYSCTL_THRESHOLD_I2C0 + i2c_num, 3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_init(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t address_width,
 | 
			
		||||
              uint32_t i2c_clk)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(i2c_num < I2C_MAX_NUM);
 | 
			
		||||
    configASSERT(address_width == 7 || address_width == 10);
 | 
			
		||||
 | 
			
		||||
    volatile i2c_t *i2c_adapter = i2c[i2c_num];
 | 
			
		||||
 | 
			
		||||
    i2c_clk_init(i2c_num);
 | 
			
		||||
 | 
			
		||||
    uint32_t v_i2c_freq = SysctlClockGetFreq(SYSCTL_CLOCK_I2C0 + i2c_num);
 | 
			
		||||
    uint16_t v_period_clk_cnt = v_i2c_freq / i2c_clk / 2;
 | 
			
		||||
 | 
			
		||||
    if(v_period_clk_cnt == 0)
 | 
			
		||||
        v_period_clk_cnt = 1;
 | 
			
		||||
 | 
			
		||||
    i2c_adapter->enable = 0;
 | 
			
		||||
    i2c_adapter->con = I2C_CON_MASTER_MODE | I2C_CON_SLAVE_DISABLE | I2C_CON_RESTART_EN |
 | 
			
		||||
                       (address_width == 10 ? I2C_CON_10BITADDR_SLAVE : 0) | I2C_CON_SPEED(1);
 | 
			
		||||
    i2c_adapter->ss_scl_hcnt = I2C_SS_SCL_HCNT_COUNT(v_period_clk_cnt);
 | 
			
		||||
    i2c_adapter->ss_scl_lcnt = I2C_SS_SCL_LCNT_COUNT(v_period_clk_cnt);
 | 
			
		||||
 | 
			
		||||
    i2c_adapter->tar = I2C_TAR_ADDRESS(slave_address);
 | 
			
		||||
    i2c_adapter->intr_mask = 0;
 | 
			
		||||
    i2c_adapter->dma_cr = 0x3;
 | 
			
		||||
    i2c_adapter->dma_rdlr = 0;
 | 
			
		||||
    i2c_adapter->dma_tdlr = 4;
 | 
			
		||||
    i2c_adapter->enable = I2C_ENABLE_ENABLE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int i2c_slave_irq(void *userdata)
 | 
			
		||||
{
 | 
			
		||||
    i2c_slave_instance_t *instance = (i2c_slave_instance_t *)userdata;
 | 
			
		||||
    volatile i2c_t *i2c_adapter = i2c[instance->i2c_num];
 | 
			
		||||
    uint32_t status = i2c_adapter->intr_stat;
 | 
			
		||||
    if (status & I2C_INTR_STAT_START_DET)
 | 
			
		||||
    {
 | 
			
		||||
        instance->slave_handler->on_event(I2C_EV_START);
 | 
			
		||||
        readl(&i2c_adapter->clr_start_det);
 | 
			
		||||
    }
 | 
			
		||||
    if (status & I2C_INTR_STAT_STOP_DET)
 | 
			
		||||
    {
 | 
			
		||||
        instance->slave_handler->on_event(I2C_EV_STOP);
 | 
			
		||||
        readl(&i2c_adapter->clr_stop_det);
 | 
			
		||||
    }
 | 
			
		||||
    if (status & I2C_INTR_STAT_RX_FULL)
 | 
			
		||||
    {
 | 
			
		||||
        instance->slave_handler->on_receive(i2c_adapter->data_cmd);
 | 
			
		||||
    }
 | 
			
		||||
    if (status & I2C_INTR_STAT_RD_REQ)
 | 
			
		||||
    {
 | 
			
		||||
        i2c_adapter->data_cmd = instance->slave_handler->on_transmit();
 | 
			
		||||
        readl(&i2c_adapter->clr_rd_req);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_init_as_slave(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t address_width,
 | 
			
		||||
    const i2c_slave_handler_t *handler)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(address_width == 7 || address_width == 10);
 | 
			
		||||
    volatile i2c_t *i2c_adapter = i2c[i2c_num];
 | 
			
		||||
    slave_instance[i2c_num].i2c_num = i2c_num;
 | 
			
		||||
    slave_instance[i2c_num].slave_handler = handler;
 | 
			
		||||
 | 
			
		||||
    i2c_clk_init(i2c_num);
 | 
			
		||||
    i2c_adapter->enable = 0;
 | 
			
		||||
    i2c_adapter->con = (address_width == 10 ? I2C_CON_10BITADDR_SLAVE : 0) | I2C_CON_SPEED(1) | I2C_CON_STOP_DET_IFADDRESSED;
 | 
			
		||||
    i2c_adapter->ss_scl_hcnt = I2C_SS_SCL_HCNT_COUNT(37);
 | 
			
		||||
    i2c_adapter->ss_scl_lcnt = I2C_SS_SCL_LCNT_COUNT(40);
 | 
			
		||||
    i2c_adapter->sar = I2C_SAR_ADDRESS(slave_address);
 | 
			
		||||
    i2c_adapter->rx_tl = I2C_RX_TL_VALUE(0);
 | 
			
		||||
    i2c_adapter->tx_tl = I2C_TX_TL_VALUE(0);
 | 
			
		||||
    i2c_adapter->intr_mask = I2C_INTR_MASK_RX_FULL | I2C_INTR_MASK_START_DET | I2C_INTR_MASK_STOP_DET | I2C_INTR_MASK_RD_REQ;
 | 
			
		||||
 | 
			
		||||
    plic_set_priority(IRQN_I2C0_INTERRUPT + i2c_num, 1);
 | 
			
		||||
    plic_irq_register(IRQN_I2C0_INTERRUPT + i2c_num, i2c_slave_irq, slave_instance + i2c_num);
 | 
			
		||||
    plic_irq_enable(IRQN_I2C0_INTERRUPT + i2c_num);
 | 
			
		||||
 | 
			
		||||
    i2c_adapter->enable = I2C_ENABLE_ENABLE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int i2c_send_data(i2c_device_number_t i2c_num, const uint8_t *SendBuf, size_t send_buf_len)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(i2c_num < I2C_MAX_NUM);
 | 
			
		||||
    volatile i2c_t* i2c_adapter = i2c[i2c_num];
 | 
			
		||||
    size_t fifo_len, index;
 | 
			
		||||
    i2c_adapter->clr_tx_abrt = i2c_adapter->clr_tx_abrt;
 | 
			
		||||
    while (send_buf_len)
 | 
			
		||||
    {
 | 
			
		||||
        fifo_len = 8 - i2c_adapter->txflr;
 | 
			
		||||
        fifo_len = send_buf_len < fifo_len ? send_buf_len : fifo_len;
 | 
			
		||||
        for (index = 0; index < fifo_len; index++)
 | 
			
		||||
            i2c_adapter->data_cmd = I2C_DATA_CMD_DATA(*SendBuf++);
 | 
			
		||||
        if (i2c_adapter->tx_abrt_source != 0)
 | 
			
		||||
            return 1;
 | 
			
		||||
        send_buf_len -= fifo_len;
 | 
			
		||||
    }
 | 
			
		||||
    while ((i2c_adapter->status & I2C_STATUS_ACTIVITY) || !(i2c_adapter->status & I2C_STATUS_TFE))
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
    if (i2c_adapter->tx_abrt_source != 0)
 | 
			
		||||
        return 1;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_send_data_dma(dmac_channel_number_t dma_channel_num, i2c_device_number_t i2c_num, const uint8_t *SendBuf,
 | 
			
		||||
                       size_t send_buf_len)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(i2c_num < I2C_MAX_NUM);
 | 
			
		||||
    volatile i2c_t* i2c_adapter = i2c[i2c_num];
 | 
			
		||||
    i2c_adapter->clr_tx_abrt = i2c_adapter->clr_tx_abrt;
 | 
			
		||||
    uint32_t *buf = malloc(send_buf_len * sizeof(uint32_t));
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < send_buf_len; i++)
 | 
			
		||||
    {
 | 
			
		||||
        buf[i] = SendBuf[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sysctl_dma_select((sysctl_dma_channel_t)dma_channel_num, SYSCTL_DMA_SELECT_I2C0_TX_REQ + i2c_num * 2);
 | 
			
		||||
    dmac_set_single_mode(dma_channel_num, buf, (void *)(&i2c_adapter->data_cmd), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
 | 
			
		||||
        DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, send_buf_len);
 | 
			
		||||
 | 
			
		||||
    dmac_wait_done(dma_channel_num);
 | 
			
		||||
    free((void *)buf);
 | 
			
		||||
 | 
			
		||||
    while ((i2c_adapter->status & I2C_STATUS_ACTIVITY) || !(i2c_adapter->status & I2C_STATUS_TFE))
 | 
			
		||||
    {
 | 
			
		||||
        if (i2c_adapter->tx_abrt_source != 0)
 | 
			
		||||
            return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int i2c_recv_data(i2c_device_number_t i2c_num, const uint8_t *SendBuf, size_t send_buf_len, uint8_t *receive_buf,
 | 
			
		||||
                  size_t receive_buf_len)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(i2c_num < I2C_MAX_NUM);
 | 
			
		||||
 | 
			
		||||
    size_t fifo_len, index;
 | 
			
		||||
    size_t rx_len = receive_buf_len;
 | 
			
		||||
    volatile i2c_t* i2c_adapter = i2c[i2c_num];
 | 
			
		||||
 | 
			
		||||
    while (send_buf_len)
 | 
			
		||||
    {
 | 
			
		||||
        fifo_len = 8 - i2c_adapter->txflr;
 | 
			
		||||
        fifo_len = send_buf_len < fifo_len ? send_buf_len : fifo_len;
 | 
			
		||||
        for (index = 0; index < fifo_len; index++)
 | 
			
		||||
            i2c_adapter->data_cmd = I2C_DATA_CMD_DATA(*SendBuf++);
 | 
			
		||||
        if (i2c_adapter->tx_abrt_source != 0)
 | 
			
		||||
            return 1;
 | 
			
		||||
        send_buf_len -= fifo_len;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (receive_buf_len || rx_len)
 | 
			
		||||
    {
 | 
			
		||||
        fifo_len = i2c_adapter->rxflr;
 | 
			
		||||
        fifo_len = rx_len < fifo_len ? rx_len : fifo_len;
 | 
			
		||||
        for (index = 0; index < fifo_len; index++)
 | 
			
		||||
            *receive_buf++ = (uint8_t)i2c_adapter->data_cmd;
 | 
			
		||||
        rx_len -= fifo_len;
 | 
			
		||||
        fifo_len = 8 - i2c_adapter->txflr;
 | 
			
		||||
        fifo_len = receive_buf_len < fifo_len ? receive_buf_len : fifo_len;
 | 
			
		||||
        for (index = 0; index < fifo_len; index++)
 | 
			
		||||
            i2c_adapter->data_cmd = I2C_DATA_CMD_CMD;
 | 
			
		||||
        if (i2c_adapter->tx_abrt_source != 0)
 | 
			
		||||
            return 1;
 | 
			
		||||
        receive_buf_len -= fifo_len;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_recv_data_dma(dmac_channel_number_t dma_send_channel_num, dmac_channel_number_t dma_receive_channel_num,
 | 
			
		||||
                       i2c_device_number_t i2c_num, const uint8_t *SendBuf, size_t send_buf_len,
 | 
			
		||||
                       uint8_t *receive_buf, size_t receive_buf_len)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(i2c_num < I2C_MAX_NUM);
 | 
			
		||||
 | 
			
		||||
    volatile i2c_t* i2c_adapter = i2c[i2c_num];
 | 
			
		||||
 | 
			
		||||
    uint32_t *write_cmd = malloc(sizeof(uint32_t) * (send_buf_len + receive_buf_len));
 | 
			
		||||
    size_t i;
 | 
			
		||||
    for(i = 0; i < send_buf_len; i++)
 | 
			
		||||
        write_cmd[i] = *SendBuf++;
 | 
			
		||||
    for (i = 0; i < receive_buf_len; i++)
 | 
			
		||||
        write_cmd[i + send_buf_len] = I2C_DATA_CMD_CMD;
 | 
			
		||||
 | 
			
		||||
    sysctl_dma_select((sysctl_dma_channel_t)dma_send_channel_num, SYSCTL_DMA_SELECT_I2C0_TX_REQ + i2c_num * 2);
 | 
			
		||||
    sysctl_dma_select((sysctl_dma_channel_t)dma_receive_channel_num, SYSCTL_DMA_SELECT_I2C0_RX_REQ + i2c_num * 2);
 | 
			
		||||
 | 
			
		||||
    dmac_set_single_mode(dma_receive_channel_num, (void *)(&i2c_adapter->data_cmd), write_cmd, DMAC_ADDR_NOCHANGE,
 | 
			
		||||
         DMAC_ADDR_INCREMENT,DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, receive_buf_len);
 | 
			
		||||
 | 
			
		||||
    dmac_set_single_mode(dma_send_channel_num, write_cmd, (void *)(&i2c_adapter->data_cmd), DMAC_ADDR_INCREMENT,
 | 
			
		||||
         DMAC_ADDR_NOCHANGE,DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, receive_buf_len + send_buf_len);
 | 
			
		||||
 | 
			
		||||
    dmac_wait_done(dma_send_channel_num);
 | 
			
		||||
    dmac_wait_done(dma_receive_channel_num);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < receive_buf_len; i++)
 | 
			
		||||
    {
 | 
			
		||||
        receive_buf[i] = (uint8_t)write_cmd[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(write_cmd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int i2c_dma_irq(void *ctx)
 | 
			
		||||
{
 | 
			
		||||
    i2c_instance_t *v_instance = (i2c_instance_t *)ctx;
 | 
			
		||||
    volatile i2c_t* i2c_adapter = i2c[v_instance->i2c_num];
 | 
			
		||||
    dmac_irq_unregister(v_instance->dmac_channel);
 | 
			
		||||
    if(v_instance->TransferMode == I2C_SEND)
 | 
			
		||||
    {
 | 
			
		||||
        while ((i2c_adapter->status & I2C_STATUS_ACTIVITY) || !(i2c_adapter->status & I2C_STATUS_TFE))
 | 
			
		||||
        {
 | 
			
		||||
            if (i2c_adapter->tx_abrt_source != 0)
 | 
			
		||||
            {
 | 
			
		||||
                spinlock_unlock(&v_instance->lock);
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    spinlock_unlock(&v_instance->lock);
 | 
			
		||||
    if(v_instance->i2c_int_instance.callback)
 | 
			
		||||
    {
 | 
			
		||||
        v_instance->i2c_int_instance.callback(v_instance->i2c_int_instance.ctx);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_handle_data_dma(i2c_device_number_t i2c_num, i2c_data_t data, plic_interrupt_t *cb)
 | 
			
		||||
{
 | 
			
		||||
    configASSERT(i2c_num < I2C_MAX_NUM);
 | 
			
		||||
    configASSERT(data.tx_channel < DMAC_CHANNEL_MAX && data.rx_channel < DMAC_CHANNEL_MAX);
 | 
			
		||||
 | 
			
		||||
    spinlock_lock(&g_i2c_instance[i2c_num].lock);
 | 
			
		||||
    if(cb)
 | 
			
		||||
    {
 | 
			
		||||
        g_i2c_instance[i2c_num].i2c_int_instance.callback = cb->callback;
 | 
			
		||||
        g_i2c_instance[i2c_num].i2c_int_instance.ctx = cb->ctx;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    volatile i2c_t* i2c_adapter = i2c[i2c_num];
 | 
			
		||||
    if(data.TransferMode == I2C_SEND)
 | 
			
		||||
    {
 | 
			
		||||
        configASSERT(data.tx_buf && data.tx_len);
 | 
			
		||||
 | 
			
		||||
        i2c_adapter->clr_tx_abrt = i2c_adapter->clr_tx_abrt;
 | 
			
		||||
        if(cb)
 | 
			
		||||
        {
 | 
			
		||||
            g_i2c_instance[i2c_num].dmac_channel = data.tx_channel;
 | 
			
		||||
            g_i2c_instance[i2c_num].TransferMode = I2C_SEND;
 | 
			
		||||
            dmac_irq_register(data.tx_channel, i2c_dma_irq, &g_i2c_instance[i2c_num], cb->priority);
 | 
			
		||||
        }
 | 
			
		||||
        sysctl_dma_select((sysctl_dma_channel_t)data.tx_channel, SYSCTL_DMA_SELECT_I2C0_TX_REQ + i2c_num * 2);
 | 
			
		||||
        dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&i2c_adapter->data_cmd), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
 | 
			
		||||
            DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len);
 | 
			
		||||
        if(!cb)
 | 
			
		||||
        {
 | 
			
		||||
            dmac_wait_done(data.tx_channel);
 | 
			
		||||
            while ((i2c_adapter->status & I2C_STATUS_ACTIVITY) || !(i2c_adapter->status & I2C_STATUS_TFE))
 | 
			
		||||
            {
 | 
			
		||||
                if (i2c_adapter->tx_abrt_source != 0)
 | 
			
		||||
                    configASSERT(!"source abort");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        configASSERT(data.rx_buf && data.rx_len);
 | 
			
		||||
        if(data.tx_len)
 | 
			
		||||
            configASSERT(data.tx_buf);
 | 
			
		||||
        if(cb)
 | 
			
		||||
        {
 | 
			
		||||
            g_i2c_instance[i2c_num].dmac_channel = data.rx_channel;
 | 
			
		||||
            g_i2c_instance[i2c_num].TransferMode = I2C_RECEIVE;
 | 
			
		||||
            dmac_irq_register(data.rx_channel, i2c_dma_irq, &g_i2c_instance[i2c_num], cb->priority);
 | 
			
		||||
        }
 | 
			
		||||
        sysctl_dma_select((sysctl_dma_channel_t)data.rx_channel, SYSCTL_DMA_SELECT_I2C0_RX_REQ + i2c_num * 2);
 | 
			
		||||
        dmac_set_single_mode(data.rx_channel, (void *)(&i2c_adapter->data_cmd), data.rx_buf, DMAC_ADDR_NOCHANGE,
 | 
			
		||||
             DMAC_ADDR_INCREMENT,DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len);
 | 
			
		||||
 | 
			
		||||
        sysctl_dma_select((sysctl_dma_channel_t)data.tx_channel, SYSCTL_DMA_SELECT_I2C0_TX_REQ + i2c_num * 2);
 | 
			
		||||
        if(data.tx_len)
 | 
			
		||||
        {
 | 
			
		||||
            configASSERT(data.tx_buf);
 | 
			
		||||
            dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&i2c_adapter->data_cmd), DMAC_ADDR_INCREMENT,
 | 
			
		||||
                 DMAC_ADDR_NOCHANGE,DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len);
 | 
			
		||||
            dmac_wait_done(data.tx_channel);
 | 
			
		||||
        }
 | 
			
		||||
        static uint32_t s_read_cmd = I2C_DATA_CMD_CMD;
 | 
			
		||||
        dmac_set_single_mode(data.tx_channel, &s_read_cmd, (void *)(&i2c_adapter->data_cmd), DMAC_ADDR_NOCHANGE,
 | 
			
		||||
                     DMAC_ADDR_NOCHANGE,DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len);
 | 
			
		||||
 | 
			
		||||
        if(!cb)
 | 
			
		||||
        {
 | 
			
		||||
            dmac_wait_done(data.tx_channel);
 | 
			
		||||
            dmac_wait_done(data.rx_channel);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if(!cb)
 | 
			
		||||
        spinlock_unlock(&g_i2c_instance[i2c_num].lock);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,323 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 clint.h
 | 
			
		||||
* @brief add from Canaan k210 SDK
 | 
			
		||||
*                https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __CLINT_H__
 | 
			
		||||
#define __CLINT_H__
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* clang-format off */
 | 
			
		||||
/* Register address offsets */
 | 
			
		||||
#define CLINT_MSIP          (0x0000)
 | 
			
		||||
#define CLINT_MSIP_SIZE     (0x4)
 | 
			
		||||
#define CLINT_MTIMECMP      (0x4000)
 | 
			
		||||
#define CLINT_MTIMECMP_SIZE (0x8)
 | 
			
		||||
#define CLINT_MTIME         (0xBFF8)
 | 
			
		||||
#define CLINT_MTIME_SIZE    (0x8)
 | 
			
		||||
/* Max number of cores */
 | 
			
		||||
#define CLINT_MAX_CORES     (4095)
 | 
			
		||||
/* Real number of cores */
 | 
			
		||||
#define CLINT_NUM_CORES     (2)
 | 
			
		||||
/* Clock frequency division factor */
 | 
			
		||||
#define CLINT_CLOCK_DIV     (50)
 | 
			
		||||
/* clang-format on */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       MSIP Registers
 | 
			
		||||
 *
 | 
			
		||||
 *              Machine-mode software interrupts are generated by writing to a
 | 
			
		||||
 *              per-core memory-mapped control register. The msip registers are
 | 
			
		||||
 *              32-bit wide WARL registers, where the LSB is reflected in the
 | 
			
		||||
 *              msip bit of the associated core’s mip register. Other bits in
 | 
			
		||||
 *              the msip registers are hardwired to zero. The mapping supports
 | 
			
		||||
 *              up to 4095 machine-mode cores.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _clint_msip
 | 
			
		||||
{
 | 
			
		||||
    uint32_t msip : 1;  /*!< Bit 0 is msip */
 | 
			
		||||
    uint32_t zero : 31; /*!< Bits [32:1] is 0 */
 | 
			
		||||
} __attribute__((packed, aligned(4))) clint_msip_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Timer compare Registers Machine-mode timer interrupts are
 | 
			
		||||
 *              generated by a real-time counter and a per-core comparator. The
 | 
			
		||||
 *              mtime register is a 64-bit read-only register that contains the
 | 
			
		||||
 *              current value of the real-time counter. Each mtimecmp register
 | 
			
		||||
 *              holds its core’s time comparator. A timer interrupt is pending
 | 
			
		||||
 *              whenever mtime is greater than or equal to the value in a
 | 
			
		||||
 *              core’s mtimecmp register. The timer interrupt is reflected in
 | 
			
		||||
 *              the mtip bit of the associated core’s mip register.
 | 
			
		||||
 */
 | 
			
		||||
typedef uint64_t clint_mtimecmp_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Timer Registers
 | 
			
		||||
 *
 | 
			
		||||
 *              The mtime register has a 64-bit precision on all RV32, RV64,
 | 
			
		||||
 *              and RV128 systems. Platforms provide a 64-bit memory-mapped
 | 
			
		||||
 *              machine-mode timer compare register (mtimecmp), which causes a
 | 
			
		||||
 *              timer interrupt to be posted when the mtime register contains a
 | 
			
		||||
 *              value greater than or equal to the value in the mtimecmp
 | 
			
		||||
 *              register. The interrupt remains posted until it is cleared by
 | 
			
		||||
 *              writing the mtimecmp register. The interrupt will only be taken
 | 
			
		||||
 *              if interrupts are enabled and the MTIE bit is set in the mie
 | 
			
		||||
 *              register.
 | 
			
		||||
 */
 | 
			
		||||
typedef uint64_t clint_mtime_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       CLINT object
 | 
			
		||||
 *
 | 
			
		||||
 *              Coreplex-Local INTerrupts, which includes software interrupts,
 | 
			
		||||
 *              local timer interrupts, and other interrupts routed directly to
 | 
			
		||||
 *              a core.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _clint
 | 
			
		||||
{
 | 
			
		||||
    /* 0x0000 to 0x3FF8, MSIP Registers */
 | 
			
		||||
    clint_msip_t msip[CLINT_MAX_CORES];
 | 
			
		||||
    /* Resverd space, do not use */
 | 
			
		||||
    uint32_t resv0;
 | 
			
		||||
    /* 0x4000 to 0xBFF0, Timer Compare Registers */
 | 
			
		||||
    clint_mtimecmp_t mtimecmp[CLINT_MAX_CORES];
 | 
			
		||||
    /* 0xBFF8, Time Register */
 | 
			
		||||
    clint_mtime_t mtime;
 | 
			
		||||
} __attribute__((packed, aligned(4))) clint_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Clint object instanse
 | 
			
		||||
 */
 | 
			
		||||
extern volatile clint_t* const clint;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Definitions for the timer callbacks
 | 
			
		||||
 */
 | 
			
		||||
typedef int (*clint_timer_callback_t)(void *ctx);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Definitions for local interprocessor interrupt callbacks
 | 
			
		||||
 */
 | 
			
		||||
typedef int (*clint_ipi_callback_t)(void *ctx);
 | 
			
		||||
 | 
			
		||||
typedef struct _clint_timer_instance
 | 
			
		||||
{
 | 
			
		||||
    uint64_t interval;
 | 
			
		||||
    uint64_t cycles;
 | 
			
		||||
    uint64_t single_shot;
 | 
			
		||||
    clint_timer_callback_t callback;
 | 
			
		||||
    void *ctx;
 | 
			
		||||
} clint_timer_instance_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _clint_ipi_instance
 | 
			
		||||
{
 | 
			
		||||
    clint_ipi_callback_t callback;
 | 
			
		||||
    void *ctx;
 | 
			
		||||
} clint_ipi_instance_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Get the time form CLINT timer register
 | 
			
		||||
 *
 | 
			
		||||
 * @note        The CLINT must init to get right time
 | 
			
		||||
 *
 | 
			
		||||
 * @return      64bit Time
 | 
			
		||||
 */
 | 
			
		||||
uint64_t clint_get_time(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Init the CLINT timer
 | 
			
		||||
 *
 | 
			
		||||
 * @note        MIP_MTIP will be clear after init. The MSTATUS_MIE must set by
 | 
			
		||||
 *              user.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_timer_init(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Stop the CLINT timer
 | 
			
		||||
 *
 | 
			
		||||
 * @note        MIP_MTIP will be clear after stop
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_timer_stop(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Start the CLINT timer
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   interval        The interval with Millisecond(ms)
 | 
			
		||||
 * @param[in]   single_shot     Single shot or repeat
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_timer_start(uint64_t interval, int single_shot);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Get the interval of timer
 | 
			
		||||
 *
 | 
			
		||||
 * @return      The interval with Millisecond(ms)
 | 
			
		||||
 */
 | 
			
		||||
uint64_t clint_timer_get_interval(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set the interval with Millisecond(ms)
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   interval  The interval with Millisecond(ms)
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_timer_set_interval(uint64_t interval);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief      Get whether the timer is a single shot timer
 | 
			
		||||
 *
 | 
			
		||||
 * @return     result
 | 
			
		||||
 *     - 0     It is a repeat timer
 | 
			
		||||
 *     - 1     It is a single shot timer
 | 
			
		||||
 */
 | 
			
		||||
int clint_timer_get_single_shot(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set the timer working as a single shot timer or repeat timer
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   single_shot  Single shot or repeat
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_timer_set_single_shot(int single_shot);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set user callback function when timer is timeout
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   callback        The callback function
 | 
			
		||||
 * @param[in]   ctx             The context
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_timer_register(clint_timer_callback_t callback, void *ctx);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Deregister user callback function
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_timer_unregister(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Initialize local interprocessor interrupt
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_ipi_init(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Enable local interprocessor interrupt
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_ipi_enable(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Disable local interprocessor interrupt
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_ipi_disable(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Send local interprocessor interrupt to core by core id
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   core_id  The core identifier
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_ipi_send(size_t core_id);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Clear local interprocessor interrupt
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   core_id  The core identifier
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 1      An IPI was pending
 | 
			
		||||
 *     - 0      Non IPI was pending
 | 
			
		||||
 *     - -1     Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_ipi_clear(size_t core_id);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief      Set user callback function when interprocessor interrupt
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   callback        The callback function
 | 
			
		||||
 * @param[in]   ctx             The context
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_ipi_register(clint_ipi_callback_t callback, void *ctx);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Deregister user callback function
 | 
			
		||||
 *
 | 
			
		||||
 * @return      result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other  Fail
 | 
			
		||||
 */
 | 
			
		||||
int clint_ipi_unregister(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* __CLINT_H__ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) 2020 AIIT XUOS Lab
 | 
			
		||||
* XiUOS is licensed under Mulan PSL v2.
 | 
			
		||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
 | 
			
		||||
* You may obtain a copy of Mulan PSL v2 at:
 | 
			
		||||
*        http://license.coscl.org.cn/MulanPSL2
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the Mulan PSL v2 for more details.
 | 
			
		||||
*/
 | 
			
		||||
 
 | 
			
		||||
/**
 | 
			
		||||
* @file connect_ch376.h
 | 
			
		||||
* @brief define edu-riscv64 ch376 function and struct
 | 
			
		||||
* @version 2.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef CONNECT_CH376_H
 | 
			
		||||
#define CONNECT_CH376_H
 | 
			
		||||
 | 
			
		||||
#include <device.h>
 | 
			
		||||
 | 
			
		||||
struct HwCh376
 | 
			
		||||
{
 | 
			
		||||
    HardwareDevType dev;
 | 
			
		||||
    x_size_t msg_len;
 | 
			
		||||
    int sem;
 | 
			
		||||
    KTaskDescriptorType task;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int HwCh376Init(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) 2020 AIIT XUOS Lab
 | 
			
		||||
* XiUOS is licensed under Mulan PSL v2.
 | 
			
		||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
 | 
			
		||||
* You may obtain a copy of Mulan PSL v2 at:
 | 
			
		||||
*        http://license.coscl.org.cn/MulanPSL2
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the Mulan PSL v2 for more details.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @file connect_gpio.h
 | 
			
		||||
* @brief define edu-riscv64-board gpio function and struct
 | 
			
		||||
* @version 2.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef CONNECT_GPIO_H
 | 
			
		||||
#define CONNECT_GPIO_H
 | 
			
		||||
 | 
			
		||||
#include <device.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int HwGpioInit(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) 2020 AIIT XUOS Lab
 | 
			
		||||
* XiUOS is licensed under Mulan PSL v2.
 | 
			
		||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
 | 
			
		||||
* You may obtain a copy of Mulan PSL v2 at:
 | 
			
		||||
*        http://license.coscl.org.cn/MulanPSL2
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the Mulan PSL v2 for more details.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @file connect_i2c.h
 | 
			
		||||
* @brief define edu-riscv64-board i2c function and struct
 | 
			
		||||
* @version 2.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef CONNECT_I2C_H
 | 
			
		||||
#define CONNECT_I2C_H
 | 
			
		||||
 | 
			
		||||
#include <device.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int HwI2cInit(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,52 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 connect_lcd.h
 | 
			
		||||
* @brief define aiit-riscv64-board lcd function
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
File name: connect_lcd.h
 | 
			
		||||
Description: define aiit-riscv64-board lcd function
 | 
			
		||||
Others:  https://canaan-creative.com/developer
 | 
			
		||||
History: 
 | 
			
		||||
1. Date: 2021-04-25
 | 
			
		||||
Author: AIIT XUOS Lab
 | 
			
		||||
Modification: 
 | 
			
		||||
1. add aiit-riscv64-board lcd function
 | 
			
		||||
*************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef CONNECT_LCD_H
 | 
			
		||||
#define CONNECT_LCD_H
 | 
			
		||||
 | 
			
		||||
#include <device.h>
 | 
			
		||||
#include "hardware_spi.h"
 | 
			
		||||
#include <sysctl.h>
 | 
			
		||||
 | 
			
		||||
#ifdef BSP_USING_TOUCH
 | 
			
		||||
#include "connect_touch.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void DrvLcdClear(uint16_t color);
 | 
			
		||||
void LcdDrawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2,uint16 color);							
 | 
			
		||||
void LcdDrawRectangle(uint16 x1, uint16 y1, uint16 x2, uint16 y2,uint16 color);		   			
 | 
			
		||||
void LcdDrawCircle(uint16 x0,uint16 y0,uint8 r,uint16 color);
 | 
			
		||||
 | 
			
		||||
int HwLcdInit(void);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) 2020 AIIT XUOS Lab
 | 
			
		||||
* XiUOS is licensed under Mulan PSL v2.
 | 
			
		||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
 | 
			
		||||
* You may obtain a copy of Mulan PSL v2 at:
 | 
			
		||||
*        http://license.coscl.org.cn/MulanPSL2
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the Mulan PSL v2 for more details.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @file connect_spi.h
 | 
			
		||||
* @brief define aiit-riscv64-board spi function and struct
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2021-04-25
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef CONNECT_SPI_H
 | 
			
		||||
#define CONNECT_SPI_H
 | 
			
		||||
 | 
			
		||||
#include <device.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int HwSpiInit(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) 2020 AIIT XUOS Lab
 | 
			
		||||
* XiUOS is licensed under Mulan PSL v2.
 | 
			
		||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
 | 
			
		||||
* You may obtain a copy of Mulan PSL v2 at:
 | 
			
		||||
*        http://license.coscl.org.cn/MulanPSL2
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the Mulan PSL v2 for more details.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @file connect_touch.h
 | 
			
		||||
* @brief support edu-riscv64 touch function and register to bus framework
 | 
			
		||||
* @version 2.0 
 | 
			
		||||
* @author AIIT XiUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __CONNECT_TOUCH_H__
 | 
			
		||||
#define __CONNECT_TOUCH_H__
 | 
			
		||||
 | 
			
		||||
#include <device.h>	 
 | 
			
		||||
 | 
			
		||||
/* 表示读数据 */ 
 | 
			
		||||
#define I2C_M_RD		0x0001
 | 
			
		||||
 | 
			
		||||
struct i2c_msg {
 | 
			
		||||
	uint16_t flags;	    /*控制标志 */
 | 
			
		||||
	uint16_t len;		/*读写数据的长度	*/
 | 
			
		||||
	uint8_t *buf;		/*存储读写数据的指针 */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  int  X;
 | 
			
		||||
  int  Y;
 | 
			
		||||
} POINT;
 | 
			
		||||
 | 
			
		||||
typedef enum _touch_event
 | 
			
		||||
{
 | 
			
		||||
    kTouch_Down = 0,    /*!< The state changed to touched. */
 | 
			
		||||
    kTouch_Up = 1,      /*!< The state changed to not touched. */
 | 
			
		||||
    kTouch_Contact = 2, /*!< There is a continuous touch being detected. */
 | 
			
		||||
    kTouch_Reserved = 3 /*!< No touch information available. */
 | 
			
		||||
} touch_event_t;
 | 
			
		||||
 | 
			
		||||
/*设定使用的电容屏IIC设备地址*/
 | 
			
		||||
#define GTP_ADDRESS            0xBA
 | 
			
		||||
 | 
			
		||||
#define GTP_MAX_HEIGHT   272
 | 
			
		||||
#define GTP_MAX_WIDTH    480
 | 
			
		||||
#define GTP_INT_TRIGGER  0
 | 
			
		||||
#define GTP_MAX_TOUCH    5
 | 
			
		||||
 | 
			
		||||
#define GTP_CONFIG_MAX_LENGTH 240
 | 
			
		||||
#define GTP_ADDR_LENGTH       2
 | 
			
		||||
 | 
			
		||||
// Registers define
 | 
			
		||||
#define GTP_READ_COOR_ADDR    0x814E
 | 
			
		||||
#define GTP_REG_SLEEP         0x8040
 | 
			
		||||
#define GTP_REG_SENSOR_ID     0x814A
 | 
			
		||||
#define GTP_REG_CONFIG_DATA   0x8047
 | 
			
		||||
#define GTP_REG_VERSION       0x8140
 | 
			
		||||
 | 
			
		||||
#define CFG_GROUP_LEN(p_cfg_grp)  (sizeof(p_cfg_grp) / sizeof(p_cfg_grp[0]))
 | 
			
		||||
 | 
			
		||||
int HwTouchInit(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,40 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) 2020 AIIT XUOS Lab
 | 
			
		||||
* XiUOS is licensed under Mulan PSL v2.
 | 
			
		||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
 | 
			
		||||
* You may obtain a copy of Mulan PSL v2 at:
 | 
			
		||||
*        http://license.coscl.org.cn/MulanPSL2
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the Mulan PSL v2 for more details.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @file connect_uart.h
 | 
			
		||||
* @brief define edu-riscv64-board uart function and struct
 | 
			
		||||
* @version 2.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef CONNECT_UART_H
 | 
			
		||||
#define CONNECT_UART_H
 | 
			
		||||
 | 
			
		||||
#include <device.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define KERNEL_CONSOLE_BUS_NAME        SERIAL_BUS_NAME_0
 | 
			
		||||
#define KERNEL_CONSOLE_DRV_NAME        SERIAL_DRV_NAME_0
 | 
			
		||||
#define KERNEL_CONSOLE_DEVICE_NAME SERIAL_0_DEVICE_NAME_0
 | 
			
		||||
 | 
			
		||||
int HwUartInit(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,83 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2006-2018, RT-Thread Development Team
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Change Logs:
 | 
			
		||||
 * Date           Author       Notes
 | 
			
		||||
 * 2019-03-19     ZYH          first version
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @file drv_io_config.h
 | 
			
		||||
* @brief define edu-riscv64-board io configure
 | 
			
		||||
* @version 2.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
File name: drv_io_config.h
 | 
			
		||||
Description: define edu-riscv64-board io configure
 | 
			
		||||
Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.h for references
 | 
			
		||||
                https://github.com/RT-Thread/rt-thread/tree/v4.0.2
 | 
			
		||||
History: 
 | 
			
		||||
1. Date: 2022-10-17
 | 
			
		||||
Author: AIIT XUOS Lab
 | 
			
		||||
Modification: add edu-riscv64-board io configure define
 | 
			
		||||
*************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef __DRV_IO_CONFIG_H__
 | 
			
		||||
#define __DRV_IO_CONFIG_H__
 | 
			
		||||
 | 
			
		||||
enum HS_GPIO_CONFIG
 | 
			
		||||
{
 | 
			
		||||
#ifdef BSP_USING_LCD
 | 
			
		||||
    LCD_DC_PIN = 0,     /* LCD DC PIN */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_SPI1_USING_SS0
 | 
			
		||||
    SPI1_CS0_PIN,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_SPI1_USING_SS1
 | 
			
		||||
    SPI1_CS1_PIN,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_SPI1_USING_SS2
 | 
			
		||||
    SPI1_CS2_PIN,
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_SPI1_USING_SS3
 | 
			
		||||
    SPI1_CS3_PIN,
 | 
			
		||||
#endif
 | 
			
		||||
    GPIO_ALLOC_START /* index of gpio driver start */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef BSP_USING_CH438
 | 
			
		||||
#define FPIOA_CH438_ALE   12
 | 
			
		||||
#define FPIOA_CH438_NWR   13
 | 
			
		||||
#define FPIOA_CH438_NRD   14
 | 
			
		||||
#define FPIOA_CH438_D0    15
 | 
			
		||||
#define FPIOA_CH438_D1    16
 | 
			
		||||
#define FPIOA_CH438_D2    17
 | 
			
		||||
#define FPIOA_CH438_D3    18
 | 
			
		||||
#define FPIOA_CH438_D4    19
 | 
			
		||||
#define FPIOA_CH438_D5    20
 | 
			
		||||
#define FPIOA_CH438_D6    21
 | 
			
		||||
#define FPIOA_CH438_D7    22
 | 
			
		||||
#define FPIOA_CH438_INT   23
 | 
			
		||||
 | 
			
		||||
#define BSP_CH438_ALE_PIN   24
 | 
			
		||||
#define BSP_CH438_NWR_PIN   25
 | 
			
		||||
#define BSP_CH438_NRD_PIN   26
 | 
			
		||||
#define BSP_CH438_D0_PIN    27
 | 
			
		||||
#define BSP_CH438_D1_PIN    28
 | 
			
		||||
#define BSP_CH438_D2_PIN    29
 | 
			
		||||
#define BSP_CH438_D3_PIN    30
 | 
			
		||||
#define BSP_CH438_D4_PIN    31
 | 
			
		||||
#define BSP_CH438_D5_PIN    32
 | 
			
		||||
#define BSP_CH438_D6_PIN    33
 | 
			
		||||
#define BSP_CH438_D7_PIN    34
 | 
			
		||||
#define BSP_CH438_INT_PIN   35
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
extern int IoConfigInit(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,279 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 dvp.h
 | 
			
		||||
* @brief add from Canaan k210 SDK
 | 
			
		||||
*                https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __DVP_H__
 | 
			
		||||
#define __DVP_H__
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* clang-format off */
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       DVP object
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _dvp
 | 
			
		||||
{
 | 
			
		||||
    uint32_t dvp_cfg;
 | 
			
		||||
    uint32_t r_addr;
 | 
			
		||||
    uint32_t g_addr;
 | 
			
		||||
    uint32_t b_addr;
 | 
			
		||||
    uint32_t cmos_cfg;
 | 
			
		||||
    uint32_t sccb_cfg;
 | 
			
		||||
    uint32_t sccb_ctl;
 | 
			
		||||
    uint32_t axi;
 | 
			
		||||
    uint32_t sts;
 | 
			
		||||
    uint32_t reverse;
 | 
			
		||||
    uint32_t rgb_addr;
 | 
			
		||||
} __attribute__((packed, aligned(4))) dvp_t;
 | 
			
		||||
 | 
			
		||||
/* DVP Config Register */
 | 
			
		||||
#define DVP_CFG_START_INT_ENABLE                0x00000001U
 | 
			
		||||
#define DVP_CFG_FINISH_INT_ENABLE               0x00000002U
 | 
			
		||||
#define DVP_CFG_AI_OUTPUT_ENABLE                0x00000004U
 | 
			
		||||
#define DVP_CFG_DISPLAY_OUTPUT_ENABLE           0x00000008U
 | 
			
		||||
#define DVP_CFG_AUTO_ENABLE                     0x00000010U
 | 
			
		||||
#define DVP_CFG_BURST_SIZE_4BEATS               0x00000100U
 | 
			
		||||
#define DVP_CFG_FORMAT_MASK                     0x00000600U
 | 
			
		||||
#define DVP_CFG_RGB_FORMAT                      0x00000000U
 | 
			
		||||
#define DVP_CFG_YUV_FORMAT                      0x00000200U
 | 
			
		||||
#define DVP_CFG_Y_FORMAT                        0x00000600U
 | 
			
		||||
#define DVP_CFG_HREF_BURST_NUM_MASK             0x000FF000U
 | 
			
		||||
#define DVP_CFG_HREF_BURST_NUM(x)               ((x) << 12)
 | 
			
		||||
#define DVP_CFG_LINE_NUM_MASK                   0x3FF00000U
 | 
			
		||||
#define DVP_CFG_LINE_NUM(x)                     ((x) << 20)
 | 
			
		||||
 | 
			
		||||
/* DVP CMOS Config Register */
 | 
			
		||||
#define DVP_CMOS_CLK_DIV_MASK                   0x000000FFU
 | 
			
		||||
#define DVP_CMOS_CLK_DIV(x)                     ((x) << 0)
 | 
			
		||||
#define DVP_CMOS_CLK_ENABLE                     0x00000100U
 | 
			
		||||
#define DVP_CMOS_RESET                          0x00010000U
 | 
			
		||||
#define DVP_CMOS_POWER_DOWN                     0x01000000U
 | 
			
		||||
 | 
			
		||||
/* DVP SCCB Config Register */
 | 
			
		||||
#define DVP_SCCB_BYTE_NUM_MASK                  0x00000003U
 | 
			
		||||
#define DVP_SCCB_BYTE_NUM_2                     0x00000001U
 | 
			
		||||
#define DVP_SCCB_BYTE_NUM_3                     0x00000002U
 | 
			
		||||
#define DVP_SCCB_BYTE_NUM_4                     0x00000003U
 | 
			
		||||
#define DVP_SCCB_SCL_LCNT_MASK                  0x0000FF00U
 | 
			
		||||
#define DVP_SCCB_SCL_LCNT(x)                    ((x) << 8)
 | 
			
		||||
#define DVP_SCCB_SCL_HCNT_MASK                  0x00FF0000U
 | 
			
		||||
#define DVP_SCCB_SCL_HCNT(x)                    ((x) << 16)
 | 
			
		||||
#define DVP_SCCB_RDATA_BYTE(x)                  ((x) >> 24)
 | 
			
		||||
 | 
			
		||||
/* DVP SCCB Control Register */
 | 
			
		||||
#define DVP_SCCB_WRITE_DATA_ENABLE                   0x00000001U
 | 
			
		||||
#define DVP_SCCB_DEVICE_ADDRESS(x)              ((x) << 0)
 | 
			
		||||
#define DVP_SCCB_REG_ADDRESS(x)                 ((x) << 8)
 | 
			
		||||
#define DVP_SCCB_WDATA_BYTE0(x)                 ((x) << 16)
 | 
			
		||||
#define DVP_SCCB_WDATA_BYTE1(x)                 ((x) << 24)
 | 
			
		||||
 | 
			
		||||
/* DVP AXI Register */
 | 
			
		||||
#define DVP_AXI_GM_MLEN_MASK                    0x000000FFU
 | 
			
		||||
#define DVP_AXI_GM_MLEN_1BYTE                   0x00000000U
 | 
			
		||||
#define DVP_AXI_GM_MLEN_4BYTE                   0x00000003U
 | 
			
		||||
 | 
			
		||||
/* DVP STS Register */
 | 
			
		||||
#define DVP_STS_FRAME_START                     0x00000001U
 | 
			
		||||
#define DVP_STS_FRAME_START_WE                  0x00000002U
 | 
			
		||||
#define DVP_STS_FRAME_FINISH                    0x00000100U
 | 
			
		||||
#define DVP_STS_FRAME_FINISH_WE                 0x00000200U
 | 
			
		||||
#define DVP_STS_DVP_EN                          0x00010000U
 | 
			
		||||
#define DVP_STS_DVP_EN_WE                       0x00020000U
 | 
			
		||||
#define DVP_STS_SCCB_EN                         0x01000000U
 | 
			
		||||
#define DVP_STS_SCCB_EN_WE                      0x02000000U
 | 
			
		||||
/* clang-format on */
 | 
			
		||||
 | 
			
		||||
typedef enum _dvp_output_mode
 | 
			
		||||
{
 | 
			
		||||
    DVP_OUTPUT_AI,
 | 
			
		||||
    DVP_OUTPUT_DISPLAY,
 | 
			
		||||
} dvp_output_mode_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       DVP object instance
 | 
			
		||||
 */
 | 
			
		||||
extern volatile dvp_t* const dvp;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Initialize DVP
 | 
			
		||||
 */
 | 
			
		||||
void dvp_init(uint8_t reg_len);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set image format
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   format      The image format
 | 
			
		||||
 */
 | 
			
		||||
void dvp_set_image_format(uint32_t format);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set image size
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   width   The width  of image
 | 
			
		||||
 * @param[in]   height  The height of image
 | 
			
		||||
 */
 | 
			
		||||
void dvp_set_image_size(uint32_t width, uint32_t height);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set the address of RGB for AI
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   r_addr      The R address of RGB
 | 
			
		||||
 * @param[in]   g_addr      The G address of RGB
 | 
			
		||||
 * @param[in]   b_addr      The B address of RGB
 | 
			
		||||
 */
 | 
			
		||||
void dvp_set_ai_addr(uint32_t r_addr, uint32_t g_addr, uint32_t b_addr);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set the address of RGB for display
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   r_addr      The R address of RGB
 | 
			
		||||
 * @param[in]   g_addr      The G address of RGB
 | 
			
		||||
 * @param[in]   b_addr      The B address of RGB
 | 
			
		||||
 */
 | 
			
		||||
void dvp_set_display_addr(uint32_t addr);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       The frame start transfer
 | 
			
		||||
 */
 | 
			
		||||
void dvp_start_frame(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       The DVP convert start
 | 
			
		||||
 */
 | 
			
		||||
void dvp_start_convert(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       The DVP convert finish
 | 
			
		||||
 */
 | 
			
		||||
void dvp_finish_convert(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Get the image data
 | 
			
		||||
 *
 | 
			
		||||
 * @note        The image data stored in the address of RGB
 | 
			
		||||
 */
 | 
			
		||||
void dvp_get_image(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Use SCCB write register
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   DevAddr        The device address
 | 
			
		||||
 * @param[in]   reg_addr        The register address
 | 
			
		||||
 * @param[in]   reg_data        The register data
 | 
			
		||||
 */
 | 
			
		||||
void dvp_sccb_send_data(uint8_t DevAddr, uint16_t reg_addr, uint8_t reg_data);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Use SCCB read register
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   DevAddr        The device address
 | 
			
		||||
 * @param[in]   reg_addr        The register address
 | 
			
		||||
 *
 | 
			
		||||
 * @return      The register value
 | 
			
		||||
 */
 | 
			
		||||
uint8_t dvp_sccb_receive_data(uint8_t DevAddr, uint16_t reg_addr);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Enable dvp burst
 | 
			
		||||
 */
 | 
			
		||||
void dvp_enable_burst(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Disable dvp burst
 | 
			
		||||
 */
 | 
			
		||||
void dvp_disable_burst(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Enable or disable dvp interrupt
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   interrupt       Dvp interrupt
 | 
			
		||||
 * @param[in]   status          0:disable 1:enable
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void dvp_config_interrupt(uint32_t interrupt, uint8_t enable);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Get dvp interrupt status
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   interrupt       Dvp interrupt
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * @return      Interrupt status
 | 
			
		||||
 *     - 0      false
 | 
			
		||||
 *     - 1      true
 | 
			
		||||
 */
 | 
			
		||||
int dvp_get_interrupt(uint32_t interrupt);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Clear dvp interrupt status
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   interrupt       Dvp interrupt
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void dvp_clear_interrupt(uint32_t interrupt);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Enable dvp auto mode
 | 
			
		||||
 */
 | 
			
		||||
void dvp_enable_auto(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Disable dvp auto mode
 | 
			
		||||
 */
 | 
			
		||||
void dvp_disable_auto(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Dvp ouput data enable or not
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   index       0:AI, 1:display
 | 
			
		||||
 * @param[in]   enable      0:disable, 1:enable
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void dvp_set_output_enable(dvp_output_mode_t index, int enable);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set sccb clock rate
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   clk_rate       Sccb clock rate
 | 
			
		||||
 *
 | 
			
		||||
 * @return      The real sccb clock rate
 | 
			
		||||
 */
 | 
			
		||||
uint32_t dvp_sccb_set_clk_rate(uint32_t clk_rate);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set xclk rate
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   clk_rate       xclk rate
 | 
			
		||||
 *
 | 
			
		||||
 * @return      The real xclk rate
 | 
			
		||||
 */
 | 
			
		||||
uint32_t dvp_set_xclk_rate(uint32_t xclk_rate);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* __DVP_H__ */
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,425 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 font.h
 | 
			
		||||
* @brief add from Canaan k210 SDK
 | 
			
		||||
*                https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __FONT_H__
 | 
			
		||||
#define __FONT_H__ 	   
 | 
			
		||||
//ASCII char table
 | 
			
		||||
//offset 32 
 | 
			
		||||
//ASCII char : !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
 | 
			
		||||
//bytes of a single char : (size/8+((size%8)?1:0))*(size/2), size : (12/16/24/32...) code table size
 | 
			
		||||
 | 
			
		||||
//12*12 ASCII code
 | 
			
		||||
const unsigned char asc2_1206[95][12]={
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x3F,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
 | 
			
		||||
{0x00,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x40,0x00,0x00,0x00},/*""",2*/
 | 
			
		||||
{0x09,0x00,0x0B,0xC0,0x3D,0x00,0x0B,0xC0,0x3D,0x00,0x09,0x00},/*"#",3*/
 | 
			
		||||
{0x18,0xC0,0x24,0x40,0x7F,0xE0,0x22,0x40,0x31,0x80,0x00,0x00},/*"$",4*/
 | 
			
		||||
{0x18,0x00,0x24,0xC0,0x1B,0x00,0x0D,0x80,0x32,0x40,0x01,0x80},/*"%",5*/
 | 
			
		||||
{0x03,0x80,0x1C,0x40,0x27,0x40,0x1C,0x80,0x07,0x40,0x00,0x40},/*"&",6*/
 | 
			
		||||
{0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x40,0x20},/*"(",8*/
 | 
			
		||||
{0x00,0x00,0x40,0x20,0x20,0x40,0x1F,0x80,0x00,0x00,0x00,0x00},/*")",9*/
 | 
			
		||||
{0x09,0x00,0x06,0x00,0x1F,0x80,0x06,0x00,0x09,0x00,0x00,0x00},/*"*",10*/
 | 
			
		||||
{0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x00,0x00},/*"+",11*/
 | 
			
		||||
{0x00,0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
 | 
			
		||||
{0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00},/*"-",13*/
 | 
			
		||||
{0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
 | 
			
		||||
{0x00,0x20,0x01,0xC0,0x06,0x00,0x38,0x00,0x40,0x00,0x00,0x00},/*"/",15*/
 | 
			
		||||
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"0",16*/
 | 
			
		||||
{0x00,0x00,0x10,0x40,0x3F,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"1",17*/
 | 
			
		||||
{0x18,0xC0,0x21,0x40,0x22,0x40,0x24,0x40,0x18,0x40,0x00,0x00},/*"2",18*/
 | 
			
		||||
{0x10,0x80,0x20,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"3",19*/
 | 
			
		||||
{0x02,0x00,0x0D,0x00,0x11,0x00,0x3F,0xC0,0x01,0x40,0x00,0x00},/*"4",20*/
 | 
			
		||||
{0x3C,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x23,0x80,0x00,0x00},/*"5",21*/
 | 
			
		||||
{0x1F,0x80,0x24,0x40,0x24,0x40,0x34,0x40,0x03,0x80,0x00,0x00},/*"6",22*/
 | 
			
		||||
{0x30,0x00,0x20,0x00,0x27,0xC0,0x38,0x00,0x20,0x00,0x00,0x00},/*"7",23*/
 | 
			
		||||
{0x1B,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"8",24*/
 | 
			
		||||
{0x1C,0x00,0x22,0xC0,0x22,0x40,0x22,0x40,0x1F,0x80,0x00,0x00},/*"9",25*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
 | 
			
		||||
{0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40},/*"<",28*/
 | 
			
		||||
{0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00},/*"=",29*/
 | 
			
		||||
{0x00,0x00,0x40,0x40,0x20,0x80,0x11,0x00,0x0A,0x00,0x04,0x00},/*">",30*/
 | 
			
		||||
{0x18,0x00,0x20,0x00,0x23,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"?",31*/
 | 
			
		||||
{0x1F,0x80,0x20,0x40,0x27,0x40,0x29,0x40,0x1F,0x40,0x00,0x00},/*"@",32*/
 | 
			
		||||
{0x00,0x40,0x07,0xC0,0x39,0x00,0x0F,0x00,0x01,0xC0,0x00,0x40},/*"A",33*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"B",34*/
 | 
			
		||||
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x30,0x80,0x00,0x00},/*"C",35*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"D",36*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x40,0x30,0xC0,0x00,0x00},/*"E",37*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x00,0x30,0x00,0x00,0x00},/*"F",38*/
 | 
			
		||||
{0x0F,0x00,0x10,0x80,0x20,0x40,0x22,0x40,0x33,0x80,0x02,0x00},/*"G",39*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x04,0x00,0x04,0x00,0x3F,0xC0,0x20,0x40},/*"H",40*/
 | 
			
		||||
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x00,0x00},/*"I",41*/
 | 
			
		||||
{0x00,0x60,0x20,0x20,0x20,0x20,0x3F,0xC0,0x20,0x00,0x20,0x00},/*"J",42*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x0B,0x00,0x30,0xC0,0x20,0x40},/*"K",43*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x00,0x40,0x00,0x40,0x00,0xC0},/*"L",44*/
 | 
			
		||||
{0x3F,0xC0,0x3C,0x00,0x03,0xC0,0x3C,0x00,0x3F,0xC0,0x00,0x00},/*"M",45*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x0C,0x40,0x23,0x00,0x3F,0xC0,0x20,0x00},/*"N",46*/
 | 
			
		||||
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"O",47*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"P",48*/
 | 
			
		||||
{0x1F,0x80,0x21,0x40,0x21,0x40,0x20,0xE0,0x1F,0xA0,0x00,0x00},/*"Q",49*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x26,0x00,0x19,0xC0,0x00,0x40},/*"R",50*/
 | 
			
		||||
{0x18,0xC0,0x24,0x40,0x24,0x40,0x22,0x40,0x31,0x80,0x00,0x00},/*"S",51*/
 | 
			
		||||
{0x30,0x00,0x20,0x40,0x3F,0xC0,0x20,0x40,0x30,0x00,0x00,0x00},/*"T",52*/
 | 
			
		||||
{0x20,0x00,0x3F,0x80,0x00,0x40,0x00,0x40,0x3F,0x80,0x20,0x00},/*"U",53*/
 | 
			
		||||
{0x20,0x00,0x3E,0x00,0x01,0xC0,0x07,0x00,0x38,0x00,0x20,0x00},/*"V",54*/
 | 
			
		||||
{0x38,0x00,0x07,0xC0,0x3C,0x00,0x07,0xC0,0x38,0x00,0x00,0x00},/*"W",55*/
 | 
			
		||||
{0x20,0x40,0x39,0xC0,0x06,0x00,0x39,0xC0,0x20,0x40,0x00,0x00},/*"X",56*/
 | 
			
		||||
{0x20,0x00,0x38,0x40,0x07,0xC0,0x38,0x40,0x20,0x00,0x00,0x00},/*"Y",57*/
 | 
			
		||||
{0x30,0x40,0x21,0xC0,0x26,0x40,0x38,0x40,0x20,0xC0,0x00,0x00},/*"Z",58*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x7F,0xE0,0x40,0x20,0x40,0x20,0x00,0x00},/*"[",59*/
 | 
			
		||||
{0x00,0x00,0x70,0x00,0x0C,0x00,0x03,0x80,0x00,0x40,0x00,0x00},/*"\",60*/
 | 
			
		||||
{0x00,0x00,0x40,0x20,0x40,0x20,0x7F,0xE0,0x00,0x00,0x00,0x00},/*"]",61*/
 | 
			
		||||
{0x00,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
 | 
			
		||||
{0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10},/*"_",63*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
 | 
			
		||||
{0x00,0x00,0x02,0x80,0x05,0x40,0x05,0x40,0x03,0xC0,0x00,0x40},/*"a",65*/
 | 
			
		||||
{0x20,0x00,0x3F,0xC0,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"b",66*/
 | 
			
		||||
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x06,0x40,0x00,0x00},/*"c",67*/
 | 
			
		||||
{0x00,0x00,0x03,0x80,0x04,0x40,0x24,0x40,0x3F,0xC0,0x00,0x40},/*"d",68*/
 | 
			
		||||
{0x00,0x00,0x03,0x80,0x05,0x40,0x05,0x40,0x03,0x40,0x00,0x00},/*"e",69*/
 | 
			
		||||
{0x00,0x00,0x04,0x40,0x1F,0xC0,0x24,0x40,0x24,0x40,0x20,0x00},/*"f",70*/
 | 
			
		||||
{0x00,0x00,0x02,0xE0,0x05,0x50,0x05,0x50,0x06,0x50,0x04,0x20},/*"g",71*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"h",72*/
 | 
			
		||||
{0x00,0x00,0x04,0x40,0x27,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"i",73*/
 | 
			
		||||
{0x00,0x10,0x00,0x10,0x04,0x10,0x27,0xE0,0x00,0x00,0x00,0x00},/*"j",74*/
 | 
			
		||||
{0x20,0x40,0x3F,0xC0,0x01,0x40,0x07,0x00,0x04,0xC0,0x04,0x40},/*"k",75*/
 | 
			
		||||
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x00,0x40,0x00,0x40,0x00,0x00},/*"l",76*/
 | 
			
		||||
{0x07,0xC0,0x04,0x00,0x07,0xC0,0x04,0x00,0x03,0xC0,0x00,0x00},/*"m",77*/
 | 
			
		||||
{0x04,0x40,0x07,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"n",78*/
 | 
			
		||||
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"o",79*/
 | 
			
		||||
{0x04,0x10,0x07,0xF0,0x04,0x50,0x04,0x40,0x03,0x80,0x00,0x00},/*"p",80*/
 | 
			
		||||
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x50,0x07,0xF0,0x00,0x10},/*"q",81*/
 | 
			
		||||
{0x04,0x40,0x07,0xC0,0x02,0x40,0x04,0x00,0x04,0x00,0x00,0x00},/*"r",82*/
 | 
			
		||||
{0x00,0x00,0x06,0x40,0x05,0x40,0x05,0x40,0x04,0xC0,0x00,0x00},/*"s",83*/
 | 
			
		||||
{0x00,0x00,0x04,0x00,0x1F,0x80,0x04,0x40,0x00,0x40,0x00,0x00},/*"t",84*/
 | 
			
		||||
{0x04,0x00,0x07,0x80,0x00,0x40,0x04,0x40,0x07,0xC0,0x00,0x40},/*"u",85*/
 | 
			
		||||
{0x04,0x00,0x07,0x00,0x04,0xC0,0x01,0x80,0x06,0x00,0x04,0x00},/*"v",86*/
 | 
			
		||||
{0x06,0x00,0x01,0xC0,0x07,0x00,0x01,0xC0,0x06,0x00,0x00,0x00},/*"w",87*/
 | 
			
		||||
{0x04,0x40,0x06,0xC0,0x01,0x00,0x06,0xC0,0x04,0x40,0x00,0x00},/*"x",88*/
 | 
			
		||||
{0x04,0x10,0x07,0x10,0x04,0xE0,0x01,0x80,0x06,0x00,0x04,0x00},/*"y",89*/
 | 
			
		||||
{0x00,0x00,0x04,0x40,0x05,0xC0,0x06,0x40,0x04,0x40,0x00,0x00},/*"z",90*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x04,0x00,0x7B,0xE0,0x40,0x20,0x00,0x00},/*"{",91*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x00,0x00},/*"|",92*/
 | 
			
		||||
{0x00,0x00,0x40,0x20,0x7B,0xE0,0x04,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
 | 
			
		||||
{0x40,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x40,0x00},/*"~",94*/
 | 
			
		||||
};  
 | 
			
		||||
//16*16 ASCII鐎涙顑侀梿鍡欏仯闂冿拷
 | 
			
		||||
const unsigned char asc2_1608[95][16]={	
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xCC,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
 | 
			
		||||
{0x00,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x00,0x00},/*""",2*/
 | 
			
		||||
{0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x00,0x00},/*"#",3*/
 | 
			
		||||
{0x00,0x00,0x0E,0x18,0x11,0x04,0x3F,0xFF,0x10,0x84,0x0C,0x78,0x00,0x00,0x00,0x00},/*"$",4*/
 | 
			
		||||
{0x0F,0x00,0x10,0x84,0x0F,0x38,0x00,0xC0,0x07,0x78,0x18,0x84,0x00,0x78,0x00,0x00},/*"%",5*/
 | 
			
		||||
{0x00,0x78,0x0F,0x84,0x10,0xC4,0x11,0x24,0x0E,0x98,0x00,0xE4,0x00,0x84,0x00,0x08},/*"&",6*/
 | 
			
		||||
{0x08,0x00,0x68,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x18,0x18,0x20,0x04,0x40,0x02,0x00,0x00},/*"(",8*/
 | 
			
		||||
{0x00,0x00,0x40,0x02,0x20,0x04,0x18,0x18,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/
 | 
			
		||||
{0x02,0x40,0x02,0x40,0x01,0x80,0x0F,0xF0,0x01,0x80,0x02,0x40,0x02,0x40,0x00,0x00},/*"*",10*/
 | 
			
		||||
{0x00,0x80,0x00,0x80,0x00,0x80,0x0F,0xF8,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00},/*"+",11*/
 | 
			
		||||
{0x00,0x01,0x00,0x0D,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
 | 
			
		||||
{0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80},/*"-",13*/
 | 
			
		||||
{0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
 | 
			
		||||
{0x00,0x00,0x00,0x06,0x00,0x18,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00},/*"/",15*/
 | 
			
		||||
{0x00,0x00,0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"0",16*/
 | 
			
		||||
{0x00,0x00,0x08,0x04,0x08,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"1",17*/
 | 
			
		||||
{0x00,0x00,0x0E,0x0C,0x10,0x14,0x10,0x24,0x10,0x44,0x11,0x84,0x0E,0x0C,0x00,0x00},/*"2",18*/
 | 
			
		||||
{0x00,0x00,0x0C,0x18,0x10,0x04,0x11,0x04,0x11,0x04,0x12,0x88,0x0C,0x70,0x00,0x00},/*"3",19*/
 | 
			
		||||
{0x00,0x00,0x00,0xE0,0x03,0x20,0x04,0x24,0x08,0x24,0x1F,0xFC,0x00,0x24,0x00,0x00},/*"4",20*/
 | 
			
		||||
{0x00,0x00,0x1F,0x98,0x10,0x84,0x11,0x04,0x11,0x04,0x10,0x88,0x10,0x70,0x00,0x00},/*"5",21*/
 | 
			
		||||
{0x00,0x00,0x07,0xF0,0x08,0x88,0x11,0x04,0x11,0x04,0x18,0x88,0x00,0x70,0x00,0x00},/*"6",22*/
 | 
			
		||||
{0x00,0x00,0x1C,0x00,0x10,0x00,0x10,0xFC,0x13,0x00,0x1C,0x00,0x10,0x00,0x00,0x00},/*"7",23*/
 | 
			
		||||
{0x00,0x00,0x0E,0x38,0x11,0x44,0x10,0x84,0x10,0x84,0x11,0x44,0x0E,0x38,0x00,0x00},/*"8",24*/
 | 
			
		||||
{0x00,0x00,0x07,0x00,0x08,0x8C,0x10,0x44,0x10,0x44,0x08,0x88,0x07,0xF0,0x00,0x00},/*"9",25*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
 | 
			
		||||
{0x00,0x00,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x08,0x08,0x10,0x04,0x00,0x00},/*"<",28*/
 | 
			
		||||
{0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x00,0x00},/*"=",29*/
 | 
			
		||||
{0x00,0x00,0x10,0x04,0x08,0x08,0x04,0x10,0x02,0x20,0x01,0x40,0x00,0x80,0x00,0x00},/*">",30*/
 | 
			
		||||
{0x00,0x00,0x0E,0x00,0x12,0x00,0x10,0x0C,0x10,0x6C,0x10,0x80,0x0F,0x00,0x00,0x00},/*"?",31*/
 | 
			
		||||
{0x03,0xE0,0x0C,0x18,0x13,0xE4,0x14,0x24,0x17,0xC4,0x08,0x28,0x07,0xD0,0x00,0x00},/*"@",32*/
 | 
			
		||||
{0x00,0x04,0x00,0x3C,0x03,0xC4,0x1C,0x40,0x07,0x40,0x00,0xE4,0x00,0x1C,0x00,0x04},/*"A",33*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x11,0x04,0x0E,0x88,0x00,0x70,0x00,0x00},/*"B",34*/
 | 
			
		||||
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0x08,0x1C,0x10,0x00,0x00},/*"C",35*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"D",36*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x17,0xC4,0x10,0x04,0x08,0x18,0x00,0x00},/*"E",37*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x17,0xC0,0x10,0x00,0x08,0x00,0x00,0x00},/*"F",38*/
 | 
			
		||||
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x44,0x1C,0x78,0x00,0x40,0x00,0x00},/*"G",39*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x00,0x80,0x00,0x80,0x10,0x84,0x1F,0xFC,0x10,0x04},/*"H",40*/
 | 
			
		||||
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x00,0x00,0x00,0x00},/*"I",41*/
 | 
			
		||||
{0x00,0x03,0x00,0x01,0x10,0x01,0x10,0x01,0x1F,0xFE,0x10,0x00,0x10,0x00,0x00,0x00},/*"J",42*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x03,0x80,0x14,0x64,0x18,0x1C,0x10,0x04,0x00,0x00},/*"K",43*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0C,0x00,0x00},/*"L",44*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x1F,0xFC,0x10,0x04,0x00,0x00},/*"M",45*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x0C,0x04,0x03,0x00,0x00,0xE0,0x10,0x18,0x1F,0xFC,0x10,0x00},/*"N",46*/
 | 
			
		||||
{0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"O",47*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x10,0x80,0x10,0x80,0x10,0x80,0x0F,0x00,0x00,0x00},/*"P",48*/
 | 
			
		||||
{0x07,0xF0,0x08,0x18,0x10,0x24,0x10,0x24,0x10,0x1C,0x08,0x0A,0x07,0xF2,0x00,0x00},/*"Q",49*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x11,0xC0,0x11,0x30,0x0E,0x0C,0x00,0x04},/*"R",50*/
 | 
			
		||||
{0x00,0x00,0x0E,0x1C,0x11,0x04,0x10,0x84,0x10,0x84,0x10,0x44,0x1C,0x38,0x00,0x00},/*"S",51*/
 | 
			
		||||
{0x18,0x00,0x10,0x00,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x00,0x18,0x00,0x00,0x00},/*"T",52*/
 | 
			
		||||
{0x10,0x00,0x1F,0xF8,0x10,0x04,0x00,0x04,0x00,0x04,0x10,0x04,0x1F,0xF8,0x10,0x00},/*"U",53*/
 | 
			
		||||
{0x10,0x00,0x1E,0x00,0x11,0xE0,0x00,0x1C,0x00,0x70,0x13,0x80,0x1C,0x00,0x10,0x00},/*"V",54*/
 | 
			
		||||
{0x1F,0xC0,0x10,0x3C,0x00,0xE0,0x1F,0x00,0x00,0xE0,0x10,0x3C,0x1F,0xC0,0x00,0x00},/*"W",55*/
 | 
			
		||||
{0x10,0x04,0x18,0x0C,0x16,0x34,0x01,0xC0,0x01,0xC0,0x16,0x34,0x18,0x0C,0x10,0x04},/*"X",56*/
 | 
			
		||||
{0x10,0x00,0x1C,0x00,0x13,0x04,0x00,0xFC,0x13,0x04,0x1C,0x00,0x10,0x00,0x00,0x00},/*"Y",57*/
 | 
			
		||||
{0x08,0x04,0x10,0x1C,0x10,0x64,0x10,0x84,0x13,0x04,0x1C,0x04,0x10,0x18,0x00,0x00},/*"Z",58*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFE,0x40,0x02,0x40,0x02,0x40,0x02,0x00,0x00},/*"[",59*/
 | 
			
		||||
{0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x80,0x00,0x60,0x00,0x1C,0x00,0x03,0x00,0x00},/*"\",60*/
 | 
			
		||||
{0x00,0x00,0x40,0x02,0x40,0x02,0x40,0x02,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00},/*"^",62*/
 | 
			
		||||
{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01},/*"_",63*/
 | 
			
		||||
{0x00,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
 | 
			
		||||
{0x00,0x00,0x00,0x98,0x01,0x24,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xFC,0x00,0x04},/*"a",65*/
 | 
			
		||||
{0x10,0x00,0x1F,0xFC,0x00,0x88,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"b",66*/
 | 
			
		||||
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x00},/*"c",67*/
 | 
			
		||||
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x11,0x08,0x1F,0xFC,0x00,0x04},/*"d",68*/
 | 
			
		||||
{0x00,0x00,0x00,0xF8,0x01,0x44,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xC8,0x00,0x00},/*"e",69*/
 | 
			
		||||
{0x00,0x00,0x01,0x04,0x01,0x04,0x0F,0xFC,0x11,0x04,0x11,0x04,0x11,0x00,0x18,0x00},/*"f",70*/
 | 
			
		||||
{0x00,0x00,0x00,0xD6,0x01,0x29,0x01,0x29,0x01,0x29,0x01,0xC9,0x01,0x06,0x00,0x00},/*"g",71*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"h",72*/
 | 
			
		||||
{0x00,0x00,0x01,0x04,0x19,0x04,0x19,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"i",73*/
 | 
			
		||||
{0x00,0x00,0x00,0x03,0x00,0x01,0x01,0x01,0x19,0x01,0x19,0xFE,0x00,0x00,0x00,0x00},/*"j",74*/
 | 
			
		||||
{0x10,0x04,0x1F,0xFC,0x00,0x24,0x00,0x40,0x01,0xB4,0x01,0x0C,0x01,0x04,0x00,0x00},/*"k",75*/
 | 
			
		||||
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"l",76*/
 | 
			
		||||
{0x01,0x04,0x01,0xFC,0x01,0x04,0x01,0x00,0x01,0xFC,0x01,0x04,0x01,0x00,0x00,0xFC},/*"m",77*/
 | 
			
		||||
{0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"n",78*/
 | 
			
		||||
{0x00,0x00,0x00,0xF8,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0xF8,0x00,0x00},/*"o",79*/
 | 
			
		||||
{0x01,0x01,0x01,0xFF,0x00,0x85,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"p",80*/
 | 
			
		||||
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x05,0x01,0xFF,0x00,0x01},/*"q",81*/
 | 
			
		||||
{0x01,0x04,0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x04,0x01,0x00,0x01,0x80,0x00,0x00},/*"r",82*/
 | 
			
		||||
{0x00,0x00,0x00,0xCC,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x98,0x00,0x00},/*"s",83*/
 | 
			
		||||
{0x00,0x00,0x01,0x00,0x01,0x00,0x07,0xF8,0x01,0x04,0x01,0x04,0x00,0x00,0x00,0x00},/*"t",84*/
 | 
			
		||||
{0x01,0x00,0x01,0xF8,0x00,0x04,0x00,0x04,0x00,0x04,0x01,0x08,0x01,0xFC,0x00,0x04},/*"u",85*/
 | 
			
		||||
{0x01,0x00,0x01,0x80,0x01,0x70,0x00,0x0C,0x00,0x10,0x01,0x60,0x01,0x80,0x01,0x00},/*"v",86*/
 | 
			
		||||
{0x01,0xF0,0x01,0x0C,0x00,0x30,0x01,0xC0,0x00,0x30,0x01,0x0C,0x01,0xF0,0x01,0x00},/*"w",87*/
 | 
			
		||||
{0x00,0x00,0x01,0x04,0x01,0x8C,0x00,0x74,0x01,0x70,0x01,0x8C,0x01,0x04,0x00,0x00},/*"x",88*/
 | 
			
		||||
{0x01,0x01,0x01,0x81,0x01,0x71,0x00,0x0E,0x00,0x18,0x01,0x60,0x01,0x80,0x01,0x00},/*"y",89*/
 | 
			
		||||
{0x00,0x00,0x01,0x84,0x01,0x0C,0x01,0x34,0x01,0x44,0x01,0x84,0x01,0x0C,0x00,0x00},/*"z",90*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x3E,0xFC,0x40,0x02,0x40,0x02},/*"{",91*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/
 | 
			
		||||
{0x00,0x00,0x40,0x02,0x40,0x02,0x3E,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
 | 
			
		||||
{0x00,0x00,0x60,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x20,0x00},/*"~",94*/
 | 
			
		||||
};  
 | 
			
		||||
//24*24 ASCII code
 | 
			
		||||
const unsigned char asc2_2412[95][36]={	  
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0x0F,0xFE,0x38,0x0F,0x80,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x38,0x00,0x00,0x31,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x38,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*""",2*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x61,0x80,0x00,0x67,0xF8,0x07,0xF9,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x67,0xF8,0x07,0xF9,0x80,0x00,0x61,0x80,0x00,0x00,0x00},/*"#",3*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0xE0,0x03,0xE0,0xF0,0x06,0x30,0x08,0x04,0x18,0x08,0x1F,0xFF,0xFE,0x04,0x0E,0x08,0x07,0x87,0xF0,0x03,0x81,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*"$",4*/
 | 
			
		||||
{0x01,0xF0,0x00,0x06,0x0C,0x00,0x04,0x04,0x08,0x06,0x0C,0x70,0x01,0xF9,0xC0,0x00,0x0E,0x00,0x00,0x3B,0xE0,0x00,0xEC,0x18,0x07,0x08,0x08,0x04,0x0C,0x18,0x00,0x03,0xE0,0x00,0x00,0x00},/*"%",5*/
 | 
			
		||||
{0x00,0x01,0xE0,0x00,0x07,0xF0,0x03,0xF8,0x18,0x04,0x1C,0x08,0x04,0x17,0x08,0x07,0xE1,0xD0,0x03,0xC0,0xE0,0x00,0x23,0xB0,0x00,0x3C,0x08,0x00,0x20,0x08,0x00,0x00,0x10,0x00,0x00,0x00},/*"&",6*/
 | 
			
		||||
{0x00,0x00,0x00,0x01,0x00,0x00,0x31,0x00,0x00,0x32,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0xFF,0xC0,0x07,0x80,0xF0,0x0C,0x00,0x18,0x10,0x00,0x04,0x20,0x00,0x02,0x00,0x00,0x00},/*"(",8*/
 | 
			
		||||
{0x00,0x00,0x00,0x20,0x00,0x02,0x10,0x00,0x04,0x0C,0x00,0x18,0x07,0x80,0xF0,0x01,0xFF,0xC0,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x42,0x00,0x00,0x66,0x00,0x00,0x66,0x00,0x00,0x3C,0x00,0x00,0x18,0x00,0x03,0xFF,0xC0,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x66,0x00,0x00,0x66,0x00,0x00,0x42,0x00},/*"*",10*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x01,0xFF,0xC0,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00},/*"+",11*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x31,0x00,0x00,0x32,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00},/*"-",13*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x1C,0x00,0x00,0x70,0x00,0x01,0x80,0x00,0x0E,0x00,0x00,0x38,0x00,0x00,0xC0,0x00,0x07,0x00,0x00,0x1C,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*"/",15*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x03,0x80,0x70,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"0",16*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x08,0x01,0x00,0x08,0x01,0x00,0x08,0x03,0xFF,0xF8,0x07,0xFF,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"1",17*/
 | 
			
		||||
{0x00,0x00,0x00,0x01,0xC0,0x38,0x02,0xC0,0x58,0x04,0x00,0x98,0x04,0x01,0x18,0x04,0x02,0x18,0x04,0x04,0x18,0x06,0x1C,0x18,0x03,0xF8,0x18,0x01,0xE0,0xF8,0x00,0x00,0x00,0x00,0x00,0x00},/*"2",18*/
 | 
			
		||||
{0x00,0x00,0x00,0x01,0xC0,0xE0,0x03,0xC0,0xF0,0x04,0x00,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x06,0x18,0x08,0x03,0xF4,0x18,0x01,0xE7,0xF0,0x00,0x01,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*"3",19*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x0D,0x00,0x00,0x11,0x00,0x00,0x61,0x00,0x00,0x81,0x08,0x03,0x01,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x00,0x00},/*"4",20*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0xFC,0xD0,0x06,0x08,0x08,0x06,0x10,0x08,0x06,0x10,0x08,0x06,0x10,0x08,0x06,0x18,0x38,0x06,0x0F,0xF0,0x06,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00},/*"5",21*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x84,0x30,0x02,0x08,0x18,0x04,0x10,0x08,0x04,0x10,0x08,0x04,0x10,0x08,0x07,0x18,0x10,0x03,0x0F,0xF0,0x00,0x07,0xC0,0x00,0x00,0x00},/*"6",22*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x00,0x07,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0xF8,0x06,0x07,0xF8,0x06,0x18,0x00,0x06,0xE0,0x00,0x07,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00},/*"7",23*/
 | 
			
		||||
{0x00,0x00,0x00,0x01,0xE1,0xE0,0x03,0xF7,0xF0,0x06,0x34,0x10,0x04,0x18,0x08,0x04,0x18,0x08,0x04,0x0C,0x08,0x04,0x0C,0x08,0x06,0x16,0x18,0x03,0xF3,0xF0,0x01,0xC1,0xE0,0x00,0x00,0x00},/*"8",24*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0xF8,0x00,0x03,0xFC,0x30,0x03,0x06,0x38,0x04,0x02,0x08,0x04,0x02,0x08,0x04,0x02,0x08,0x04,0x04,0x10,0x03,0x08,0xF0,0x01,0xFF,0xC0,0x00,0x7F,0x00,0x00,0x00,0x00},/*"9",25*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x38,0x00,0x70,0x38,0x00,0x70,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x1A,0x00,0x30,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x14,0x00,0x00,0x22,0x00,0x00,0x41,0x00,0x00,0x80,0x80,0x01,0x00,0x40,0x02,0x00,0x20,0x04,0x00,0x10,0x08,0x00,0x08,0x00,0x00,0x00},/*"<",28*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x00,0x00},/*"=",29*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x04,0x00,0x10,0x02,0x00,0x20,0x01,0x00,0x40,0x00,0x80,0x80,0x00,0x41,0x00,0x00,0x22,0x00,0x00,0x14,0x00,0x00,0x08,0x00,0x00,0x00,0x00},/*">",30*/
 | 
			
		||||
{0x00,0x00,0x00,0x03,0xC0,0x00,0x04,0xC0,0x00,0x04,0x00,0x00,0x08,0x00,0x38,0x08,0x0F,0x38,0x08,0x08,0x38,0x08,0x10,0x00,0x0C,0x30,0x00,0x07,0xE0,0x00,0x03,0xC0,0x00,0x00,0x00,0x00},/*"?",31*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x3F,0x80,0x00,0xFF,0xE0,0x03,0x80,0x70,0x02,0x0F,0x10,0x06,0x70,0x88,0x04,0xC0,0x88,0x04,0x83,0x08,0x04,0x7F,0x88,0x02,0xC0,0x90,0x03,0x01,0x20,0x00,0xFE,0x40},/*"@",32*/
 | 
			
		||||
{0x00,0x00,0x08,0x00,0x00,0x18,0x00,0x01,0xF8,0x00,0x3E,0x08,0x01,0xC2,0x00,0x07,0x02,0x00,0x07,0xE2,0x00,0x00,0xFE,0x00,0x00,0x1F,0xC8,0x00,0x01,0xF8,0x00,0x00,0x38,0x00,0x00,0x08},/*"A",33*/
 | 
			
		||||
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x06,0x18,0x08,0x03,0xF4,0x18,0x01,0xE7,0xF0,0x00,0x01,0xE0,0x00,0x00,0x00},/*"B",34*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x02,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x10,0x06,0x00,0x20,0x07,0x80,0xC0,0x00,0x00,0x00},/*"C",35*/
 | 
			
		||||
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x18,0x02,0x00,0x10,0x03,0x80,0x70,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"D",36*/
 | 
			
		||||
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x3E,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x01,0x00,0x60,0x00,0x00,0x00},/*"E",37*/
 | 
			
		||||
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x00,0x04,0x08,0x00,0x04,0x08,0x00,0x04,0x3E,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00},/*"F",38*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x02,0x08,0x04,0x02,0x08,0x02,0x03,0xF0,0x07,0x83,0xF0,0x00,0x02,0x00,0x00,0x02,0x00},/*"G",39*/
 | 
			
		||||
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x04,0x08,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08},/*"H",40*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"I",41*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x07,0x00,0x00,0x01,0x04,0x00,0x01,0x04,0x00,0x01,0x04,0x00,0x03,0x07,0xFF,0xFE,0x07,0xFF,0xFC,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00},/*"J",42*/
 | 
			
		||||
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x0C,0x08,0x00,0x18,0x00,0x00,0x3E,0x00,0x04,0xC7,0x80,0x05,0x03,0xC8,0x06,0x00,0xF8,0x04,0x00,0x38,0x04,0x00,0x18,0x00,0x00,0x08},/*"K",43*/
 | 
			
		||||
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x18,0x00,0x00,0x60,0x00,0x00,0x00},/*"L",44*/
 | 
			
		||||
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0x80,0x08,0x07,0xFC,0x00,0x00,0x7F,0xC0,0x00,0x03,0xF8,0x00,0x07,0xC0,0x00,0x78,0x00,0x07,0x80,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08},/*"M",45*/
 | 
			
		||||
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0x00,0x08,0x03,0xC0,0x00,0x00,0xE0,0x00,0x00,0x38,0x00,0x00,0x1E,0x00,0x00,0x07,0x00,0x00,0x01,0xC0,0x04,0x00,0xF0,0x07,0xFF,0xF8,0x04,0x00,0x00},/*"N",46*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x03,0x00,0x30,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"O",47*/
 | 
			
		||||
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x04,0x08,0x04,0x04,0x00,0x04,0x04,0x00,0x04,0x04,0x00,0x04,0x04,0x00,0x06,0x0C,0x00,0x03,0xF8,0x00,0x01,0xF0,0x00,0x00,0x00,0x00},/*"P",48*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x88,0x04,0x00,0x88,0x04,0x00,0xC8,0x06,0x00,0x3C,0x03,0x00,0x3E,0x01,0xFF,0xE6,0x00,0x7F,0x84,0x00,0x00,0x00},/*"Q",49*/
 | 
			
		||||
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x00,0x04,0x0C,0x00,0x04,0x0F,0x00,0x04,0x0B,0xC0,0x06,0x10,0xF0,0x03,0xF0,0x38,0x01,0xE0,0x08,0x00,0x00,0x08},/*"R",50*/
 | 
			
		||||
{0x00,0x00,0x00,0x01,0xE0,0xF8,0x03,0xF0,0x30,0x06,0x30,0x10,0x04,0x18,0x08,0x04,0x18,0x08,0x04,0x0C,0x08,0x04,0x0C,0x08,0x02,0x06,0x18,0x02,0x07,0xF0,0x07,0x81,0xE0,0x00,0x00,0x00},/*"S",51*/
 | 
			
		||||
{0x01,0x80,0x00,0x06,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x00,0x04,0x00,0x00,0x06,0x00,0x00,0x01,0x80,0x00},/*"T",52*/
 | 
			
		||||
{0x04,0x00,0x00,0x07,0xFF,0xE0,0x07,0xFF,0xF0,0x04,0x00,0x18,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x04,0x00,0x10,0x07,0xFF,0xE0,0x04,0x00,0x00},/*"U",53*/
 | 
			
		||||
{0x04,0x00,0x00,0x06,0x00,0x00,0x07,0xE0,0x00,0x07,0xFE,0x00,0x04,0x1F,0xE0,0x00,0x01,0xF8,0x00,0x00,0x38,0x00,0x01,0xE0,0x04,0x3E,0x00,0x07,0xC0,0x00,0x06,0x00,0x00,0x04,0x00,0x00},/*"V",54*/
 | 
			
		||||
{0x04,0x00,0x00,0x07,0xE0,0x00,0x07,0xFF,0xC0,0x04,0x1F,0xF8,0x00,0x07,0xC0,0x07,0xF8,0x00,0x07,0xFF,0x80,0x04,0x3F,0xF8,0x00,0x07,0xC0,0x04,0xF8,0x00,0x07,0x00,0x00,0x04,0x00,0x00},/*"W",55*/
 | 
			
		||||
{0x00,0x00,0x00,0x04,0x00,0x08,0x06,0x00,0x18,0x07,0xC0,0x78,0x05,0xF1,0xC8,0x00,0x3E,0x00,0x00,0x1F,0x80,0x04,0x63,0xE8,0x07,0x80,0xF8,0x06,0x00,0x18,0x04,0x00,0x08,0x00,0x00,0x00},/*"X",56*/
 | 
			
		||||
{0x04,0x00,0x00,0x06,0x00,0x00,0x07,0x80,0x00,0x07,0xE0,0x08,0x04,0x7C,0x08,0x00,0x1F,0xF8,0x00,0x07,0xF8,0x00,0x18,0x08,0x04,0xE0,0x08,0x07,0x00,0x00,0x06,0x00,0x00,0x04,0x00,0x00},/*"Y",57*/
 | 
			
		||||
{0x00,0x00,0x00,0x01,0x00,0x08,0x06,0x00,0x38,0x04,0x00,0xF8,0x04,0x03,0xE8,0x04,0x0F,0x08,0x04,0x7C,0x08,0x05,0xF0,0x08,0x07,0xC0,0x08,0x07,0x00,0x18,0x04,0x00,0x60,0x00,0x00,0x00},/*"Z",58*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0xFE,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x00,0x00,0x00},/*"[",59*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x07,0x00,0x00,0x00,0xC0,0x00,0x00,0x38,0x00,0x00,0x06,0x00,0x00,0x01,0xC0,0x00,0x00,0x30,0x00,0x00,0x0E,0x00,0x00,0x01,0x00,0x00,0x00},/*"\",60*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x3F,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x10,0x00,0x00,0x30,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
 | 
			
		||||
{0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01},/*"_",63*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x19,0xF8,0x00,0x1B,0x18,0x00,0x22,0x08,0x00,0x26,0x08,0x00,0x24,0x08,0x00,0x24,0x10,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x18},/*"a",65*/
 | 
			
		||||
{0x00,0x00,0x00,0x04,0x00,0x00,0x07,0xFF,0xF8,0x0F,0xFF,0xF0,0x00,0x18,0x18,0x00,0x10,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x18,0x00,0x1F,0xF0,0x00,0x0F,0xC0,0x00,0x00,0x00},/*"b",66*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x18,0x30,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x3C,0x08,0x00,0x1C,0x10,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*"c",67*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x38,0x18,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x04,0x10,0x10,0x07,0xFF,0xF8,0x0F,0xFF,0xF0,0x00,0x00,0x10,0x00,0x00,0x00},/*"d",68*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x12,0x30,0x00,0x22,0x18,0x00,0x22,0x08,0x00,0x22,0x08,0x00,0x32,0x08,0x00,0x1E,0x10,0x00,0x0E,0x20,0x00,0x00,0x00},/*"e",69*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x01,0xFF,0xF8,0x03,0xFF,0xF8,0x06,0x20,0x08,0x04,0x20,0x08,0x04,0x20,0x08,0x07,0x20,0x00,0x03,0x00,0x00,0x00,0x00,0x00},/*"f",70*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x6E,0x00,0x1F,0xF3,0x00,0x31,0xB1,0x00,0x20,0xB1,0x00,0x20,0xB1,0x00,0x31,0x91,0x00,0x1F,0x13,0x00,0x2E,0x1E,0x00,0x20,0x0E,0x00,0x30,0x00},/*"g",71*/
 | 
			
		||||
{0x00,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x00},/*"h",72*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x06,0x3F,0xF8,0x06,0x3F,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"i",73*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x20,0x01,0x00,0x20,0x01,0x00,0x20,0x03,0x06,0x3F,0xFE,0x06,0x3F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"j",74*/
 | 
			
		||||
{0x00,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x01,0x88,0x00,0x03,0x00,0x00,0x2F,0xC0,0x00,0x38,0xF8,0x00,0x20,0x38,0x00,0x20,0x08,0x00,0x00,0x08,0x00,0x00,0x00},/*"k",75*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"l",76*/
 | 
			
		||||
{0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x00,0x08},/*"m",77*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x10,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x00},/*"n",78*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x0F,0xF0,0x00,0x18,0x30,0x00,0x30,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x08,0x00,0x18,0x30,0x00,0x0F,0xF0,0x00,0x07,0xC0,0x00,0x00,0x00},/*"o",79*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x20,0x01,0x00,0x3F,0xFF,0x00,0x3F,0xFF,0x00,0x10,0x11,0x00,0x20,0x09,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x38,0x00,0x1F,0xF0,0x00,0x0F,0xC0,0x00,0x00,0x00},/*"p",80*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x38,0x18,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x09,0x00,0x10,0x11,0x00,0x1F,0xFF,0x00,0x3F,0xFF,0x00,0x00,0x01,0x00,0x00,0x00},/*"q",81*/
 | 
			
		||||
{0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x08,0x08,0x00,0x10,0x08,0x00,0x20,0x08,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x00,0x00},/*"r",82*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x78,0x00,0x1E,0x18,0x00,0x33,0x08,0x00,0x23,0x08,0x00,0x21,0x08,0x00,0x21,0x88,0x00,0x21,0x98,0x00,0x30,0xF0,0x00,0x38,0x60,0x00,0x00,0x00},/*"s",83*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0xFF,0xF0,0x03,0xFF,0xF8,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00},/*"t",84*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x3F,0xF0,0x00,0x7F,0xF8,0x00,0x00,0x18,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x20,0x10,0x00,0x3F,0xF8,0x00,0x7F,0xF0,0x00,0x00,0x10,0x00,0x00,0x00},/*"u",85*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x3C,0x00,0x00,0x3F,0x80,0x00,0x23,0xF0,0x00,0x00,0x78,0x00,0x00,0x70,0x00,0x23,0x80,0x00,0x3C,0x00,0x00,0x30,0x00,0x00,0x20,0x00},/*"v",86*/
 | 
			
		||||
{0x00,0x20,0x00,0x00,0x3C,0x00,0x00,0x3F,0xE0,0x00,0x23,0xF8,0x00,0x00,0xE0,0x00,0x27,0x00,0x00,0x3E,0x00,0x00,0x3F,0xE0,0x00,0x21,0xF8,0x00,0x01,0xE0,0x00,0x3E,0x00,0x00,0x20,0x00},/*"w",87*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x38,0x38,0x00,0x3E,0x68,0x00,0x27,0x80,0x00,0x03,0xC8,0x00,0x2C,0xF8,0x00,0x38,0x38,0x00,0x20,0x18,0x00,0x20,0x08,0x00,0x00,0x00},/*"x",88*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x30,0x03,0x00,0x3C,0x01,0x00,0x3F,0x83,0x00,0x23,0xEC,0x00,0x00,0x70,0x00,0x23,0x80,0x00,0x3C,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"y",89*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x08,0x00,0x20,0x38,0x00,0x20,0xF8,0x00,0x23,0xE8,0x00,0x2F,0x88,0x00,0x3E,0x08,0x00,0x38,0x08,0x00,0x20,0x18,0x00,0x00,0x70,0x00,0x00,0x00},/*"z",90*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x14,0x00,0x1F,0xF7,0xFC,0x30,0x00,0x06,0x20,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00},/*"{",91*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x02,0x30,0x00,0x06,0x1F,0xF7,0xFC,0x00,0x14,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
 | 
			
		||||
{0x00,0x00,0x00,0x18,0x00,0x00,0x60,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x0C,0x00,0x00,0x10,0x00,0x00},/*"~",94*/
 | 
			
		||||
};     
 | 
			
		||||
 | 
			
		||||
//32*32 ASCII code
 | 
			
		||||
const unsigned char asc2_3216[95][128]={
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF0,0x00,0xC0,0x07,0xFF,0xE1,0xE0,0x07,0xF0,0x01,0xE0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x01,0xC0,0x00,0x00,0x07,0x80,0x00,0x00,0x1F,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x1C,0x20,0x00,0x00,0x01,0xC0,0x00,0x00,0x07,0x80,0x00,0x00,0x1F,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0F,0xE0,0x00,0x1F,0xFC,0x00,0x03,0xF8,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0F,0xE0,0x00,0x1F,0xFC,0x00,0x03,0xF8,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x00,0x00,0x00},/*"#",3*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x00,0x78,0x07,0xC0,0x00,0xFC,0x06,0x40,0x01,0x0E,0x00,0x20,0x03,0x07,0x00,0x20,0x02,0x03,0x80,0x20,0x0F,0xFF,0xFF,0xFC,0x02,0x01,0xC0,0x20,0x02,0x00,0xE0,0x60,0x01,0x30,0x70,0x40,0x01,0xF0,0x3F,0x80,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"$",4*/
 | 
			
		||||
{0x00,0xFE,0x00,0x00,0x01,0xFF,0x00,0x00,0x03,0x01,0x80,0x00,0x02,0x00,0x80,0x60,0x03,0x01,0x81,0xC0,0x01,0xFF,0x07,0x00,0x00,0xFE,0x18,0x00,0x00,0x00,0xE0,0x00,0x00,0x03,0xBF,0x00,0x00,0x0C,0xFF,0xC0,0x00,0x71,0x80,0x60,0x01,0xC1,0x00,0x20,0x03,0x01,0x80,0x60,0x00,0x00,0xFF,0xC0,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00},/*"%",5*/
 | 
			
		||||
{0x00,0x00,0x1F,0x00,0x00,0x00,0x7F,0xC0,0x00,0xFC,0xC0,0xC0,0x01,0xFF,0x80,0x60,0x03,0x03,0xE0,0x20,0x02,0x02,0x78,0x20,0x02,0x06,0x1E,0x20,0x03,0xFC,0x07,0x40,0x01,0xF0,0x03,0x80,0x00,0x01,0x03,0xC0,0x00,0x01,0x1C,0x60,0x00,0x01,0xE0,0x20,0x00,0x01,0x00,0x20,0x00,0x01,0x00,0x40,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00},/*"&",6*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x1C,0x60,0x00,0x00,0x1C,0x40,0x00,0x00,0x1F,0x80,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF8,0x00,0x00,0x3F,0xFF,0x00,0x00,0x78,0x07,0xC0,0x01,0xC0,0x00,0xE0,0x03,0x00,0x00,0x30,0x04,0x00,0x00,0x08,0x08,0x00,0x00,0x04,0x10,0x00,0x00,0x02,0x00,0x00,0x00,0x00},/*"(",8*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x02,0x08,0x00,0x00,0x04,0x04,0x00,0x00,0x08,0x03,0x00,0x00,0x30,0x01,0xC0,0x00,0xE0,0x00,0x78,0x07,0xC0,0x00,0x3F,0xFF,0x00,0x00,0x07,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x18,0x00,0x00,0x0E,0x38,0x00,0x00,0x0E,0x38,0x00,0x00,0x06,0x30,0x00,0x00,0x03,0x60,0x00,0x00,0x61,0x43,0x80,0x00,0xFF,0xFF,0x80,0x00,0x61,0x43,0x00,0x00,0x03,0x60,0x00,0x00,0x06,0x30,0x00,0x00,0x0E,0x38,0x00,0x00,0x0E,0x38,0x00,0x00,0x0C,0x18,0x00,0x00,0x00,0x00,0x00},/*"*",10*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x7F,0xFF,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00},/*"+",11*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xE3,0x00,0x00,0x00,0xE2,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00},/*"-",13*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x00,0x03,0x80,0x00,0x00,0x0E,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x00,0x03,0x80,0x00,0x00,0x0E,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x00,0x03,0x80,0x00,0x00,0x0E,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"/",15*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,0x00,0x7F,0xFF,0x00,0x00,0xF0,0x07,0x80,0x01,0x80,0x00,0xC0,0x03,0x00,0x00,0x60,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0x00,0x00,0x60,0x01,0x80,0x00,0xC0,0x00,0xE0,0x03,0x80,0x00,0x7F,0xFF,0x00,0x00,0x0F,0xF8,0x00,0x00,0x00,0x00,0x00},/*"0",16*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x20,0x00,0x80,0x00,0x20,0x00,0x80,0x00,0x20,0x00,0x80,0x00,0x60,0x01,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"1",17*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0xE0,0x00,0x98,0x01,0x60,0x01,0x00,0x02,0x60,0x02,0x00,0x04,0x60,0x02,0x00,0x08,0x60,0x02,0x00,0x10,0x60,0x02,0x00,0x20,0x60,0x02,0x00,0x40,0x60,0x03,0x00,0x80,0x60,0x01,0x83,0x00,0x60,0x01,0xFE,0x00,0xE0,0x00,0x7C,0x07,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"2",18*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x80,0x01,0xF0,0x07,0xC0,0x01,0x00,0x00,0x40,0x02,0x00,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x03,0x03,0x80,0x20,0x01,0x86,0x80,0x40,0x01,0xFC,0xC0,0xC0,0x00,0x78,0x7F,0x80,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"3",19*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x48,0x00,0x00,0x01,0x88,0x00,0x00,0x06,0x08,0x00,0x00,0x0C,0x08,0x10,0x00,0x30,0x08,0x10,0x00,0x40,0x08,0x10,0x01,0xFF,0xFF,0xF0,0x03,0xFF,0xFF,0xF0,0x03,0xFF,0xFF,0xF0,0x00,0x00,0x08,0x10,0x00,0x00,0x08,0x10,0x00,0x00,0x08,0x10,0x00,0x00,0x00,0x00},/*"4",20*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x00,0x1F,0x86,0x40,0x03,0xE1,0x00,0x20,0x03,0x02,0x00,0x20,0x03,0x04,0x00,0x20,0x03,0x04,0x00,0x20,0x03,0x04,0x00,0x20,0x03,0x04,0x00,0x20,0x03,0x06,0x00,0x40,0x03,0x03,0x01,0xC0,0x03,0x01,0xFF,0x80,0x03,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"5",21*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xFC,0x00,0x00,0x3F,0xFF,0x00,0x00,0x70,0xC3,0x80,0x00,0x81,0x80,0xC0,0x01,0x01,0x00,0x60,0x03,0x02,0x00,0x20,0x02,0x02,0x00,0x20,0x02,0x02,0x00,0x20,0x02,0x02,0x00,0x20,0x02,0x03,0x00,0x40,0x01,0xC1,0x80,0xC0,0x00,0xC0,0xFF,0x80,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00},/*"6",22*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0x80,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x07,0xE0,0x03,0x00,0x3F,0xE0,0x03,0x01,0xC0,0x00,0x03,0x06,0x00,0x00,0x03,0x18,0x00,0x00,0x03,0x60,0x00,0x00,0x03,0x80,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"7",23*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x78,0x3F,0x80,0x00,0xFC,0x60,0xC0,0x01,0x8E,0xC0,0x40,0x03,0x07,0x80,0x20,0x02,0x03,0x00,0x20,0x02,0x01,0x80,0x20,0x02,0x01,0x80,0x20,0x02,0x01,0xC0,0x20,0x03,0x01,0xE0,0x40,0x01,0x86,0x70,0xC0,0x00,0xFC,0x3F,0x80,0x00,0x78,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"8",24*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0xFF,0x81,0xC0,0x01,0xC0,0xC1,0xC0,0x01,0x00,0x60,0x20,0x02,0x00,0x20,0x20,0x02,0x00,0x20,0x20,0x02,0x00,0x20,0x20,0x02,0x00,0x20,0x60,0x02,0x00,0x40,0xC0,0x01,0x00,0xC1,0x80,0x00,0xC1,0x8F,0x00,0x00,0x7F,0xFE,0x00,0x00,0x1F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"9",25*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0xC0,0x00,0x07,0x81,0xE0,0x00,0x07,0x81,0xE0,0x00,0x03,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x66,0x00,0x06,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x01,0xC0,0x00,0x00,0x03,0x60,0x00,0x00,0x06,0x30,0x00,0x00,0x0C,0x18,0x00,0x00,0x18,0x0C,0x00,0x00,0x30,0x06,0x00,0x00,0x60,0x03,0x00,0x00,0xC0,0x01,0x80,0x01,0x00,0x00,0x40,0x02,0x00,0x00,0x20,0x04,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"<",28*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x00,0x00,0x00},/*"=",29*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x10,0x02,0x00,0x00,0x20,0x01,0x00,0x00,0x40,0x00,0xC0,0x01,0x80,0x00,0x60,0x03,0x00,0x00,0x30,0x06,0x00,0x00,0x18,0x0C,0x00,0x00,0x0C,0x18,0x00,0x00,0x06,0x30,0x00,0x00,0x03,0x60,0x00,0x00,0x01,0xC0,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*">",30*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x01,0xF8,0x00,0x00,0x02,0x38,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,0xC0,0x04,0x00,0x79,0xE0,0x04,0x00,0x81,0xE0,0x04,0x01,0x00,0xC0,0x04,0x03,0x00,0x00,0x02,0x02,0x00,0x00,0x03,0x06,0x00,0x00,0x01,0xFC,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00},/*"?",31*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,0x00,0x3F,0xFE,0x00,0x00,0x70,0x07,0x80,0x00,0xC0,0x00,0xC0,0x01,0x01,0xF8,0x40,0x03,0x07,0xFC,0x20,0x02,0x1E,0x04,0x20,0x02,0x30,0x08,0x20,0x02,0x20,0x30,0x20,0x02,0x3F,0xFC,0x20,0x01,0x3F,0x04,0x40,0x01,0x80,0x0C,0xC0,0x00,0xE0,0x31,0x80,0x00,0x1F,0xC2,0x00,0x00,0x00,0x00,0x00},/*"@",32*/
 | 
			
		||||
{0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x60,0x00,0x00,0x03,0xE0,0x00,0x00,0x3E,0x20,0x00,0x03,0xE0,0x20,0x00,0x3E,0x20,0x00,0x03,0xE0,0x20,0x00,0x03,0x80,0x20,0x00,0x07,0xFC,0x20,0x00,0x00,0x3F,0xE0,0x00,0x00,0x03,0xFE,0x20,0x00,0x00,0x3F,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"A",33*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x03,0x03,0x00,0x20,0x01,0x86,0x80,0x60,0x01,0xFC,0xC0,0xC0,0x00,0xF8,0x7F,0x80,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00},/*"B",34*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x07,0xF8,0x00,0x00,0x3F,0xFF,0x00,0x00,0x70,0x07,0x80,0x00,0xC0,0x00,0xC0,0x01,0x00,0x00,0x40,0x03,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x01,0x00,0x00,0x40,0x01,0x80,0x00,0xC0,0x03,0xC0,0x01,0x80,0x00,0x30,0x06,0x00,0x00,0x00,0x00,0x00},/*"C",35*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0x00,0x00,0x60,0x01,0x00,0x00,0x40,0x01,0x80,0x00,0xC0,0x00,0xF0,0x07,0x80,0x00,0x7F,0xFE,0x00,0x00,0x0F,0xF8,0x00,0x00,0x00,0x00,0x00},/*"D",36*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x03,0x80,0x20,0x02,0x0F,0xE0,0x20,0x03,0x00,0x00,0x60,0x03,0xC0,0x00,0xE0,0x00,0x60,0x03,0x00,0x00,0x00,0x00,0x00},/*"E",37*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x00,0x02,0x01,0x00,0x00,0x02,0x01,0x00,0x00,0x02,0x01,0x00,0x00,0x02,0x03,0x80,0x00,0x03,0x0F,0xE0,0x00,0x03,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x00,0x60,0x00,0x00},/*"F",38*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x07,0xF8,0x00,0x00,0x3F,0xFE,0x00,0x00,0x70,0x07,0x80,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x40,0x03,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x01,0x00,0x20,0x20,0x01,0x00,0x20,0x40,0x03,0xC0,0x3F,0x80,0x00,0x30,0x3F,0x80,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00},/*"G",39*/
 | 
			
		||||
{0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x80,0x20,0x02,0x00,0x80,0x20,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x02,0x00,0x80,0x20,0x02,0x00,0x80,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"H",40*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"I",41*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x03,0x02,0x00,0x00,0x06,0x03,0xFF,0xFF,0xFC,0x03,0xFF,0xFF,0xF8,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"J",42*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0xC0,0x20,0x02,0x01,0x00,0x20,0x00,0x07,0x80,0x00,0x00,0x0F,0xE0,0x00,0x00,0x30,0xF8,0x00,0x02,0x60,0x3E,0x20,0x03,0x80,0x0F,0x20,0x03,0x00,0x03,0xE0,0x02,0x00,0x00,0xE0,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x20},/*"K",43*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xE0,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00},/*"L",44*/
 | 
			
		||||
{0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xE0,0x00,0x20,0x03,0xFF,0x00,0x20,0x00,0x1F,0xF0,0x00,0x00,0x01,0xFF,0x80,0x00,0x00,0x0F,0xE0,0x00,0x00,0x1E,0x00,0x00,0x03,0xE0,0x00,0x00,0x3E,0x00,0x20,0x03,0xE0,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20},/*"M",45*/
 | 
			
		||||
{0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0x80,0x00,0x20,0x03,0xF0,0x00,0x20,0x00,0xFC,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x01,0xF0,0x00,0x00,0x00,0x7C,0x00,0x02,0x00,0x1F,0x80,0x02,0x00,0x07,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"N",46*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,0x00,0x3F,0xFE,0x00,0x00,0xF0,0x07,0x80,0x01,0x80,0x00,0xC0,0x01,0x00,0x00,0x40,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x01,0x00,0x00,0x40,0x01,0x80,0x00,0xC0,0x00,0xF0,0x03,0x80,0x00,0x3F,0xFE,0x00,0x00,0x0F,0xF8,0x00,0x00,0x00,0x00,0x00},/*"O",47*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x80,0x20,0x02,0x00,0x80,0x20,0x02,0x00,0x80,0x00,0x02,0x00,0x80,0x00,0x02,0x00,0x80,0x00,0x02,0x00,0x80,0x00,0x03,0x01,0x80,0x00,0x01,0x83,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00},/*"P",48*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,0x00,0x7F,0xFF,0x00,0x00,0xF0,0x03,0x80,0x01,0x80,0x01,0xC0,0x01,0x00,0x06,0x40,0x02,0x00,0x04,0x20,0x02,0x00,0x04,0x20,0x02,0x00,0x06,0x20,0x02,0x00,0x03,0xE0,0x01,0x00,0x00,0xF8,0x01,0x80,0x00,0x5C,0x00,0xE0,0x03,0x8C,0x00,0x3F,0xFF,0x0C,0x00,0x0F,0xFC,0x18,0x00,0x00,0x00,0x00},/*"Q",49*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x80,0x00,0x02,0x01,0xE0,0x00,0x02,0x01,0xFC,0x00,0x03,0x03,0x3F,0x80,0x01,0x86,0x07,0xE0,0x01,0xFC,0x00,0xE0,0x00,0xF8,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"R",50*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x06,0x00,0x00,0xFE,0x01,0xE0,0x01,0x86,0x00,0xC0,0x03,0x03,0x00,0x40,0x02,0x03,0x00,0x20,0x02,0x01,0x80,0x20,0x02,0x01,0x80,0x20,0x02,0x01,0xC0,0x20,0x02,0x00,0xC0,0x20,0x01,0x00,0xE0,0x60,0x01,0x80,0x70,0xC0,0x03,0xE0,0x3F,0x80,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00},/*"S",51*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x03,0x80,0x00,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*"T",52*/
 | 
			
		||||
{0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xC0,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x60,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x80,0x03,0xFF,0xFF,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"U",53*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xFC,0x00,0x00,0x02,0x3F,0xC0,0x00,0x00,0x03,0xF8,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x07,0xE0,0x00,0x00,0x07,0x80,0x00,0x00,0x78,0x00,0x02,0x03,0xC0,0x00,0x02,0x3C,0x00,0x00,0x03,0xC0,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00},/*"V",54*/
 | 
			
		||||
{0x02,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xFF,0x80,0x00,0x02,0x3F,0xFE,0x00,0x02,0x00,0x7F,0xE0,0x00,0x00,0x0F,0x00,0x02,0x00,0xF0,0x00,0x03,0xEF,0x00,0x00,0x03,0xFF,0x80,0x00,0x02,0x0F,0xFE,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x1F,0x00,0x02,0x07,0xE0,0x00,0x03,0xF8,0x00,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0x00,0x00},/*"W",55*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0x80,0x00,0xE0,0x03,0xF0,0x03,0x20,0x02,0xFC,0x0C,0x20,0x02,0x1F,0x30,0x00,0x00,0x07,0xC0,0x00,0x00,0x07,0xF0,0x00,0x02,0x18,0x7C,0x00,0x02,0x60,0x1F,0x20,0x03,0x80,0x03,0xE0,0x02,0x00,0x00,0xE0,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"X",56*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xF8,0x00,0x00,0x02,0x3E,0x00,0x20,0x02,0x0F,0xC0,0x20,0x00,0x01,0xFF,0xE0,0x00,0x00,0x7F,0xE0,0x00,0x03,0x80,0x20,0x02,0x1C,0x00,0x20,0x02,0x70,0x00,0x00,0x03,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"Y",57*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x60,0x00,0xE0,0x03,0x80,0x03,0xE0,0x03,0x00,0x0F,0xA0,0x02,0x00,0x3E,0x20,0x02,0x00,0xF8,0x20,0x02,0x03,0xE0,0x20,0x02,0x0F,0x80,0x20,0x02,0x3E,0x00,0x20,0x02,0x78,0x00,0x20,0x03,0xE0,0x00,0x60,0x03,0x80,0x00,0xE0,0x02,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"Z",58*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xFF,0xFF,0xFC,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"[",59*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x07,0x80,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"\",60*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x1F,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
 | 
			
		||||
{0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01},/*"_",63*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x01,0x8F,0xC0,0x00,0x03,0x8C,0x60,0x00,0x06,0x18,0x20,0x00,0x04,0x10,0x20,0x00,0x04,0x10,0x20,0x00,0x04,0x20,0x20,0x00,0x04,0x20,0x40,0x00,0x06,0x20,0x40,0x00,0x03,0xFF,0xC0,0x00,0x01,0xFF,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00},/*"a",65*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xC0,0x00,0x01,0x80,0xC0,0x00,0x02,0x00,0x60,0x00,0x02,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x40,0x00,0x03,0x00,0xC0,0x00,0x01,0xFF,0x80,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00},/*"b",66*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x01,0xFF,0x80,0x00,0x03,0x81,0xC0,0x00,0x02,0x00,0x40,0x00,0x06,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x20,0x00,0x03,0xC0,0x40,0x00,0x01,0xC0,0x80,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"c",67*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x01,0xFF,0x80,0x00,0x03,0x80,0xC0,0x00,0x06,0x00,0x60,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x02,0x04,0x00,0x40,0x02,0x02,0x00,0x80,0x03,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00},/*"d",68*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x01,0xFF,0x80,0x00,0x03,0x11,0xC0,0x00,0x02,0x10,0x40,0x00,0x04,0x10,0x60,0x00,0x04,0x10,0x20,0x00,0x04,0x10,0x20,0x00,0x04,0x10,0x20,0x00,0x06,0x10,0x20,0x00,0x03,0x10,0x40,0x00,0x01,0xF0,0xC0,0x00,0x00,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"e",69*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x7F,0xFF,0xE0,0x01,0xFF,0xFF,0xE0,0x01,0x04,0x00,0x20,0x03,0x04,0x00,0x20,0x02,0x04,0x00,0x20,0x02,0x04,0x00,0x20,0x02,0x04,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0xC0,0x00,0x00,0x01,0xC0,0x00,0x00},/*"f",70*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0xE3,0x3E,0x00,0x03,0xFF,0xC2,0x00,0x02,0x0C,0xC3,0x00,0x04,0x04,0xC1,0x00,0x04,0x04,0xC1,0x00,0x04,0x04,0xC1,0x00,0x04,0x04,0xC1,0x00,0x06,0x0C,0xC1,0x00,0x03,0xF8,0xC3,0x00,0x05,0xF0,0x62,0x00,0x06,0x00,0x7E,0x00,0x06,0x00,0x3C,0x00,0x00,0x00,0x00},/*"g",71*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xE0,0x00,0x01,0x00,0x20,0x00,0x02,0x00,0x20,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x20,0x00,0x03,0xFF,0xE0,0x00,0x01,0xFF,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20},/*"h",72*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x03,0x87,0xFF,0xE0,0x03,0x8F,0xFF,0xE0,0x03,0x80,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"i",73*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x04,0x00,0x01,0x00,0x04,0x00,0x01,0x00,0x04,0x00,0x03,0x00,0x04,0x00,0x06,0x03,0x87,0xFF,0xFC,0x03,0x8F,0xFF,0xF8,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"j",74*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xE0,0x00,0x00,0x08,0x20,0x00,0x00,0x10,0x20,0x00,0x00,0x30,0x00,0x00,0x00,0xFC,0x00,0x00,0x05,0x8E,0x00,0x00,0x07,0x07,0xA0,0x00,0x06,0x01,0xE0,0x00,0x04,0x00,0xE0,0x00,0x04,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"k",75*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"l",76*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x07,0xFF,0xE0,0x00,0x0F,0xFF,0xE0,0x00,0x02,0x00,0x20,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x07,0xFF,0xE0,0x00,0x03,0xFF,0xE0,0x00,0x02,0x00,0x20,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x07,0xFF,0xE0,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"m",77*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x07,0xFF,0xE0,0x00,0x0F,0xFF,0xE0,0x00,0x01,0x00,0x20,0x00,0x02,0x00,0x20,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x20,0x00,0x03,0xFF,0xE0,0x00,0x01,0xFF,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20},/*"n",78*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0xFF,0x80,0x00,0x03,0x81,0xC0,0x00,0x02,0x00,0x40,0x00,0x06,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x03,0x81,0xC0,0x00,0x01,0xFF,0x80,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00},/*"o",79*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x01,0x00,0x04,0x00,0x01,0x00,0x07,0xFF,0xFF,0x00,0x0F,0xFF,0xFF,0x00,0x01,0x00,0xC1,0x00,0x02,0x00,0x41,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x40,0x00,0x03,0x01,0xC0,0x00,0x01,0xFF,0x80,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00},/*"p",80*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x01,0xFF,0x80,0x00,0x03,0x80,0xC0,0x00,0x02,0x00,0x60,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x41,0x00,0x03,0x00,0xC1,0x00,0x03,0xFF,0xFF,0x00,0x07,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01},/*"q",81*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x0F,0xFF,0xE0,0x00,0x0F,0xFF,0xE0,0x00,0x00,0xC0,0x20,0x00,0x01,0x00,0x20,0x00,0x02,0x00,0x20,0x00,0x06,0x00,0x20,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"r",82*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x00,0x01,0xC0,0xE0,0x00,0x03,0xE0,0x40,0x00,0x06,0x30,0x20,0x00,0x04,0x30,0x20,0x00,0x04,0x18,0x20,0x00,0x04,0x18,0x20,0x00,0x04,0x18,0x20,0x00,0x04,0x0C,0x20,0x00,0x02,0x0C,0x60,0x00,0x03,0x07,0xC0,0x00,0x07,0x83,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"s",83*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0xFF,0xFF,0xC0,0x00,0x04,0x00,0x60,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x40,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"t",84*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0xFF,0x80,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x40,0x00,0x04,0x00,0x80,0x00,0x07,0xFF,0xE0,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40},/*"u",85*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x80,0x00,0x00,0x07,0xF0,0x00,0x00,0x04,0xFE,0x00,0x00,0x04,0x1F,0xC0,0x00,0x00,0x03,0xE0,0x00,0x00,0x03,0x80,0x00,0x00,0x1C,0x00,0x00,0x04,0x60,0x00,0x00,0x07,0x80,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"v",86*/
 | 
			
		||||
{0x00,0x04,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x07,0xFC,0x00,0x00,0x04,0x3F,0x80,0x00,0x00,0x03,0xE0,0x00,0x04,0x0F,0x80,0x00,0x06,0xF0,0x00,0x00,0x07,0xF0,0x00,0x00,0x07,0xFF,0x80,0x00,0x04,0x0F,0xE0,0x00,0x00,0x03,0x80,0x00,0x04,0x3C,0x00,0x00,0x07,0xC0,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00},/*"w",87*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x60,0x00,0x07,0x00,0xE0,0x00,0x07,0x83,0x20,0x00,0x07,0xE6,0x00,0x00,0x04,0xF8,0x00,0x00,0x00,0x3C,0x00,0x00,0x04,0x5E,0x20,0x00,0x05,0x87,0xA0,0x00,0x06,0x01,0xE0,0x00,0x04,0x00,0x60,0x00,0x04,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"x",88*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x03,0x00,0x07,0x00,0x03,0x00,0x07,0xE0,0x01,0x00,0x04,0xF8,0x01,0x00,0x04,0x1F,0x02,0x00,0x00,0x07,0xFC,0x00,0x00,0x00,0xE0,0x00,0x00,0x07,0x00,0x00,0x04,0x38,0x00,0x00,0x07,0xC0,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00},/*"y",89*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x60,0x00,0x06,0x00,0xE0,0x00,0x04,0x03,0xE0,0x00,0x04,0x07,0xA0,0x00,0x04,0x0E,0x20,0x00,0x04,0x3C,0x20,0x00,0x04,0x70,0x20,0x00,0x05,0xE0,0x20,0x00,0x07,0x80,0x20,0x00,0x07,0x00,0x60,0x00,0x04,0x00,0xE0,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"z",90*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x01,0x40,0x00,0x07,0xFE,0x3F,0xF8,0x08,0x00,0x00,0x04,0x10,0x00,0x00,0x02,0x10,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"{",91*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x02,0x10,0x00,0x00,0x02,0x08,0x00,0x00,0x04,0x07,0xFE,0x3F,0xF8,0x00,0x01,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
 | 
			
		||||
{0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",94*/
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,178 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 gpio.h
 | 
			
		||||
* @brief add from Canaan k210 SDK
 | 
			
		||||
*                https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __GPIO_H__
 | 
			
		||||
#define __GPIO_H__
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "gpio_common.h"
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Structure for accessing GPIO registers by individual bit
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _gpio_bits
 | 
			
		||||
{
 | 
			
		||||
    uint32_t b0 : 1;
 | 
			
		||||
    uint32_t b1 : 1;
 | 
			
		||||
    uint32_t b2 : 1;
 | 
			
		||||
    uint32_t b3 : 1;
 | 
			
		||||
    uint32_t b4 : 1;
 | 
			
		||||
    uint32_t b5 : 1;
 | 
			
		||||
    uint32_t b6 : 1;
 | 
			
		||||
    uint32_t b7 : 1;
 | 
			
		||||
    uint32_t b8 : 1;
 | 
			
		||||
    uint32_t b9 : 1;
 | 
			
		||||
    uint32_t b10 : 1;
 | 
			
		||||
    uint32_t b11 : 1;
 | 
			
		||||
    uint32_t b12 : 1;
 | 
			
		||||
    uint32_t b13 : 1;
 | 
			
		||||
    uint32_t b14 : 1;
 | 
			
		||||
    uint32_t b15 : 1;
 | 
			
		||||
    uint32_t b16 : 1;
 | 
			
		||||
    uint32_t b17 : 1;
 | 
			
		||||
    uint32_t b18 : 1;
 | 
			
		||||
    uint32_t b19 : 1;
 | 
			
		||||
    uint32_t b20 : 1;
 | 
			
		||||
    uint32_t b21 : 1;
 | 
			
		||||
    uint32_t b22 : 1;
 | 
			
		||||
    uint32_t b23 : 1;
 | 
			
		||||
    uint32_t b24 : 1;
 | 
			
		||||
    uint32_t b25 : 1;
 | 
			
		||||
    uint32_t b26 : 1;
 | 
			
		||||
    uint32_t b27 : 1;
 | 
			
		||||
    uint32_t b28 : 1;
 | 
			
		||||
    uint32_t b29 : 1;
 | 
			
		||||
    uint32_t b30 : 1;
 | 
			
		||||
    uint32_t b31 : 1;
 | 
			
		||||
} __attribute__((packed, aligned(4))) gpio_bits_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Structure of templates for accessing GPIO registers
 | 
			
		||||
 */
 | 
			
		||||
typedef union _gpio_access_tp
 | 
			
		||||
{
 | 
			
		||||
    /* 32x1 bit mode */
 | 
			
		||||
    uint32_t u32[1];
 | 
			
		||||
    /* 16x2 bit mode */
 | 
			
		||||
    uint16_t u16[2];
 | 
			
		||||
    /* 8x4 bit mode */
 | 
			
		||||
    uint8_t u8[4];
 | 
			
		||||
    /* 1 bit mode */
 | 
			
		||||
    gpio_bits_t bits;
 | 
			
		||||
} __attribute__((packed, aligned(4))) gpio_access_tp_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       The GPIO address map
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _gpio
 | 
			
		||||
{
 | 
			
		||||
    /* Offset 0x00: Data (output) registers */
 | 
			
		||||
    gpio_access_tp_t data_output;
 | 
			
		||||
    /* Offset 0x04: Data direction registers */
 | 
			
		||||
    gpio_access_tp_t direction;
 | 
			
		||||
    /* Offset 0x08: Data source registers */
 | 
			
		||||
    gpio_access_tp_t source;
 | 
			
		||||
    /* Offset 0x10 - 0x2f: Unused registers, 9x4 bytes */
 | 
			
		||||
    uint32_t unused_0[9];
 | 
			
		||||
    /* Offset 0x30: Interrupt enable/disable registers */
 | 
			
		||||
    gpio_access_tp_t interrupt_enable;
 | 
			
		||||
    /* Offset 0x34: Interrupt mask registers */
 | 
			
		||||
    gpio_access_tp_t interrupt_mask;
 | 
			
		||||
    /* Offset 0x38: Interrupt level registers */
 | 
			
		||||
    gpio_access_tp_t interrupt_level;
 | 
			
		||||
    /* Offset 0x3c: Interrupt polarity registers */
 | 
			
		||||
    gpio_access_tp_t interrupt_polarity;
 | 
			
		||||
    /* Offset 0x40: Interrupt status registers */
 | 
			
		||||
    gpio_access_tp_t interrupt_status;
 | 
			
		||||
    /* Offset 0x44: Raw interrupt status registers */
 | 
			
		||||
    gpio_access_tp_t interrupt_status_raw;
 | 
			
		||||
    /* Offset 0x48: Interrupt debounce registers */
 | 
			
		||||
    gpio_access_tp_t interrupt_debounce;
 | 
			
		||||
    /* Offset 0x4c: Registers for clearing interrupts */
 | 
			
		||||
    gpio_access_tp_t interrupt_clear;
 | 
			
		||||
    /* Offset 0x50: External port (data input) registers */
 | 
			
		||||
    gpio_access_tp_t data_input;
 | 
			
		||||
    /* Offset 0x54 - 0x5f: Unused registers, 3x4 bytes */
 | 
			
		||||
    uint32_t unused_1[3];
 | 
			
		||||
    /* Offset 0x60: Sync level registers */
 | 
			
		||||
    gpio_access_tp_t sync_level;
 | 
			
		||||
    /* Offset 0x64: ID code */
 | 
			
		||||
    gpio_access_tp_t id_code;
 | 
			
		||||
    /* Offset 0x68: Interrupt both edge type */
 | 
			
		||||
    gpio_access_tp_t interrupt_bothedge;
 | 
			
		||||
 | 
			
		||||
} __attribute__((packed, aligned(4))) gpio_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Bus GPIO object instance
 | 
			
		||||
 */
 | 
			
		||||
extern volatile gpio_t *const gpio;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Gpio initialize
 | 
			
		||||
 *
 | 
			
		||||
 * @return      Result
 | 
			
		||||
 *     - 0      Success
 | 
			
		||||
 *     - Other Fail
 | 
			
		||||
 */
 | 
			
		||||
int gpio_init(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set Gpio drive mode
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   pin         Gpio pin
 | 
			
		||||
 * @param[in]   mode        Gpio pin drive mode
 | 
			
		||||
 */
 | 
			
		||||
void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Get Gpio pin value
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   pin      Gpio pin
 | 
			
		||||
 * @return      Pin value
 | 
			
		||||
 *
 | 
			
		||||
 *     - GPIO_PV_Low     Gpio pin low
 | 
			
		||||
 *     - GPIO_PV_High    Gpio pin high
 | 
			
		||||
 */
 | 
			
		||||
gpio_pin_value_t gpio_get_pin(uint8_t pin);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set Gpio pin value
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   pin         Gpio pin
 | 
			
		||||
 * @param[in]   value       Gpio pin value
 | 
			
		||||
 */
 | 
			
		||||
void gpio_set_pin(uint8_t pin, gpio_pin_value_t value);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* __GPIO_H__ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 gpio_common.h
 | 
			
		||||
* @brief add from Canaan k210 SDK
 | 
			
		||||
*                https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __GPIO_COMMON_H__
 | 
			
		||||
#define __GPIO_COMMON_H__
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef enum _gpio_drive_mode
 | 
			
		||||
{
 | 
			
		||||
    GPIO_DM_INPUT,
 | 
			
		||||
    GPIO_DM_INPUT_PULL_DOWN,
 | 
			
		||||
    GPIO_DM_INPUT_PULL_UP,
 | 
			
		||||
    GPIO_DM_OUTPUT,
 | 
			
		||||
} gpio_drive_mode_t;
 | 
			
		||||
 | 
			
		||||
typedef enum _gpio_pin_edge
 | 
			
		||||
{
 | 
			
		||||
    GPIO_PE_NONE,
 | 
			
		||||
    GPIO_PE_FALLING,
 | 
			
		||||
    GPIO_PE_RISING,
 | 
			
		||||
    GPIO_PE_BOTH,
 | 
			
		||||
    GPIO_PE_LOW,
 | 
			
		||||
    GPIO_PE_HIGH = 8,
 | 
			
		||||
} GpioPinEdgeT;
 | 
			
		||||
 | 
			
		||||
typedef enum _gpio_pin_value
 | 
			
		||||
{
 | 
			
		||||
    GPIO_PV_LOW,
 | 
			
		||||
    GPIO_PV_HIGH
 | 
			
		||||
} gpio_pin_value_t;
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* __GPIO_COMMON_H__ */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,277 @@
 | 
			
		|||
/* Copyright 2018 Canaan Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 gpiohs.h
 | 
			
		||||
* @brief add from Canaan k210 SDK
 | 
			
		||||
*                https://canaan-creative.com/developer
 | 
			
		||||
* @version 1.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-10-17
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __GPIOHS_H__
 | 
			
		||||
#define __GPIOHS_H__
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "gpio_common.h"
 | 
			
		||||
#include "plic.h"
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* clang-format off */
 | 
			
		||||
/* Register address offsets */
 | 
			
		||||
#define GPIOHS_INPUT_VAL  (0x00)
 | 
			
		||||
#define GPIOHS_INPUT_EN   (0x04)
 | 
			
		||||
#define GPIOHS_OUTPUT_EN  (0x08)
 | 
			
		||||
#define GPIOHS_OUTPUT_VAL (0x0C)
 | 
			
		||||
#define GPIOHS_PULLUP_EN  (0x10)
 | 
			
		||||
#define GPIOHS_DRIVE      (0x14)
 | 
			
		||||
#define GPIOHS_RISE_IE    (0x18)
 | 
			
		||||
#define GPIOHS_RISE_IP    (0x1C)
 | 
			
		||||
#define GPIOHS_FALL_IE    (0x20)
 | 
			
		||||
#define GPIOHS_FALL_IP    (0x24)
 | 
			
		||||
#define GPIOHS_HIGH_IE    (0x28)
 | 
			
		||||
#define GPIOHS_HIGH_IP    (0x2C)
 | 
			
		||||
#define GPIOHS_LOW_IE     (0x30)
 | 
			
		||||
#define GPIOHS_LOW_IP     (0x34)
 | 
			
		||||
#define GPIOHS_IOF_EN     (0x38)
 | 
			
		||||
#define GPIOHS_IOF_SEL    (0x3C)
 | 
			
		||||
#define GPIOHS_OUTPUT_XOR (0x40)
 | 
			
		||||
/* clang-format on */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief      GPIO bits raw object
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _gpiohs_raw
 | 
			
		||||
{
 | 
			
		||||
    /* Address offset 0x00 */
 | 
			
		||||
    uint32_t input_val;
 | 
			
		||||
    /* Address offset 0x04 */
 | 
			
		||||
    uint32_t input_en;
 | 
			
		||||
    /* Address offset 0x08 */
 | 
			
		||||
    uint32_t output_en;
 | 
			
		||||
    /* Address offset 0x0c */
 | 
			
		||||
    uint32_t output_val;
 | 
			
		||||
    /* Address offset 0x10 */
 | 
			
		||||
    uint32_t pullup_en;
 | 
			
		||||
    /* Address offset 0x14 */
 | 
			
		||||
    uint32_t drive;
 | 
			
		||||
    /* Address offset 0x18 */
 | 
			
		||||
    uint32_t rise_ie;
 | 
			
		||||
    /* Address offset 0x1c */
 | 
			
		||||
    uint32_t rise_ip;
 | 
			
		||||
    /* Address offset 0x20 */
 | 
			
		||||
    uint32_t fall_ie;
 | 
			
		||||
    /* Address offset 0x24 */
 | 
			
		||||
    uint32_t fall_ip;
 | 
			
		||||
    /* Address offset 0x28 */
 | 
			
		||||
    uint32_t high_ie;
 | 
			
		||||
    /* Address offset 0x2c */
 | 
			
		||||
    uint32_t high_ip;
 | 
			
		||||
    /* Address offset 0x30 */
 | 
			
		||||
    uint32_t low_ie;
 | 
			
		||||
    /* Address offset 0x34 */
 | 
			
		||||
    uint32_t low_ip;
 | 
			
		||||
    /* Address offset 0x38 */
 | 
			
		||||
    uint32_t iof_en;
 | 
			
		||||
    /* Address offset 0x3c */
 | 
			
		||||
    uint32_t iof_sel;
 | 
			
		||||
    /* Address offset 0x40 */
 | 
			
		||||
    uint32_t output_xor;
 | 
			
		||||
} __attribute__((packed, aligned(4))) gpiohs_raw_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       GPIO bits object
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _gpiohs_bits
 | 
			
		||||
{
 | 
			
		||||
    uint32_t b0 : 1;
 | 
			
		||||
    uint32_t b1 : 1;
 | 
			
		||||
    uint32_t b2 : 1;
 | 
			
		||||
    uint32_t b3 : 1;
 | 
			
		||||
    uint32_t b4 : 1;
 | 
			
		||||
    uint32_t b5 : 1;
 | 
			
		||||
    uint32_t b6 : 1;
 | 
			
		||||
    uint32_t b7 : 1;
 | 
			
		||||
    uint32_t b8 : 1;
 | 
			
		||||
    uint32_t b9 : 1;
 | 
			
		||||
    uint32_t b10 : 1;
 | 
			
		||||
    uint32_t b11 : 1;
 | 
			
		||||
    uint32_t b12 : 1;
 | 
			
		||||
    uint32_t b13 : 1;
 | 
			
		||||
    uint32_t b14 : 1;
 | 
			
		||||
    uint32_t b15 : 1;
 | 
			
		||||
    uint32_t b16 : 1;
 | 
			
		||||
    uint32_t b17 : 1;
 | 
			
		||||
    uint32_t b18 : 1;
 | 
			
		||||
    uint32_t b19 : 1;
 | 
			
		||||
    uint32_t b20 : 1;
 | 
			
		||||
    uint32_t b21 : 1;
 | 
			
		||||
    uint32_t b22 : 1;
 | 
			
		||||
    uint32_t b23 : 1;
 | 
			
		||||
    uint32_t b24 : 1;
 | 
			
		||||
    uint32_t b25 : 1;
 | 
			
		||||
    uint32_t b26 : 1;
 | 
			
		||||
    uint32_t b27 : 1;
 | 
			
		||||
    uint32_t b28 : 1;
 | 
			
		||||
    uint32_t b29 : 1;
 | 
			
		||||
    uint32_t b30 : 1;
 | 
			
		||||
    uint32_t b31 : 1;
 | 
			
		||||
} __attribute__((packed, aligned(4))) gpiohs_bits_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       GPIO bits multi access union
 | 
			
		||||
 */
 | 
			
		||||
typedef union _gpiohs_u32
 | 
			
		||||
{
 | 
			
		||||
    /* 32x1 bit mode */
 | 
			
		||||
    uint32_t u32[1];
 | 
			
		||||
    /* 16x2 bit mode */
 | 
			
		||||
    uint16_t u16[2];
 | 
			
		||||
    /* 8x4 bit mode */
 | 
			
		||||
    uint8_t u8[4];
 | 
			
		||||
    /* 1 bit mode */
 | 
			
		||||
    gpiohs_bits_t bits;
 | 
			
		||||
} __attribute__((packed, aligned(4))) gpiohs_u32_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief      GPIO object
 | 
			
		||||
 *
 | 
			
		||||
 *             The GPIO controller is a peripheral device mapped in the
 | 
			
		||||
 *             internal memory map, discoverable in the Configuration String.
 | 
			
		||||
 *             It is responsible for low-level configuration of the actual
 | 
			
		||||
 *             GPIO pads on the device (direction, pull up-enable, and drive
 | 
			
		||||
 *             value), as well as selecting between various sources of the
 | 
			
		||||
 *             controls for these signals. The GPIO controller allows seperate
 | 
			
		||||
 *             configuration of each of N GPIO bits.
 | 
			
		||||
 *
 | 
			
		||||
 *             Once the interrupt is pending, it will remain set until a 1 is
 | 
			
		||||
 *             written to the *_ip register at that bit.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef struct _gpiohs
 | 
			
		||||
{
 | 
			
		||||
    /* Address offset 0x00, Input Values */
 | 
			
		||||
    gpiohs_u32_t input_val;
 | 
			
		||||
    /* Address offset 0x04, Input enable */
 | 
			
		||||
    gpiohs_u32_t input_en;
 | 
			
		||||
    /* Address offset 0x08, Output enable */
 | 
			
		||||
    gpiohs_u32_t output_en;
 | 
			
		||||
    /* Address offset 0x0c, Onput Values */
 | 
			
		||||
    gpiohs_u32_t output_val;
 | 
			
		||||
    /* Address offset 0x10, Internal Pull-Ups enable */
 | 
			
		||||
    gpiohs_u32_t pullup_en;
 | 
			
		||||
    /* Address offset 0x14, Drive Strength */
 | 
			
		||||
    gpiohs_u32_t drive;
 | 
			
		||||
    /* Address offset 0x18, Rise interrupt enable */
 | 
			
		||||
    gpiohs_u32_t rise_ie;
 | 
			
		||||
    /* Address offset 0x1c, Rise interrupt pending */
 | 
			
		||||
    gpiohs_u32_t rise_ip;
 | 
			
		||||
    /* Address offset 0x20, Fall interrupt enable */
 | 
			
		||||
    gpiohs_u32_t fall_ie;
 | 
			
		||||
    /* Address offset 0x24, Fall interrupt pending */
 | 
			
		||||
    gpiohs_u32_t fall_ip;
 | 
			
		||||
    /* Address offset 0x28, High interrupt enable */
 | 
			
		||||
    gpiohs_u32_t high_ie;
 | 
			
		||||
    /* Address offset 0x2c, High interrupt pending */
 | 
			
		||||
    gpiohs_u32_t high_ip;
 | 
			
		||||
    /* Address offset 0x30, Low interrupt enable */
 | 
			
		||||
    gpiohs_u32_t low_ie;
 | 
			
		||||
    /* Address offset 0x34, Low interrupt pending */
 | 
			
		||||
    gpiohs_u32_t low_ip;
 | 
			
		||||
    /* Address offset 0x38, HW I/O Function enable */
 | 
			
		||||
    gpiohs_u32_t iof_en;
 | 
			
		||||
    /* Address offset 0x3c, HW I/O Function select */
 | 
			
		||||
    gpiohs_u32_t iof_sel;
 | 
			
		||||
    /* Address offset 0x40, Output XOR (invert) */
 | 
			
		||||
    gpiohs_u32_t output_xor;
 | 
			
		||||
} __attribute__((packed, aligned(4))) gpiohs_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       GPIO High-speed object instanse
 | 
			
		||||
 */
 | 
			
		||||
extern volatile gpiohs_t *const gpiohs;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Set Gpiohs drive mode
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   pin         Gpiohs pin
 | 
			
		||||
 * @param[in]   mode        Gpiohs pin drive mode
 | 
			
		||||
 */
 | 
			
		||||
void gpiohs_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief       Get Gpiohs pin value
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   pin     Gpiohs pin
 | 
			
		||||
 * @return      Pin     value
 | 
			
		||||
 *
 | 
			
		||||
 *     - GPIO_PV_Low     Gpiohs pin low
 | 
			
		||||
 *     - GPIO_PV_High    Gpiohs pin high
 | 
			
		||||
 */
 | 
			
		||||
gpio_pin_value_t gpiohs_get_pin(uint8_t pin);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief      Set Gpiohs pin value
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   pin      Gpiohs pin
 | 
			
		||||
 * @param[in]   value    Gpiohs pin value
 | 
			
		||||
 */
 | 
			
		||||
void gpiohs_set_pin(uint8_t pin, gpio_pin_value_t value);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief      Set Gpiohs pin edge for interrupt
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   pin         Gpiohs pin
 | 
			
		||||
 * @param[in]   edge        Gpiohs pin edge type
 | 
			
		||||
 */
 | 
			
		||||
void gpiohs_set_pin_edge(uint8_t pin, GpioPinEdgeT edge);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief      Set Gpiohs pin interrupt
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   pin             Gpiohs pin
 | 
			
		||||
 * @param[in]   priority        Gpiohs pin interrupt priority
 | 
			
		||||
 * @param[in]   func            Gpiohs pin interrupt service routine
 | 
			
		||||
 */
 | 
			
		||||
void gpiohs_set_irq(uint8_t pin, uint32_t priority, void(*func)());
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief      Set Gpiohs pin interrupt
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   pin             Gpiohs pin
 | 
			
		||||
 * @param[in]   priority        Gpiohs pin interrupt priority
 | 
			
		||||
 * @param[in]   callback        Gpiohs pin interrupt service routine
 | 
			
		||||
 * @param[in]   ctx             Gpiohs interrupt param
 | 
			
		||||
 */
 | 
			
		||||
void gpiohs_irq_register(uint8_t pin, uint32_t priority, plic_irq_callback_t callback, void *ctx);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief      Unregister Gpiohs pin interrupt
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   pin             Gpiohs pin
 | 
			
		||||
 */
 | 
			
		||||
void gpiohs_irq_unregister(uint8_t pin);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* __GPIOHS_H__ */
 | 
			
		||||
 | 
			
		||||