Sfoglia il codice sorgente

add: 将air101/air103的固件源码开源

Wendal Chen 4 anni fa
commit
d72653dd39
100 ha cambiato i file con 31490 aggiunte e 0 eliminazioni
  1. 6 0
      .gitignore
  2. 21 0
      LICENSE
  3. 3 0
      app/custom/emtry.c
  4. 182 0
      app/main.c
  5. 130 0
      app/port/GT5SLCD2E_1A.h
  6. 184 0
      app/port/lfs_port.c
  7. 19 0
      app/port/lfs_port.h
  8. 109 0
      app/port/luat_adc_air101.c
  9. 293 0
      app/port/luat_base_air101.c
  10. 119 0
      app/port/luat_conf_bsp.h
  11. 305 0
      app/port/luat_crypto_air101.c
  12. 221 0
      app/port/luat_fs_air101.c
  13. 125 0
      app/port/luat_gpio_air101.c
  14. 51 0
      app/port/luat_gt_air101.c
  15. 63 0
      app/port/luat_hwtimer_air101.c
  16. 65 0
      app/port/luat_i2c_air101.c
  17. 200 0
      app/port/luat_lcdseg_air101.c
  18. 44 0
      app/port/luat_lib_gtfont.c
  19. 62 0
      app/port/luat_lib_nimble.c
  20. 34 0
      app/port/luat_log.h
  21. 80 0
      app/port/luat_malloc_air101.c
  22. 59 0
      app/port/luat_mcu_air101.c
  23. 46 0
      app/port/luat_msgbus_air101.c
  24. 222 0
      app/port/luat_nimble.c
  25. 8 0
      app/port/luat_nimble.h
  26. 87 0
      app/port/luat_pm_air101.c
  27. 385 0
      app/port/luat_pwm_air101.c
  28. 57 0
      app/port/luat_rtc_air101.c
  29. 80 0
      app/port/luat_sdio_air101.c
  30. 66 0
      app/port/luat_sfd_onchip_air101.c
  31. 53 0
      app/port/luat_shell_air101.c
  32. 161 0
      app/port/luat_spi_air101.c
  33. 93 0
      app/port/luat_timer_air101.c
  34. 177 0
      app/port/luat_uart_air101.c
  35. 27 0
      app/port/luat_wdt_air101.c
  36. 3 0
      build_xmake.bat
  37. 403 0
      demo/console/wm_demo_console.h
  38. 0 0
      demo/wm_demo.h
  39. 79 0
      include/app/wm_at_ri_init.h
  40. 91 0
      include/app/wm_crypto.h
  41. 91 0
      include/app/wm_dhcp_server.h
  42. 66 0
      include/app/wm_dns_server.h
  43. 486 0
      include/app/wm_http_client.h
  44. 15 0
      include/app/wm_netif.h
  45. 437 0
      include/app/wm_netif2.0.3.h
  46. 80 0
      include/app/wm_ntp.h
  47. 159 0
      include/app/wm_ssl_server.h
  48. 65 0
      include/app/wm_webserver.h
  49. 291 0
      include/app/wm_wifi_oneshot.h
  50. 16 0
      include/arch/xt804/csi_config.h
  51. 1612 0
      include/arch/xt804/csi_core/core_804.h
  52. 63 0
      include/arch/xt804/csi_core/csi_core.h
  53. 2902 0
      include/arch/xt804/csi_core/csi_gcc.h
  54. 351 0
      include/arch/xt804/csi_dsp/csky_common_tables.h
  55. 140 0
      include/arch/xt804/csi_dsp/csky_const_structs.h
  56. 4783 0
      include/arch/xt804/csi_dsp/csky_math.h
  57. 140 0
      include/arch/xt804/csi_dsp/csky_vdsp2_const_structs.h
  58. 2291 0
      include/arch/xt804/csi_dsp/csky_vdsp2_math.h
  59. 248 0
      include/bt/wm_ble.h
  60. 480 0
      include/bt/wm_ble_gatt.h
  61. 422 0
      include/bt/wm_bt.h
  62. 300 0
      include/bt/wm_bt_av.h
  63. 1893 0
      include/bt/wm_bt_def.h
  64. 261 0
      include/bt/wm_bt_hf_client.h
  65. 151 0
      include/bt/wm_bt_spp.h
  66. 270 0
      include/driver/wm_7816.h
  67. 318 0
      include/driver/wm_adc.h
  68. 101 0
      include/driver/wm_cpu.h
  69. 233 0
      include/driver/wm_dma.h
  70. 282 0
      include/driver/wm_efuse.h
  71. 159 0
      include/driver/wm_flash.h
  72. 41 0
      include/driver/wm_flash_map.h
  73. 60 0
      include/driver/wm_fls_gd25qxx.h
  74. 181 0
      include/driver/wm_gpio.h
  75. 589 0
      include/driver/wm_gpio_afsel.h
  76. 289 0
      include/driver/wm_hostspi.h
  77. 253 0
      include/driver/wm_hspi.h
  78. 140 0
      include/driver/wm_i2c.h
  79. 300 0
      include/driver/wm_i2s.h
  80. 328 0
      include/driver/wm_internal_flash.h
  81. 204 0
      include/driver/wm_io.h
  82. 118 0
      include/driver/wm_irq.h
  83. 238 0
      include/driver/wm_lcd.h
  84. 254 0
      include/driver/wm_pmu.h
  85. 66 0
      include/driver/wm_psram.h
  86. 400 0
      include/driver/wm_pwm.h
  87. 109 0
      include/driver/wm_rtc.h
  88. 150 0
      include/driver/wm_sasc.h
  89. 142 0
      include/driver/wm_sdio_host.h
  90. 137 0
      include/driver/wm_timer.h
  91. 1284 0
      include/driver/wm_tipc.h
  92. 107 0
      include/driver/wm_touchsensor.h
  93. 529 0
      include/driver/wm_uart.h
  94. 86 0
      include/driver/wm_watchdog.h
  95. 317 0
      include/list.h
  96. 17 0
      include/net/wm_socket.h
  97. 422 0
      include/net/wm_socket2.0.3.h
  98. 15 0
      include/net/wm_sockets.h
  99. 1177 0
      include/net/wm_sockets2.0.3.h
  100. 18 0
      include/os/wm_os_config.h

+ 6 - 0
.gitignore

@@ -0,0 +1,6 @@
+.vscode
+.xmake
+bin/
+build/
+lib/build/
+lib/bin/

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Wendal
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 3 - 0
app/custom/emtry.c

@@ -0,0 +1,3 @@
+#include "luat_base.h"
+
+void xxxxxxxxxxxxabc(void) {}

+ 182 - 0
app/main.c

@@ -0,0 +1,182 @@
+#include "wm_include.h"
+#include "wm_gpio_afsel.h"
+#include "wm_psram.h"
+#include "wm_internal_flash.h"
+
+#ifdef USE_LUATOS
+#include "string.h"
+#include "luat_fs.h"
+#include "bget.h"
+#include "luat_base.h"
+#include "luat_msgbus.h"
+#include "luat_pm.h"
+
+#include <string.h>
+#include "wm_irq.h"
+#include "tls_sys.h"
+#include "wm_ram_config.h"
+#include "wm_internal_flash.h"
+
+#include "FreeRTOS.h"
+
+#define LUAT_LOG_TAG "main"
+#include "luat_log.h"
+
+#ifndef LUAT_HEAP_SIZE
+#define LUAT_HEAP_SIZE (128+48)*1024
+#endif
+
+#if (LUAT_HEAP_SIZE > 128*1024)
+static uint8_t __attribute__((aligned(4))) heap_ext[LUAT_HEAP_SIZE - 128*1024] = {0};
+#endif
+
+static unsigned char hexchars[] = "0123456789ABCDEF";
+static void luat_start(void *sdata){
+	bpool((void*)0x20028000, 128*1024);
+	#if (LUAT_HEAP_SIZE > 128*1024)
+	bpool((void*)heap_ext, LUAT_HEAP_SIZE - 128*1024);
+	#endif
+	luat_main();
+}
+
+#ifdef LUAT_USE_LVGL
+#include "lvgl.h"
+
+static void _lvgl_handler(void* args) {
+    while (1) {
+		lv_task_handler();
+        vTaskDelay(10 / (1000 / configTICK_RATE_HZ));
+    };
+}
+#define    LVGL_TASK_SIZE      512
+static OS_STK __attribute__((aligned(4)))			LVGLTaskStk[LVGL_TASK_SIZE] = {0};
+#endif
+
+#define    TASK_START_STK_SIZE         2048
+static OS_STK __attribute__((aligned(4))) 			TaskStartStk[TASK_START_STK_SIZE] = {0};
+
+#endif
+
+int rst_sta = 0;
+
+#ifdef USE_LUATOS
+extern unsigned int  TLS_FLASH_PARAM_DEFAULT        ;
+extern unsigned int  TLS_FLASH_PARAM1_ADDR          ;
+extern unsigned int  TLS_FLASH_PARAM2_ADDR          ;
+extern unsigned int  TLS_FLASH_PARAM_RESTORE_ADDR   ;
+extern unsigned int  TLS_FLASH_OTA_FLAG_ADDR        ;
+extern unsigned int  TLS_FLASH_END_ADDR             ;
+#endif
+
+void UserMain(void){
+	char unique_id [18] = {0};
+
+	tls_uart_options_t opt;
+	opt.baudrate = UART_BAUDRATE_B921600;
+	opt.charlength = TLS_UART_CHSIZE_8BIT;
+	opt.flow_ctrl = TLS_UART_FLOW_CTRL_NONE;
+	opt.paritytype = TLS_UART_PMODE_DISABLED;
+	opt.stopbits = TLS_UART_ONE_STOPBITS;
+	tls_uart_port_init(0, &opt, 0);
+
+	// 读取开机原因
+	rst_sta = tls_reg_read32(HR_CLK_RST_STA);
+	tls_reg_write32(HR_CLK_RST_STA, 0xFF);
+
+
+#ifdef LUAT_USE_SHELL
+	luat_shell_poweron(0);
+#endif
+
+#ifdef USE_LUATOS
+	tls_fls_read_unique_id(unique_id);
+	if (unique_id[1] == 0x10){
+		printf("I/main auth ok %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X %s\n",
+			unique_id[0], unique_id[1], unique_id[2], unique_id[3], unique_id[4],
+			unique_id[5], unique_id[6], unique_id[7], unique_id[8], unique_id[9],
+			unique_id[10], unique_id[11], unique_id[12], unique_id[13], unique_id[14],unique_id[15],
+			luat_os_bsp());
+	}else{
+		printf("I/main auth ok %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X %s\n",
+			unique_id[0], unique_id[1], unique_id[2], unique_id[3], unique_id[4],
+			unique_id[5], unique_id[6], unique_id[7], unique_id[8], unique_id[9],
+			luat_os_bsp());
+	}
+#endif
+
+#ifdef AIR103
+TLS_FLASH_PARAM_DEFAULT        =		  (0x80FB000UL);
+TLS_FLASH_PARAM1_ADDR          =		  (0x80FC000UL);
+TLS_FLASH_PARAM2_ADDR          =		  (0x80FD000UL);
+TLS_FLASH_PARAM_RESTORE_ADDR   =	      (0x80FE000UL);
+TLS_FLASH_OTA_FLAG_ADDR        =	      (0x80FF000UL);
+TLS_FLASH_END_ADDR             =		  (0x80FFFFFUL);
+#endif
+
+#ifdef LUAT_USE_NIMBLE
+	// TODO 注意, 除了启用LUAT_USE_NIMBTE外
+	// 1. 修改FreeRTOSConfig.h的configTICK_RATE_HZ为500, 并重新make lib
+	// 2. 若修改libblehost.a相关代码,需要手工复制bin目录下的文件,拷贝到lib目录. 
+    tls_ft_param_init();
+    tls_param_load_factory_default();
+    tls_param_init(); /*add param to init sysparam_lock sem*/
+#endif
+
+#if 0
+	// 首先, 初始化psram相关引脚
+	printf("==============================\n");
+	printf("CALL wm_psram_config(1)\n");
+	wm_psram_config(1);
+	// 然后初始化psram的寄存器
+	printf("CALL psram_init()\n");
+	psram_init(PSRAM_QPI); // 如果失败, 再试试PSRAM_SPI
+	uint8_t* psram_ptr = (uint8_t*)(PSRAM_ADDR_START);
+	// memset + memcheck
+	memset(psram_ptr, 0x00, PSRAM_SIZE_BYTE);
+	for (size_t psram_pos = 0; psram_pos < PSRAM_SIZE_BYTE; psram_pos++)
+	{
+		if (psram_ptr[psram_pos] != 0x00) {
+			printf("PSRAM memcheck 0x00 fail at %08X %02X\n", PSRAM_ADDR_START + psram_pos, psram_ptr[psram_pos]);
+			break;
+		}
+	}
+	memset(psram_ptr, 0x3A, PSRAM_SIZE_BYTE);
+	for (size_t psram_pos = 0; psram_pos < PSRAM_SIZE_BYTE; psram_pos++)
+	{
+		if (psram_ptr[psram_pos] != 0x3A) {
+			printf("PSRAM memcheck 0x3A fail at %08X %02X\n", PSRAM_ADDR_START + psram_pos, psram_ptr[psram_pos]);
+			break;
+		}
+	}
+	printf("==============================\n");
+#endif
+	
+	
+#ifdef USE_LUATOS
+#ifdef LUAT_USE_LVGL
+	lv_init();
+	tls_os_task_create(NULL, NULL,
+				_lvgl_handler,
+				NULL,
+				(void *)LVGLTaskStk,          /* task's stack start address */
+				LVGL_TASK_SIZE * sizeof(u32), /* task's stack size, unit:byte */
+				40,
+				0);
+#endif
+	tls_os_task_create(NULL, NULL,
+				luat_start,
+				NULL,
+				(void *)TaskStartStk,          /* task's stack start address */
+				TASK_START_STK_SIZE * sizeof(u32), /* task's stack size, unit:byte */
+				31,
+				0);
+#else
+	printf("hello word\n");
+	while (1);
+#endif
+}
+
+#ifndef USE_LUATOS
+void vApplicationTickHook( void ) {}
+void bpool(void *buffer, long len) {}
+#endif

+ 130 - 0
app/port/GT5SLCD2E_1A.h

@@ -0,0 +1,130 @@
+/*
+ *创建时间:2020-03-27
+ *创建人:	yang
+**/
+#ifndef _GT5SLCD2E_1A_H_
+#define _GT5SLCD2E_1A_H_
+
+/* 外部函数声明 */
+extern unsigned long r_dat_bat(unsigned long address,unsigned long DataLen,unsigned char *pBuff);
+extern unsigned char CheckID(unsigned char CMD, unsigned long address,unsigned long byte_long,unsigned char *p_arr);
+
+/********************* 矢量公用部分 *********************/
+//中文
+#define VEC_SONG_STY		1		//宋体
+
+//ASCII码
+#define VEC_FT_ASCII_STY 	5
+#define VEC_DZ_ASCII_STY 	6
+#define VEC_CH_ASCII_STY 	7
+#define VEC_BX_ASCII_STY 	8
+#define VEC_BZ_ASCII_STY 	9
+#define VEC_FX_ASCII_STY 	10
+#define VEC_GD_ASCII_STY 	11
+#define VEC_HZ_ASCII_STY 	12
+#define VEC_MS_ASCII_STY 	13
+#define VEC_SX_ASCII_STY 	14
+#define VEC_ZY_ASCII_STY 	15
+#define VEC_TM_ASCII_STY 	16
+//拉丁文
+#define VEC_YJ_LATIN_STY	17
+
+/******************* 两种调用模式配置 *******************/
+
+/**
+ * 方式一 VEC_ST_MODE : 通过使用声明VECFONT_ST结构体变量, 配置结构体信息,
+ *   获取点阵数据到zk_buffer[]数组中.
+ * 方式二 VEC_PARM_MODE : 通过指定参数进行调用, 获取点阵数据到pBits[]数组中.
+ * ps: 两种方式可同时配置使用, 择一使用亦可.
+*/
+#define VEC_ST_MODE
+#define VEC_PARM_MODE
+
+/********************* 分割线 *********************/
+
+#ifdef VEC_ST_MODE
+
+    #define ZK_BUFFER_LEN   4608    //可修改大小, 约等于 字号*字号/8.
+
+    typedef struct vecFont
+    {
+        unsigned long fontCode;		//字符编码中文:GB18030, ASCII/外文: unicode
+        unsigned char type;			//字体	@矢量公用部分
+        unsigned char size;			//文字大小
+        unsigned char thick;		//文字粗细
+        unsigned char zkBuffer[ZK_BUFFER_LEN];	//数据存储
+    }VECFONT_ST;
+
+    unsigned int get_font_st(VECFONT_ST * font_st);
+#endif
+
+#ifdef VEC_PARM_MODE
+	/*
+	 *函数名:	get_font()
+	 *功能:		矢量文字读取函数
+	 *参数:pBits		数据存储
+	 *		sty			文字字体选择  @矢量公用部分
+	 *		fontCode	字符编码中文:GB18030, ASCII/外文: unicode
+	 *		width		文字宽度
+	 *		height		文字高度
+	 *		thick		文字粗细
+	 *返回值:文字显示宽度
+	**/
+    unsigned int get_font(unsigned char *pBits,unsigned char sty,unsigned long fontCode,unsigned char width,unsigned char height, unsigned char thick);
+#endif
+/********************* 矢量区域结束 *********************/
+
+/*
+ *函数名:	get_Font_Gray()
+ *功能		灰度矢量文字读取函数
+ *参数:pBits		数据存储
+ *		sty			文字字体选择  @矢量公用部分
+ *		fontCode	字符编码中文:GB18030, ASCII/外文: unicode
+ *		fontSize	文字大小
+ *		thick		文字粗细
+ *返回值:re_buff[0] 字符的显示宽度 , re_buff[1] 字符的灰度阶级[1阶/2阶/3阶/4阶]
+**/	
+unsigned int* get_Font_Gray(unsigned char *pBits,unsigned char sty,unsigned long fontCode,unsigned char fontSize, unsigned char thick);
+
+//Unicode转GBK
+unsigned long  U2G(unsigned int  unicode);	
+//BIG5转GBK
+unsigned int BIG52GBK( unsigned char h,unsigned char l );
+
+/*----------------------------------------------------------------------------------------
+ * 灰度数据转换函数 2阶灰度/4阶灰度
+ * 说明 : 将点阵数据转换为灰度数据 [eg:32点阵数据转2阶灰度数据则转为16点阵灰度数据]
+ * 参数 :
+ *   OutPutData灰度数据;	 width 宽度; High 高度;	grade 灰度阶级[1阶/2阶/3阶/4阶]
+ *------------------------------------------------------------------------------------------*/
+void Gray_Process(unsigned char *OutPutData ,int width,int High,unsigned char Grade);
+
+/*----------------------------------------------------------------------------------------
+ * 灰度文字颜色设置 
+ * BmpDst 目标图片数据 
+ * BmpSrc 图标图片数据 
+ * WORD x, WORD y, 图标在目标图片的 X,Y位置。
+ * WORD src_w, WORD src_h,  图标的宽度和高度 
+ * WORD dst_w, WORD dst_h   目标图片的宽度和高度 
+ * SrcGray 灰度文字数据
+ * Grade	灰度阶级[2阶/4阶]
+ *------------------------------------------------------------------------------------------*/
+void AlphaBlend_whiteBC(unsigned char *BmpDst,unsigned char *BmpSrc, int x, int y, 
+	int src_w, int src_h, int dst_w, int dst_h,unsigned char *SrcGray,unsigned char Grade);
+
+/*----------------------------------------------------------------------------------------
+ * 灰度文字与背景混合
+ * BmpDst 目标图片数据 
+ * BmpSrc 图标图片数据 
+ * WORD x, WORD y, 图标在目标图片的 X,Y位置。
+ * WORD src_w, WORD src_h,  图标的宽度和高度 
+ * WORD dst_w, WORD dst_h   目标图片的宽度和高度 
+ * SrcGray 灰度文字数据
+ * Grade	灰度阶级[2阶/4阶]
+ *------------------------------------------------------------------------------------------*/
+void AlphaBlend_blackBC(unsigned char *BmpDst,unsigned char *BmpSrc, int x, int y,
+	int src_w, int src_h, int dst_w, int dst_h,unsigned char *SrcGray,unsigned char Grade);
+
+#endif
+
+/*--------------------------------------- end of file ---------------------------------------------*/

+ 184 - 0
app/port/lfs_port.c

@@ -0,0 +1,184 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "lfs_port.h"
+#include "lfs_util.h"
+
+#include "luat_base.h"
+
+#define LUAT_LOG_TAG "luat.fs.port"
+#include "luat_log.h"
+#include "wm_include.h"
+#include "lfs.h"
+#include "wm_flash_map.h"
+#include "wm_internal_flash.h"
+
+
+#ifndef FLASH_FS_REGION_SIZE
+#define FLASH_FS_REGION_SIZE 112
+#endif
+
+#ifndef LFS_START_ADDR
+#ifdef AIR103
+#define LFS_START_ADDR (0x0FC000 - FLASH_FS_REGION_SIZE * 1024)
+#else
+#define LFS_START_ADDR (0x1FC000 - FLASH_FS_REGION_SIZE * 1024)
+#endif
+#endif
+/***************************************************
+ ***************       MACRO      ******************
+ ***************************************************/
+#define LFS_BLOCK_DEVICE_READ_SIZE (256)
+#define LFS_BLOCK_DEVICE_PROG_SIZE (256)
+#define LFS_BLOCK_DEVICE_CACHE_SIZE (256)
+#define LFS_BLOCK_DEVICE_ERASE_SIZE (4096) // one sector 4KB
+#define LFS_BLOCK_DEVICE_TOTOAL_SIZE (FLASH_FS_REGION_SIZE * 1024)
+#define LFS_BLOCK_DEVICE_LOOK_AHEAD (16)
+/***************************************************
+ *******    FUNCTION FORWARD DECLARTION     ********
+ ***************************************************/
+
+// Read a block
+static int block_device_read(const struct lfs_config *cfg, lfs_block_t block,
+        lfs_off_t off, void *buffer, lfs_size_t size);
+
+// Program a block
+//
+// The block must have previously been erased.
+static int block_device_prog(const struct lfs_config *cfg, lfs_block_t block,
+        lfs_off_t off, const void *buffer, lfs_size_t size);
+
+// Erase a block
+//
+// A block must be erased before being programmed. The
+// state of an erased block is undefined.
+static int block_device_erase(const struct lfs_config *cfg, lfs_block_t block);
+
+// Sync the block device
+static int block_device_sync(const struct lfs_config *cfg);
+
+// utility functions for traversals
+static int lfs_statfs_count(void *p, lfs_block_t b);
+
+/***************************************************
+ ***************  GLOBAL VARIABLE  *****************
+ ***************************************************/
+
+#ifdef LFS_THREAD_SAFE_MUTEX
+static osMutexId_t lfs_mutex;
+#endif
+
+static char lfs_read_buf[256];
+static char lfs_prog_buf[256];
+// static __ALIGNED(4) char lfs_lookahead_buf[LFS_BLOCK_DEVICE_LOOK_AHEAD];
+static  char  __attribute__((aligned(4))) lfs_lookahead_buf[LFS_BLOCK_DEVICE_LOOK_AHEAD];
+
+// configuration of the filesystem is provided by this struct
+struct lfs_config lfs_cfg =
+{
+    .context = NULL,
+    // block device operations
+    .read = block_device_read,
+    .prog = block_device_prog,
+    .erase = block_device_erase,
+    .sync = block_device_sync,
+
+    // block device configuration
+    .read_size = LFS_BLOCK_DEVICE_READ_SIZE,
+    .prog_size = LFS_BLOCK_DEVICE_PROG_SIZE,
+    .block_size = LFS_BLOCK_DEVICE_ERASE_SIZE,
+    .block_count = LFS_BLOCK_DEVICE_TOTOAL_SIZE / LFS_BLOCK_DEVICE_ERASE_SIZE,
+    .block_cycles = 200,
+    .cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE,
+    .lookahead_size = LFS_BLOCK_DEVICE_LOOK_AHEAD,
+
+    .read_buffer = lfs_read_buf,
+    .prog_buffer = lfs_prog_buf,
+    .lookahead_buffer = lfs_lookahead_buf,
+    .name_max = 63,
+    .file_max = 0,
+    .attr_max = 0
+};
+
+lfs_t lfs;
+
+/***************************************************
+ *******         INTERANL FUNCTION          ********
+ ***************************************************/
+
+static int block_device_read(const struct lfs_config *cfg, lfs_block_t block,
+                             lfs_off_t off, void *buffer, lfs_size_t size)
+{
+    int ret;
+    //LLOGD("block_device_read ,block = %d, off = %d,  size = %d",block, off, size);
+    ret = tls_fls_read(block * 4096 + off + LFS_START_ADDR, (u8 *)buffer, size);
+    //LLOGD("block_device_read return val : %d",ret);
+    if (ret != TLS_FLS_STATUS_OK)
+    {
+        return -1;
+    }
+    return 0;
+}
+
+static int block_device_prog(const struct lfs_config *cfg, lfs_block_t block,
+                             lfs_off_t off, const void *buffer, lfs_size_t size)
+{
+    int ret;
+    //LLOGD("block_device_prog ,block = %d, off = %d,  size = %d",block, off, size);
+    ret = tls_fls_write(block * 4096 + off + LFS_START_ADDR, (u8 *)buffer, size);
+    //LLOGD("block_device_prog return val : %d",ret);
+    if (ret != TLS_FLS_STATUS_OK)
+    {
+        return -1;
+    }
+
+    return 0;
+}
+
+static int block_device_erase(const struct lfs_config *cfg, lfs_block_t block)
+{
+    int ret;
+    ret = tls_fls_erase((block * 4096 + LFS_START_ADDR) / INSIDE_FLS_SECTOR_SIZE);
+    if (ret != TLS_FLS_STATUS_OK)
+    {
+        return -1;
+    }
+    return 0;
+}
+
+static int block_device_sync(const struct lfs_config *cfg)
+{
+    return 0;
+}
+
+static int lfs_statfs_count(void *p, lfs_block_t b)
+{
+    *(lfs_size_t *)p += 1;
+
+    return 0;
+}
+
+// Initialize
+int LFS_Init(void)
+{
+    //printf("------------LFS_Init------------\r\n");
+    // mount the filesystem
+    int err = lfs_mount(&lfs, &lfs_cfg);
+    //printf("lfs_mount %d\r\n",err);
+    // reformat if we can't mount the filesystem
+    // this should only happen on the first boot
+    if (err)
+    {
+        err = lfs_format(&lfs, &lfs_cfg);
+        //printf("lfs_format %d\r\n",err);
+        if(err)
+            return err;
+
+        err = lfs_mount(&lfs, &lfs_cfg);
+        //printf("lfs_mount %d\r\n",err);
+        if(err)
+            return err;
+    }
+    return 0;
+}

+ 19 - 0
app/port/lfs_port.h

@@ -0,0 +1,19 @@
+#ifndef LFS_PORT_H
+#define LFS_PORT_H
+
+// variables used by the filesystem
+#include "lfs.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// Initialize
+int LFS_Init(void);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif

+ 109 - 0
app/port/luat_adc_air101.c

@@ -0,0 +1,109 @@
+#include "luat_adc.h"
+#include "luat_base.h"
+#include "wm_adc.h"
+#include "wm_gpio_afsel.h"
+#include "wm_include.h"
+
+// 0,1 标准ADC
+// 3 - 内部温度传感
+
+int luat_adc_open(int ch, void *args)
+{
+    switch (ch)
+    {
+    case 0:
+        wm_adc_config(ch);
+        break;
+    case 1:
+        wm_adc_config(ch);
+        break;
+#ifdef AIR103
+    case 2:
+        wm_adc_config(ch);
+        break;
+    case 3:
+        wm_adc_config(ch);
+        break;
+#endif
+    case 10:
+        return 0; // 温度传感器
+    case 11:
+        return 0; // VBAT电压
+    default:
+        return 1;
+    }
+    return 0;
+}
+
+int luat_adc_read(int ch, int *val, int *val2)
+{
+    int voltage = 0;
+
+    switch (ch)
+    {
+    case 0:
+        voltage = adc_get_inputVolt2(ch, val);
+        break;
+    case 1:
+        voltage = adc_get_inputVolt2(ch, val);
+        break;
+#ifdef AIR103
+    case 2:
+        voltage = adc_get_inputVolt2(ch, val);
+        break;
+    case 3:
+        voltage = adc_get_inputVolt2(ch, val);
+        break;
+#endif
+    case 10:
+        voltage = adc_temp();
+        *val = voltage;
+        *val2 = voltage;
+        return 0;
+    case 11:
+        voltage = adc_get_interVolt();
+        *val = voltage;
+        *val2 = voltage;
+        return 0;
+    default:
+        return 1;
+    }
+    if (*val < 46134) {
+        *val2 = 0;
+    }
+    else if (*val > 123405) {
+        *val2 = 2300;
+    }
+    else {
+        *val2 = (int)((double)(*val - 46134) / (double)(32.196));
+    }
+    return 0;
+}
+
+int luat_adc_close(int ch)
+{
+    switch (ch)
+    {
+    case 0:
+        tls_io_cfg_set(WM_IO_PA_01, WM_IO_OPTION5);
+        break;
+    case 1:
+        tls_io_cfg_set(WM_IO_PA_04, WM_IO_OPTION5);
+        break;
+#ifdef AIR103
+    case 2:
+        tls_io_cfg_set(WM_IO_PA_03, WM_IO_OPTION5);
+        break;
+    case 3:
+        tls_io_cfg_set(WM_IO_PA_02, WM_IO_OPTION5);
+        break;
+#endif
+    case 10:
+        break; // 温度
+    case 11:
+        break; // 内部电压
+    default:
+        return 1;
+    }
+    return 0;
+}

+ 293 - 0
app/port/luat_base_air101.c

@@ -0,0 +1,293 @@
+#include "luat_base.h"
+#include "time.h"
+#include "luat_msgbus.h"
+// #include "wm_cmdp.h"
+#include "wm_include.h"
+#include "wm_watchdog.h"
+#include "wm_pmu.h"
+#include "wm_rtc.h"
+#include "wm_regs.h"
+#include "wm_cpu.h"
+
+LUAMOD_API int luaopen_gtfont( lua_State *L );
+LUAMOD_API int luaopen_nimble( lua_State *L );
+
+time_t time(time_t* _tm)
+{
+  struct tm tmt = {0};
+  tls_get_rtc(&tmt);
+  time_t t = mktime(&tmt);
+  if (_tm != NULL)
+    memcpy(_tm, &t, sizeof(time_t));
+  return t;
+}
+clock_t clock(void)
+{
+  return (clock_t)time(NULL);
+}
+
+static const luaL_Reg loadedlibs[] = {
+  {"_G", luaopen_base}, // _G
+  {LUA_LOADLIBNAME, luaopen_package}, // require
+  {LUA_COLIBNAME, luaopen_coroutine}, // coroutine协程库
+  {LUA_TABLIBNAME, luaopen_table},    // table库,操作table类型的数据结构
+  {LUA_IOLIBNAME, luaopen_io},        // io库,操作文件
+  {LUA_OSLIBNAME, luaopen_os},        // os库,已精简
+  {LUA_STRLIBNAME, luaopen_string},   // string库,字符串操作
+  {LUA_MATHLIBNAME, luaopen_math},    // math 数值计算
+// //  {LUA_UTF8LIBNAME, luaopen_utf8},
+  {LUA_DBLIBNAME, luaopen_debug},     // debug库,已精简
+#if defined(LUA_COMPAT_BITLIB)
+  {LUA_BITLIBNAME, luaopen_bit32},    // 不太可能启用
+#endif
+// 往下是LuatOS定制的库, 如需精简请仔细测试
+//----------------------------------------------------------------------
+// 核心支撑库, 不可禁用!!
+  {"rtos",    luaopen_rtos},              // rtos底层库, 核心功能是队列和定时器
+  {"log",     luaopen_log},               // 日志库
+  {"timer",   luaopen_timer},             // 延时库
+//-----------------------------------------------------------------------
+// 设备驱动类, 可按实际情况删减. 即使最精简的固件, 也强烈建议保留uart库
+#ifdef LUAT_USE_UART
+  {"uart",    luaopen_uart},              // 串口操作
+#endif
+#ifdef LUAT_USE_GPIO
+  {"gpio",    luaopen_gpio},              // GPIO脚的操作
+#endif
+#ifdef LUAT_USE_I2C
+  {"i2c",     luaopen_i2c},               // I2C操作
+#endif
+#ifdef LUAT_USE_SPI
+  {"spi",     luaopen_spi},               // SPI操作
+#endif
+#ifdef LUAT_USE_ADC
+  {"adc",     luaopen_adc},               // ADC模块
+#endif
+#ifdef LUAT_USE_SDIO
+  {"sdio",     luaopen_sdio},             // SDIO模块
+#endif
+#ifdef LUAT_USE_PWM
+  {"pwm",     luaopen_pwm},               // PWM模块
+#endif
+#ifdef LUAT_USE_WDT
+  {"wdt",     luaopen_wdt},               // watchdog模块
+#endif
+#ifdef LUAT_USE_PM
+  {"pm",      luaopen_pm},                // 电源管理模块
+#endif
+#ifdef LUAT_USE_MCU
+  {"mcu",     luaopen_mcu},               // MCU特有的一些操作
+#endif
+#ifdef LUAT_USE_HWTIMER
+  {"hwtimer", luaopen_hwtimer},           // 硬件定时器
+#endif
+#ifdef LUAT_USE_RTC
+  {"rtc", luaopen_rtc},                   // 实时时钟
+#endif
+//-----------------------------------------------------------------------
+// 工具库, 按需选用
+#ifdef LUAT_USE_CRYPTO
+  {"crypto",luaopen_crypto},            // 加密和hash模块
+#endif
+#ifdef LUAT_USE_CJSON
+  {"json",    luaopen_cjson},          // json的序列化和反序列化
+#endif
+#ifdef LUAT_USE_ZBUFF
+  {"zbuff",   luaopen_zbuff},             // 像C语言语言操作内存块
+#endif
+#ifdef LUAT_USE_PACK
+  {"pack",    luaopen_pack},              // pack.pack/pack.unpack
+#endif
+  // {"mqttcore",luaopen_mqttcore},          // MQTT 协议封装
+  // {"libcoap", luaopen_libcoap},           // 处理COAP消息
+
+#ifdef LUAT_USE_GNSS
+  {"libgnss", luaopen_libgnss},           // 处理GNSS定位数据
+#endif
+#ifdef LUAT_USE_FS
+  {"fs",      luaopen_fs},                // 文件系统库,在io库之外再提供一些方法
+#endif
+#ifdef LUAT_USE_SENSOR
+  {"sensor",  luaopen_sensor},            // 传感器库,支持DS18B20
+#endif
+#ifdef LUAT_USE_SFUD
+  {"sfud", luaopen_sfud},              // sfud
+#endif
+#ifdef LUAT_USE_DISP
+  {"disp",  luaopen_disp},              // OLED显示模块,支持SSD1306
+#endif
+#ifdef LUAT_USE_U8G2
+  {"u8g2", luaopen_u8g2},              // u8g2
+#endif
+
+#ifdef LUAT_USE_EINK
+  {"eink",  luaopen_eink},              // 电子墨水屏,试验阶段
+#endif
+
+#ifdef LUAT_USE_LVGL
+#ifndef LUAT_USE_LCD
+#define LUAT_USE_LCD
+#endif
+  {"lvgl",   luaopen_lvgl},
+#endif
+
+#ifdef LUAT_USE_LCD
+  {"lcd",    luaopen_lcd},
+#endif
+#ifdef LUAT_USE_STATEM
+  {"statem",    luaopen_statem},
+#endif
+#ifdef LUAT_USE_GTFONT
+  {"gtfont",    luaopen_gtfont},
+#endif
+#ifdef LUAT_USE_NIMBLE
+  {"nimble",    luaopen_nimble},
+#endif
+  {NULL, NULL}
+};
+
+// 按不同的rtconfig加载不同的库函数
+void luat_openlibs(lua_State *L) {
+    // 初始化队列服务
+    luat_msgbus_init();
+    // print_list_mem("done>luat_msgbus_init");
+    // 加载系统库
+    const luaL_Reg *lib;
+    /* "require" functions from 'loadedlibs' and set results to global table */
+    for (lib = loadedlibs; lib->func; lib++) {
+        luaL_requiref(L, lib->name, lib->func, 1);
+        lua_pop(L, 1);  /* remove lib */
+        //extern void print_list_mem(const char* name);
+        //print_list_mem(lib->name);
+    }
+}
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#if configUSE_HEAP3
+extern size_t xTotalHeapSize;
+extern size_t xFreeBytesRemaining;
+extern size_t xFreeBytesMin;
+#endif
+
+void luat_meminfo_sys(size_t* total, size_t* used, size_t* max_used)
+{
+#if configUSE_HEAP3
+  *used = xTotalHeapSize - xFreeBytesRemaining;
+  *max_used = xTotalHeapSize - xFreeBytesMin;
+  *total = xTotalHeapSize;
+#else
+  *used = configTOTAL_HEAP_SIZE - xPortGetFreeHeapSize();
+	*max_used = *used;
+  *total = configTOTAL_HEAP_SIZE;
+#endif
+}
+
+
+const char* luat_os_bsp(void)
+{
+#ifdef AIR103
+    return "air103";
+#else
+    return "air101";
+#endif
+}
+
+void luat_os_reboot(int code)
+{
+   tls_sys_reset();
+}
+
+static void pmu_timer0_irq(u8 *arg){}
+void luat_os_standy(int timeout)
+{
+  tls_pmu_timer0_isr_register((tls_pmu_irq_callback)pmu_timer0_irq, NULL);
+  tls_pmu_timer0_start(timeout);
+  tls_pmu_standby_start();
+  return;
+}
+
+//void delay_1us(unsigned int time);
+
+void luat_timer_us_delay(size_t time)
+{
+  if(time<=0)
+    return;
+	volatile unsigned int value=1;
+  clk_div_reg clk_div;
+  clk_div.w = tls_reg_read32(HR_CLK_DIV_CTL);
+  switch (clk_div.b.CPU)
+  {
+    case CPU_CLK_240M:
+      value = 341*time/10 - 30;
+      break;
+    case CPU_CLK_160M:
+      value = 227*time/10 - 22;
+      break;
+    case CPU_CLK_80M:
+      value = 113*time/10;
+      if(value>=22) value -= 22;
+      break;
+    case CPU_CLK_40M:
+      value = 562*time/100;
+      if(value>=31) value -= 31;
+      break;
+    default:
+      value = time/2;
+      break;
+  }
+  if(value<=1)
+    return;
+	while(value--)
+	{
+		__NOP();
+	}
+}
+
+u32 cpu_sr = 0;
+void luat_os_entry_cri(void) {
+  cpu_sr = tls_os_set_critical();
+}
+
+void luat_os_exit_cri(void) {
+  tls_os_release_critical(cpu_sr);
+}
+
+#ifdef LUAT_USE_LVGL
+#include "lvgl.h"
+#endif
+
+void vApplicationTickHook( void ) {
+	#ifdef LUAT_USE_LVGL
+	lv_tick_inc(1000 / configTICK_RATE_HZ);
+	#endif
+}
+
+
+//-------------- cjson 需要这个函数
+int  strncasecmp ( const char* s1, const char* s2, size_t len )
+{
+	register unsigned int  x2;
+	register unsigned int  x1;
+	register const char*   end = s1 + len;
+
+	while (1)
+	{
+		if ((s1 >= end) )
+			return 0;
+
+		x2 = *s2 - 'A'; if ((x2 < 26u)) x2 += 32;
+		x1 = *s1 - 'A'; if ((x1 < 26u)) x1 += 32;
+		s1++; s2++;
+
+		if (x2 != x1)
+			break;
+
+		if (x1 == (unsigned int)-'A')
+			break;
+	}
+
+	return x1 - x2;
+}
+//--------------

+ 119 - 0
app/port/luat_conf_bsp.h

@@ -0,0 +1,119 @@
+
+#ifndef LUAT_CONF_BSP
+#define LUAT_CONF_BSP
+
+#define LUAT_BSP_VERSION "V0003"
+
+#define AIR101
+
+#define LUAT_FAST_RAMRUN __attribute__((section (".ram_run")))
+#define LV_ATTRIBUTE_FAST_MEM __attribute__((section (".ram_run")))
+
+// 启用64位虚拟机
+// #define LUAT_CONF_VM_64bit
+
+//#define LUAT_CONF_LUASTATE_NOT_STATIC
+
+// #define LUAT_CONF_LAUX_BUFFSIZE 1024
+
+// #define LUA_COMPAT_BITLIB 1
+
+//#define LUAT_CONF_DISABLE_ROTABLE
+
+#define LUAT_USE_FS_VFS 1
+
+#define LUAT_USE_VFS_INLINE_LIB 1
+
+#define LUAT_USE_UART 1
+#define LUAT_USE_GPIO 1
+#define LUAT_USE_I2C  1
+#define LUAT_USE_SPI  1
+#define LUAT_USE_ADC  1
+#define LUAT_USE_PWM  1
+#define LUAT_USE_WDT  1
+#define LUAT_USE_PM  1
+#define LUAT_USE_MCU  1
+#define LUAT_USE_HWTIMER  1
+#define LUAT_USE_RTC 1
+#define LUAT_USE_SDIO 1
+#define LUAT_USE_LCDSEG 1
+
+// #define LUAT_USE_CRYPTO  1
+// #define LUAT_USE_CJSON  1
+// #define LUAT_USE_ZBUFF  1
+// #define LUAT_USE_PACK  1
+//#define LUAT_USE_GNSS  1
+// #define LUAT_USE_FS  1
+// #define LUAT_USE_SENSOR  1
+// #define LUAT_USE_SFUD  1
+// #define LUAT_USE_STATEM 1
+
+// #define LUAT_USE_GTFONT 1
+
+#define LUAT_USE_SHELL 1
+// #define LUAT_USE_NIMBLE 1
+
+// #define LUAT_USE_DISP 1
+// #define USE_CHINESE_WQY12_FONT
+
+// #define LUAT_USE_EINK
+// #define LUAT_USE_EINK_FONT_C16P 1
+// #define LUAT_USE_EINK_FONT_C24P 1
+
+//---------------------
+// U8G2
+// #define LUAT_MEMORY_OPT_G_FUNCS
+// #define LUAT_USE_U8G2
+// #define USE_U8G2_WQY12_T_GB2312
+// #define USE_U8G2_UNIFONT_SYMBOLS
+
+//---------------------
+// LVGL
+// #define LUAT_USE_LCD
+// #define LUAT_USE_LVGL
+// #define LV_DISP_DEF_REFR_PERIOD 10
+// #define LUAT_LV_DEBUG 0
+// #define LV_FONT_OPPOSANS_M_8
+// #define LV_FONT_OPPOSANS_M_10
+
+#define LUAT_USE_LVGL_ARC   //圆弧 无依赖
+#define LUAT_USE_LVGL_BAR   //进度条 无依赖
+#define LUAT_USE_LVGL_BTN   //按钮 依赖容器CONT
+#define LUAT_USE_LVGL_BTNMATRIX   //按钮矩阵 无依赖
+#define LUAT_USE_LVGL_CALENDAR   //日历 无依赖
+#define LUAT_USE_LVGL_CANVAS   //画布 依赖图片IMG
+#define LUAT_USE_LVGL_CHECKBOX   //复选框 依赖按钮BTN 标签LABEL
+#define LUAT_USE_LVGL_CHART   //图表 无依赖
+#define LUAT_USE_LVGL_CONT   //容器 无依赖
+#define LUAT_USE_LVGL_CPICKER   //颜色选择器 无依赖
+#define LUAT_USE_LVGL_DROPDOWN   //下拉列表 依赖页面PAGE 标签LABEL
+#define LUAT_USE_LVGL_GAUGE   //仪表 依赖进度条BAR 仪表(弧形刻度)LINEMETER
+#define LUAT_USE_LVGL_IMG   //图片 依赖标签LABEL
+#define LUAT_USE_LVGL_IMGBTN   //图片按钮 依赖按钮BTN
+#define LUAT_USE_LVGL_KEYBOARD   //键盘 依赖图片按钮IMGBTN
+#define LUAT_USE_LVGL_LABEL   //标签 无依赖
+#define LUAT_USE_LVGL_LED   //LED 无依赖
+#define LUAT_USE_LVGL_LINE   //线 无依赖
+#define LUAT_USE_LVGL_LIST   //列表 依赖页面PAGE 按钮BTN 标签LABEL
+#define LUAT_USE_LVGL_LINEMETER   //仪表(弧形刻度) 无依赖
+#define LUAT_USE_LVGL_OBJMASK   //对象蒙版 无依赖
+#define LUAT_USE_LVGL_MSGBOX   //消息框 依赖图片按钮IMGBTN 标签LABEL
+#define LUAT_USE_LVGL_PAGE   //页面 依赖容器CONT
+#define LUAT_USE_LVGL_SPINNER   //旋转器 依赖圆弧ARC 动画ANIM
+#define LUAT_USE_LVGL_ROLLER   //滚筒 无依赖
+#define LUAT_USE_LVGL_SLIDER   //滑杆 依赖进度条BAR
+#define LUAT_USE_LVGL_SPINBOX   //数字调整框 无依赖
+#define LUAT_USE_LVGL_SWITCH   //开关 依赖滑杆SLIDER
+#define LUAT_USE_LVGL_TEXTAREA   //文本框 依赖标签LABEL 页面PAGE
+#define LUAT_USE_LVGL_TABLE   //表格 依赖标签LABEL
+#define LUAT_USE_LVGL_TABVIEW   //页签 依赖页面PAGE 图片按钮IMGBTN
+#define LUAT_USE_LVGL_TILEVIEW   //平铺视图 依赖页面PAGE
+#define LUAT_USE_LVGL_WIN   //窗口 依赖容器CONT 按钮BTN 标签LABEL 图片IMG 页面PAGE
+
+#define LV_HOR_RES_MAX          (160)
+#define LV_VER_RES_MAX          (80)
+#define LV_COLOR_DEPTH          16
+
+#define LV_COLOR_16_SWAP   1
+
+#endif

+ 305 - 0
app/port/luat_crypto_air101.c

@@ -0,0 +1,305 @@
+
+#include "string.h"
+#include "wm_include.h"
+#include "wm_crypto_hard.h"
+#include "aes.h"
+
+#include "luat_base.h"
+#include "luat_crypto.h"
+#define LUAT_LOG_TAG "crypto"
+#include "luat_log.h"
+
+//#include "mbedtls/sha1.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+//#include "mbedtls/md5.h"
+
+void luat_crypto_HmacSha1(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen);
+void luat_crypto_HmacSha256(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen);
+void luat_crypto_HmacSha512(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen);
+void luat_crypto_HmacMd5(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen);
+
+int luat_crypto_md5_simple(const char* str, size_t str_size, void* out_ptr) {
+    psDigestContext_t ctx;
+    tls_crypto_md5_init(&ctx);
+
+    tls_crypto_md5_update(&ctx, (const unsigned char *)str, str_size);
+    tls_crypto_md5_final(&ctx, (unsigned char *)out_ptr);
+    return 0;
+}
+int luat_crypto_sha1_simple(const char* str, size_t str_size, void* out_ptr) {
+    psDigestContext_t ctx;
+    tls_crypto_sha1_init(&ctx);
+
+    tls_crypto_sha1_update(&ctx, (const unsigned char *)str, str_size);
+    tls_crypto_sha1_final(&ctx, (unsigned char *)out_ptr);
+    return 0;
+}
+
+int luat_crypto_sha256_simple(const char* str, size_t str_size, void* out_ptr) {
+    mbedtls_sha256_context ctx;
+    mbedtls_sha256_init(&ctx);
+
+    mbedtls_sha256_starts(&ctx, 0);
+    mbedtls_sha256_update(&ctx, (const unsigned char *)str, str_size);
+    mbedtls_sha256_finish(&ctx, (unsigned char *)out_ptr);
+    mbedtls_sha256_free(&ctx);
+    return 0;
+}
+
+int luat_crypto_sha512_simple(const char* str, size_t str_size, void* out_ptr) {
+    mbedtls_sha512_context ctx;
+    mbedtls_sha512_init(&ctx);
+
+    mbedtls_sha512_starts(&ctx, 0);
+    mbedtls_sha512_update(&ctx, (const unsigned char *)str, str_size);
+    mbedtls_sha512_finish(&ctx, (unsigned char *)out_ptr);
+    mbedtls_sha512_free(&ctx);
+    return 0;
+}
+
+int luat_crypto_hmac_md5_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
+    luat_crypto_HmacMd5((const unsigned char *)str, str_size, (unsigned char *)out_ptr, (const unsigned char *)mac, mac_size);
+    return 0;
+}
+
+int luat_crypto_hmac_sha1_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
+    luat_crypto_HmacSha1((const unsigned char *)str, str_size, (unsigned char *)out_ptr, (const unsigned char *)mac, mac_size);
+    return 0;
+}
+
+int luat_crypto_hmac_sha256_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
+    luat_crypto_HmacSha256((const unsigned char *)str, str_size, (unsigned char *)out_ptr, (const unsigned char *)mac, mac_size);
+    return 0;
+}
+
+int luat_crypto_hmac_sha512_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
+    luat_crypto_HmacSha512((const unsigned char *)str, str_size, (unsigned char *)out_ptr, (const unsigned char *)mac, mac_size);
+    return 0;
+}
+
+
+///----------------------------
+
+#define ALI_SHA1_KEY_IOPAD_SIZE (64)
+#define ALI_SHA1_DIGEST_SIZE    (20)
+
+#define ALI_SHA256_KEY_IOPAD_SIZE   (64)
+#define ALI_SHA256_DIGEST_SIZE      (32)
+
+#define ALI_SHA512_KEY_IOPAD_SIZE   (128)
+#define ALI_SHA512_DIGEST_SIZE      (64)
+
+#define ALI_MD5_KEY_IOPAD_SIZE  (64)
+#define ALI_MD5_DIGEST_SIZE     (16)
+
+// char atHb2Hex(unsigned char hb)
+// {
+//     hb = hb&0xF;
+//     return (char)(hb<10 ? '0'+hb : hb-10+'a');
+// }
+
+
+/*
+ * output = SHA-1( input buffer )
+ */
+void luat_crypto_HmacSha1(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen)
+{
+    int i;
+    psDigestContext_t ctx;
+    unsigned char k_ipad[ALI_SHA1_KEY_IOPAD_SIZE] = {0};
+    unsigned char k_opad[ALI_SHA1_KEY_IOPAD_SIZE] = {0};
+    unsigned char tempbuf[ALI_SHA1_DIGEST_SIZE];
+
+    memset(k_ipad, 0x36, ALI_SHA1_KEY_IOPAD_SIZE);
+    memset(k_opad, 0x5C, ALI_SHA1_KEY_IOPAD_SIZE);
+
+    for(i=0; i<keylen; i++)
+    {
+        if(i>=ALI_SHA1_KEY_IOPAD_SIZE)
+        {
+            break;
+        }
+        k_ipad[i] ^=key[i];
+        k_opad[i] ^=key[i];
+    }
+
+    tls_crypto_sha1_init(&ctx);
+
+    tls_crypto_sha1_update(&ctx, k_ipad, ALI_SHA1_KEY_IOPAD_SIZE);
+    tls_crypto_sha1_update(&ctx, input, ilen);
+    tls_crypto_sha1_final(&ctx, tempbuf);
+
+    tls_crypto_sha1_init(&ctx);
+
+    tls_crypto_sha1_update(&ctx, k_opad, ALI_SHA1_KEY_IOPAD_SIZE);
+    tls_crypto_sha1_update(&ctx, tempbuf, ALI_SHA1_DIGEST_SIZE);
+    tls_crypto_sha1_final(&ctx, tempbuf);
+
+    memcpy(output, tempbuf, ALI_SHA1_DIGEST_SIZE);
+}
+/*
+ * output = SHA-256( input buffer )
+ */
+void luat_crypto_HmacSha256(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen)
+{
+    int i;
+    mbedtls_sha256_context ctx;
+    unsigned char k_ipad[ALI_SHA256_KEY_IOPAD_SIZE] = {0};
+    unsigned char k_opad[ALI_SHA256_KEY_IOPAD_SIZE] = {0};
+
+    memset(k_ipad, 0x36, 64);
+    memset(k_opad, 0x5C, 64);
+
+    if ((NULL == input) || (NULL == key) || (NULL == output)) {
+        return;
+    }
+
+    if (keylen > ALI_SHA256_KEY_IOPAD_SIZE) {
+        return;
+    }
+
+    for(i=0; i<keylen; i++)
+    {
+        if(i>=ALI_SHA256_KEY_IOPAD_SIZE)
+        {
+            break;
+        }
+        k_ipad[i] ^=key[i];
+        k_opad[i] ^=key[i];
+    }
+    mbedtls_sha256_init(&ctx);
+
+    mbedtls_sha256_starts(&ctx, 0);
+    mbedtls_sha256_update(&ctx, k_ipad, ALI_SHA256_KEY_IOPAD_SIZE);
+    mbedtls_sha256_update(&ctx, input, ilen);
+    mbedtls_sha256_finish(&ctx, output);
+
+    mbedtls_sha256_starts(&ctx, 0);
+    mbedtls_sha256_update(&ctx, k_opad, ALI_SHA256_KEY_IOPAD_SIZE);
+    mbedtls_sha256_update(&ctx, output, ALI_SHA256_DIGEST_SIZE);
+    mbedtls_sha256_finish(&ctx, output);
+
+    mbedtls_sha256_free(&ctx);
+}
+/*
+ * output = SHA-512( input buffer )
+ */
+void luat_crypto_HmacSha512(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen)
+{
+    int i;
+    mbedtls_sha512_context ctx;
+    unsigned char k_ipad[ALI_SHA512_KEY_IOPAD_SIZE] = {0};
+    unsigned char k_opad[ALI_SHA512_KEY_IOPAD_SIZE] = {0};
+
+    memset(k_ipad, 0x36, ALI_SHA512_KEY_IOPAD_SIZE);
+    memset(k_opad, 0x5C, ALI_SHA512_KEY_IOPAD_SIZE);
+
+    if ((NULL == input) || (NULL == key) || (NULL == output)) {
+        return;
+    }
+
+    if (keylen > ALI_SHA512_KEY_IOPAD_SIZE) {
+        return;
+    }
+
+    for(i=0; i<keylen; i++)
+    {
+        if(i>=ALI_SHA512_KEY_IOPAD_SIZE)
+        {
+            break;
+        }
+        k_ipad[i] ^=key[i];
+        k_opad[i] ^=key[i];
+    }
+    mbedtls_sha512_init(&ctx);
+
+    mbedtls_sha512_starts(&ctx, 0);
+    mbedtls_sha512_update(&ctx, k_ipad, ALI_SHA512_KEY_IOPAD_SIZE);
+    mbedtls_sha512_update(&ctx, input, ilen);
+    mbedtls_sha512_finish(&ctx, output);
+
+    mbedtls_sha512_starts(&ctx, 0);
+    mbedtls_sha512_update(&ctx, k_opad, ALI_SHA512_KEY_IOPAD_SIZE);
+    mbedtls_sha512_update(&ctx, output, ALI_SHA512_DIGEST_SIZE);
+    mbedtls_sha512_finish(&ctx, output);
+
+    mbedtls_sha512_free(&ctx);
+}
+/*
+ * output = MD-5( input buffer )
+ */
+void luat_crypto_HmacMd5(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen)
+{
+    int i;
+    psDigestContext_t ctx;
+    unsigned char k_ipad[ALI_MD5_KEY_IOPAD_SIZE] = {0};
+    unsigned char k_opad[ALI_MD5_KEY_IOPAD_SIZE] = {0};
+    unsigned char tempbuf[ALI_MD5_DIGEST_SIZE];
+
+    memset(k_ipad, 0x36, ALI_MD5_KEY_IOPAD_SIZE);
+    memset(k_opad, 0x5C, ALI_MD5_KEY_IOPAD_SIZE);
+
+    for(i=0; i<keylen; i++)
+    {
+        if(i>=ALI_MD5_KEY_IOPAD_SIZE)
+        {
+            break;
+        }
+        k_ipad[i] ^=key[i];
+        k_opad[i] ^=key[i];
+    }
+
+    tls_crypto_md5_init(&ctx);
+
+    tls_crypto_md5_update(&ctx, k_ipad, ALI_MD5_KEY_IOPAD_SIZE);
+    tls_crypto_md5_update(&ctx, input, ilen);
+    tls_crypto_md5_final(&ctx, tempbuf);
+
+    tls_crypto_md5_init(&ctx);
+
+    tls_crypto_md5_update(&ctx, k_opad, ALI_MD5_KEY_IOPAD_SIZE);
+    tls_crypto_md5_update(&ctx, tempbuf, ALI_MD5_DIGEST_SIZE);
+    tls_crypto_md5_final(&ctx, tempbuf);
+
+    memcpy(output, tempbuf, ALI_MD5_DIGEST_SIZE);
+}
+
+int l_crypto_cipher_xxx(lua_State *L, uint8_t flags) {
+    int ret = -1;
+    size_t cipher_size = 0;
+    size_t pad_size = 0;
+    size_t str_size = 0;
+    size_t key_size = 0;
+    size_t iv_size = 0;
+    const char* cipher = luaL_optlstring(L, 1, "AES-128-ECB", &cipher_size);
+    const char* pad = luaL_optlstring(L, 2, "PKCS7", &pad_size);
+    const char* str = luaL_checklstring(L, 3, &str_size);
+    const char* key = luaL_checklstring(L, 4, &key_size);
+    const char* iv = luaL_optlstring(L, 5, "", &iv_size);
+
+    luaL_Buffer buff;
+
+    if (!strcmp("AES-128-CBC", cipher)) {
+        luaL_buffinitsize(L, &buff, str_size);
+        mempcpy(buff.b, str, str_size);
+        if (flags) {
+            ret = aes_128_cbc_encrypt((const u8*)key, (const u8*)iv, (u8*)buff.b, str_size);
+        }
+        else {
+            ret = aes_128_cbc_decrypt((const u8*)key, (const u8*)iv, (u8*)buff.b, str_size);
+        }
+        if (ret == 0) {
+            luaL_pushresultsize(&buff, str_size);
+            return 1;
+        }
+    }
+    lua_pushstring(L, "");
+    return 1;
+}
+
+int luat_crypto_trng(char* buff, size_t len) {
+    tls_crypto_trng(buff, len);
+    return 0;
+}
+

+ 221 - 0
app/port/luat_fs_air101.c

@@ -0,0 +1,221 @@
+#include "luat_conf_bsp.h"
+#include "luat_base.h"
+#include "luat_fs.h"
+#define LUAT_LOG_TAG "luat.fs"
+#include "luat_log.h"
+#include "lfs_port.h"
+#include "wm_include.h"
+
+extern struct lfs_config lfs_cfg;
+extern lfs_t lfs;
+
+#ifndef LUAT_USE_FS_VFS
+
+FILE *luat_fs_fopen(const char *filename, const char *mode)
+{
+    ////LLOGD("fopen %s %s", filename, mode);
+    int ret;
+    char *t = (char *)mode;
+    int flags = 0;
+    lfs_file_t *lfsfile = NULL;
+    for (int i = 0; i < strlen(mode); i++)
+    {
+
+        switch (*(t++))
+        {
+        case 'w':
+            flags |= LFS_O_RDWR;
+            break;
+        case 'r':
+            flags |= LFS_O_RDONLY;
+            break;
+        case 'a':
+            flags |= LFS_O_APPEND;
+            break;
+        case 'b':
+            break;
+        case '+':
+            break;
+        default:
+
+            break;
+        }
+    }
+
+    lfsfile = tls_mem_alloc(sizeof(lfs_file_t));
+    if (!lfsfile)
+    {
+        return lfsfile;
+    }
+
+    ret = lfs_file_open(&lfs, lfsfile, filename, flags);
+    if (ret != 0)
+    {
+        return NULL;
+    }
+
+    return lfsfile;
+
+}
+
+int luat_fs_getc(FILE *stream)
+{
+    return getc(stream);
+}
+
+int luat_fs_fseek(FILE *stream, long int offset, int origin)
+{
+    int ret;
+    ret = lfs_file_seek(&lfs, stream, offset, origin);
+    if (ret < 0)
+    {
+        return -1;
+    }
+
+    return ret;
+}
+
+int luat_fs_ftell(FILE *stream)
+{
+    return ftell(stream);
+}
+
+int luat_fs_fclose(FILE *stream)
+{
+    int ret;
+    ret = lfs_file_close(&lfs, (lfs_dir_t *)stream);
+    if (ret != 0)
+    {
+        return 1;
+    }
+    tls_mem_free(stream);
+    return 0;
+}
+int luat_fs_feof(FILE *stream)
+{
+    return feof(stream);
+}
+int luat_fs_ferror(FILE *stream)
+{
+    return ferror(stream);
+}
+size_t luat_fs_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+    int ret;
+    ret = lfs_file_read(&lfs, stream,ptr, size * nmemb);
+    if (ret < 0)
+    {
+        return 0;
+    }
+    return  ret;
+}
+size_t luat_fs_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+    int ret;
+    ret = lfs_file_write(&lfs,stream, ptr, size * nmemb);
+    if (ret < 0)
+    {
+        return 0;
+    }
+
+    return ret;
+}
+int luat_fs_remove(const char *filename)
+{
+    int ret;
+    ret = lfs_remove(&lfs,filename);
+    if(ret != 0)
+    {
+        return 1;
+    }
+    return 0;
+}
+int luat_fs_rename(const char *old_filename, const char *new_filename)
+{
+    int ret;
+    ret = lfs_rename(&lfs, old_filename,new_filename);
+    if (ret != 0)
+    {
+       return 1;
+    }
+    return 0;
+}
+int luat_fs_fexist(const char *filename)
+{
+    FILE *fd = luat_fs_fopen(filename, "rb");
+    if (fd)
+    {
+        luat_fs_fclose(fd);
+        return 1;
+    }
+    return 0;
+}
+
+size_t luat_fs_fsize(const char *filename)
+{
+    FILE *fd;
+    size_t size = 0;
+    fd = luat_fs_fopen(filename, "rb");
+    if (fd)
+    {
+        luat_fs_fseek(fd, 0, SEEK_END);
+        size = luat_fs_ftell(fd);
+        luat_fs_fclose(fd);
+    }
+    return size;
+}
+
+int luat_fs_init(void)
+{
+    LFS_Init();
+}
+
+#else
+
+extern const struct luat_vfs_filesystem vfs_fs_lfs2;
+#ifdef LUAT_USE_VFS_INLINE_LIB
+extern const char luadb_inline_sys[];
+extern const char luadb_inline[];
+extern const struct luat_vfs_filesystem vfs_fs_luadb;
+#endif
+
+#ifdef LUAT_USE_LVGL
+#include "lvgl.h"
+void luat_lv_fs_init(void);
+void lv_bmp_init(void);
+void lv_png_init(void);
+void lv_split_jpeg_init(void);
+#endif
+
+int luat_fs_init(void) {
+    LFS_Init();
+    luat_vfs_reg(&vfs_fs_lfs2);
+	luat_fs_conf_t conf = {
+		.busname = &lfs,
+		.type = "lfs2",
+		.filesystem = "lfs2",
+		.mount_point = "/"
+	};
+	luat_fs_mount(&conf);
+	#ifdef LUAT_USE_VFS_INLINE_LIB
+	luat_vfs_reg(&vfs_fs_luadb);
+	luat_fs_conf_t conf2 = {
+		.busname = (char*)luadb_inline_sys,
+		.type = "luadb",
+		.filesystem = "luadb",
+		.mount_point = "/luadb/",
+	};
+	luat_fs_mount(&conf2);
+	#endif
+
+	#ifdef LUAT_USE_LVGL
+	luat_lv_fs_init();
+	lv_bmp_init();
+	lv_png_init();
+	lv_split_jpeg_init();
+	#endif
+
+	return 0;
+}
+
+#endif

+ 125 - 0
app/port/luat_gpio_air101.c

@@ -0,0 +1,125 @@
+#include "luat_base.h"
+#include "luat_malloc.h"
+#include "luat_msgbus.h"
+#include "luat_timer.h"
+#include "luat_gpio.h"
+#include "wm_include.h"
+#include "luat_irq.h"
+
+typedef struct wm_gpio_conf
+{
+    luat_gpio_irq_cb cb;
+    void* args;
+}wm_gpio_conf_t;
+
+
+static wm_gpio_conf_t confs[WM_IO_PB_31 + 1];
+
+static void luat_gpio_irq_callback(void *ptr)
+{
+    int pin = (int)ptr;
+    tls_clr_gpio_irq_status(pin);
+    //luat_gpio_irq_cb cb = confs[pin].cb;
+    //if (cb == NULL)
+        luat_irq_gpio_cb(pin, NULL);
+    //else
+    //   cb(pin, confs[pin].args);
+}
+
+int luat_gpio_setup(luat_gpio_t *gpio){
+    int dir = 0;
+    int attr = 0;
+    int irq = 0;
+    int ret;
+    if (gpio->pin < 0 || gpio->pin > WM_IO_PB_31) return 0;
+    switch (gpio->mode){
+        case Luat_GPIO_OUTPUT:
+            dir = WM_GPIO_DIR_OUTPUT;
+            attr = WM_GPIO_ATTR_FLOATING;
+            break;
+        case Luat_GPIO_INPUT:
+        case Luat_GPIO_IRQ:
+        {
+            dir = WM_GPIO_DIR_INPUT;
+            switch (gpio->pull)
+            {
+            case Luat_GPIO_PULLUP:
+                attr = WM_GPIO_ATTR_PULLHIGH;
+                break;
+            case Luat_GPIO_PULLDOWN:
+                attr = WM_GPIO_ATTR_PULLLOW;
+                break;
+            case Luat_GPIO_DEFAULT:
+            default:
+                attr = WM_GPIO_ATTR_FLOATING;
+                break;
+            }
+        }
+        break;
+        default:
+            dir = WM_GPIO_DIR_INPUT;
+            attr = WM_GPIO_ATTR_FLOATING;
+            break;
+    }
+    tls_gpio_cfg(gpio->pin, dir, attr);
+
+    if (gpio->mode == Luat_GPIO_IRQ)
+    {
+
+        if (gpio->irq == Luat_GPIO_RISING)
+        {
+            irq = WM_GPIO_IRQ_TRIG_RISING_EDGE;
+        }
+        else if (gpio->irq == Luat_GPIO_FALLING)
+        {
+            irq = WM_GPIO_IRQ_TRIG_FALLING_EDGE;
+        }
+        else
+        {
+            irq = WM_GPIO_IRQ_TRIG_DOUBLE_EDGE;
+        }
+        tls_clr_gpio_irq_status(gpio->pin);
+        tls_gpio_isr_register(gpio->pin, luat_gpio_irq_callback, (void *)gpio->pin);
+        // if (gpio->irq_cb) {
+        //     confs[gpio->pin].cb = gpio->irq_cb;
+        //     confs[gpio->pin].args = gpio->irq_args;
+        // }
+        tls_gpio_irq_enable(gpio->pin, irq);
+        return 0;
+    }
+    else{
+        tls_gpio_irq_disable(gpio->pin);
+    }
+    return 0;
+}
+
+int luat_gpio_set(int pin, int level)
+{
+    if (pin < 0 || pin > WM_IO_PB_31) return 0;
+    tls_gpio_write(pin, level);
+    return 0;
+}
+
+int luat_gpio_get(int pin)
+{
+    if (pin < 0 || pin > WM_IO_PB_31) return 0;
+    int re = tls_gpio_read(pin);
+    return re;
+}
+
+void luat_gpio_close(int pin)
+{
+    if (pin < 0 || pin > WM_IO_PB_31) return;
+    tls_gpio_cfg(pin, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING);
+    tls_gpio_irq_disable(pin);
+    // confs[pin].cb = NULL;
+}
+
+// int luat_gpio_set_irq_cb(int pin, luat_gpio_irq_cb cb, void* args) {
+//     if (pin < 0 || pin > WM_IO_PB_31) return -1;
+//     if (cb) {
+//         confs[pin].cb = cb;
+//         confs[pin].args = args;
+//     }
+//     return 0;
+// }

+ 51 - 0
app/port/luat_gt_air101.c

@@ -0,0 +1,51 @@
+
+#include "luat_base.h"
+#include "luat_spi.h"
+
+#ifndef u8
+#define u8 uint8_t
+#endif
+
+#define LUAT_GT_DEBUG 1
+#define LUAT_LOG_TAG "gt"
+#include "luat_log.h"
+
+luat_spi_device_t* gt_spi_dev = NULL;
+
+unsigned long r_dat_bat(unsigned long address,unsigned long DataLen,unsigned char *pBuff) {
+    #if LUAT_GT_DEBUG
+    LLOGD("r_dat_bat addr %08X len %d pBuff %X", address, DataLen,*pBuff);
+    #endif
+    if (gt_spi_dev == NULL)
+        return 0;
+    char send_buf[4] = {
+        0x03,
+        (u8)((address)>>16),
+        (u8)((address)>>8),
+        (u8)(address)
+    };
+    // luat_spi_device_send(gt_spi_dev, send_buf, 4);
+    // luat_spi_device_recv(gt_spi_dev, pBuff, DataLen);
+    luat_spi_device_transfer(gt_spi_dev, send_buf, 4, pBuff, DataLen);
+    return pBuff[0];
+}
+
+unsigned char CheckID(unsigned char CMD, unsigned long address,unsigned long byte_long,unsigned char *p_arr) {
+    #if LUAT_GT_DEBUG
+    LLOGD("CheckID CMD %02X addr %08X len %d p_arr %X", CMD, address, byte_long,*p_arr);
+    #endif
+    if (gt_spi_dev == NULL)
+        return 0;
+    char send_buf[4] = {
+        CMD,
+        (u8)((address)>>16),
+        (u8)((address)>>8),
+        (u8)(address)
+    };
+    // luat_spi_device_send(gt_spi_dev, send_buf, 4);
+    // luat_spi_device_recv(gt_spi_dev, p_arr, byte_long);
+    luat_spi_device_transfer(gt_spi_dev, send_buf, 4, p_arr, byte_long);
+    // return p_arr[0];
+    return 1;
+}
+

+ 63 - 0
app/port/luat_hwtimer_air101.c

@@ -0,0 +1,63 @@
+#include "luat_base.h"
+#include "luat_hwtimer.h"
+
+#include "luat_msgbus.h"
+
+#include "wm_timer.h"
+
+static int l_hwtimer_handler(lua_State *L, void* ptr) {
+    lua_getglobal(L, "sys_pub");
+    if (lua_isfunction(L, -1)) {
+        lua_pushstring(L, "HWTIMER_IRQ");
+        lua_call(L, 1, 0);
+    }
+    return 0;
+}
+
+static void luat_hwtimer_cb(void *arg) {
+    rtos_msg_t msg;
+    msg.handler = l_hwtimer_handler;
+    luat_msgbus_put(&msg, 0);
+}
+
+int luat_hwtimer_create(luat_hwtimer_conf_t *conf) {
+    struct tls_timer_cfg cfg = {0};
+    cfg.unit = conf->unit == 0 ? TLS_TIMER_UNIT_US : TLS_TIMER_UNIT_MS;
+    cfg.timeout = conf->timeout;
+    cfg.is_repeat = conf->is_repeat;
+    cfg.callback = luat_hwtimer_cb;
+    cfg.arg = NULL;
+    u8 id = tls_timer_create(&cfg);
+    if (id <= 5)
+        return id;
+    return -1;
+}
+
+int luat_hwtimer_start(int id) {
+    if (id < 0 || id > 5) return -1;
+    tls_timer_start(id);
+    return 0;
+}
+
+int luat_hwtimer_stop(int id) {
+    if (id < 0 || id > 5) return -1;
+    tls_timer_stop(id);
+    return 0;
+}
+
+int luat_hwtimer_read(int id) {
+    if (id < 0 || id > 5) return -1;
+    return tls_timer_read(id);
+}
+
+int luat_hwtimer_change(int id, uint32_t newtimeout) {
+    if (id < 0 || id > 5) return -1;
+    tls_timer_change(id, newtimeout);
+    return 0;
+}
+
+int luat_hwtimer_destroy(int id)  {
+    if (id < 0 || id > 5) return -1;
+    tls_timer_destroy(id);
+    return 0;
+}

+ 65 - 0
app/port/luat_i2c_air101.c

@@ -0,0 +1,65 @@
+
+#include "luat_base.h"
+#include "luat_i2c.h"
+
+#include "wm_include.h"
+#include "wm_i2c.h"
+#include <string.h>
+#include "wm_gpio_afsel.h"
+
+#define LUAT_LOG_TAG "luat.i2c"
+#include "luat_log.h"
+
+int luat_i2c_exist(int id) {
+    return id == 0;
+}
+
+int luat_i2c_setup(int id, int speed, int slaveaddr) {
+    //if (luat_i2c_exist(id) != 0) return -1;
+    if (speed == 0)
+        speed = 100 * 1000; // SLOW
+    else if (speed == 1)
+        speed = 400 * 1000; // FAST
+    else if (speed == 2)
+        speed = 800 * 1000; // SuperFast
+    wm_i2c_scl_config(WM_IO_PA_01);
+    wm_i2c_sda_config(WM_IO_PA_04);
+    tls_i2c_init(speed);
+    return 0;
+}
+
+int luat_ic2_close(int id) {
+    tls_i2c_stop();
+    return 0;
+}
+
+int luat_i2c_send(int id, int addr, void* buff, size_t len) {
+    tls_i2c_write_byte(addr << 1, 1);
+    if(WM_FAILED == tls_i2c_wait_ack())
+        return -1;
+    for (size_t i = 0; i < len; i++)
+    {
+        tls_i2c_write_byte(((u8*)buff)[i], 0);
+        if(WM_FAILED == tls_i2c_wait_ack())
+            return -1;
+    }
+    return 0;
+}
+
+int luat_i2c_recv(int id, int addr, void* buff, size_t len) {
+    tls_i2c_write_byte((addr << 1) + 1, 1);
+    if(WM_FAILED == tls_i2c_wait_ack())
+        return -1;
+    for (size_t i = 0; i < len; i++)
+    {
+        if (i == 0)
+            ((u8*)buff)[i] = tls_i2c_read_byte(1, 0);
+        else if (i == len - 1)
+            ((u8*)buff)[i] = tls_i2c_read_byte(0, 1);
+        else
+            ((u8*)buff)[i] = tls_i2c_read_byte(1, 0);
+        if(WM_FAILED == tls_i2c_wait_ack())
+            break;
+    }
+    return 0;
+}

+ 200 - 0
app/port/luat_lcdseg_air101.c

@@ -0,0 +1,200 @@
+#include "luat_base.h"
+#include "luat_lcdseg.h"
+
+#include "wm_include.h"
+#include "wm_lcd.h"
+#include "wm_regs.h"
+#include "wm_pmu.h"
+
+#define LUAT_LOG_TAG "lcdseg"
+#include "luat_log.h"
+
+int luat_lcdseg_setup(luat_lcd_options_t *opts) {
+    tls_lcd_options_t conf = {0};
+    conf.enable = 0;
+    switch (opts->bias)
+    {
+    case 0:
+        conf.bias = BIAS_STATIC;
+        break;
+    case 2:
+        conf.bias = BIAS_ONEHALF;
+        break;
+    case 3:
+        conf.bias = BIAS_ONETHIRD;
+        break;
+    case 4:
+        conf.bias = BIAS_ONEFOURTH;
+        break;
+    default:
+        LLOGD("invaild bias %d", opts->bias);
+        return -1;
+    }
+
+    switch (opts->duty)
+    {
+    case 0:
+        conf.duty = DUTY_STATIC;
+        break;
+    case 2:
+        conf.duty = DUTY_ONEHALF;
+        break;
+    case 3:
+        conf.duty = DUTY_ONETHIRD;
+        break;
+    case 4:
+        conf.duty = DUTY_ONEFOURTH;
+        break;
+    case 5:
+        conf.duty = DUTY_ONEFIFTH;
+        break;
+    case 6:
+        conf.duty = DUTY_ONESIXTH;
+        break;
+    case 7:
+        conf.duty = DUTY_ONESEVENTH;
+        break;
+    case 8:
+        conf.duty = DUTY_ONEEIGHTH;
+        break;
+    default:
+        LLOGD("invaild duty %d", opts->bias);
+        return -1;
+    }
+
+
+    switch(opts->vlcd) {
+    case 27:
+        conf.vlcd = VLCD27;
+        break;
+    case 29:
+        conf.vlcd = VLCD29;
+        break;
+    case 31:
+        conf.vlcd = VLCD31;
+        break;
+    case 33:
+        conf.vlcd = VLCD33;
+        break;
+    default:
+        LLOGD("invaild vlcd %d", opts->vlcd);
+        return -1;
+    }
+
+    if (opts->com_number > 4) {
+        LLOGD("invaild com_number %d", opts->com_number);
+        return -1;
+    }
+    conf.com_number = opts->com_number;
+    conf.fresh_rate = opts->fresh_rate;
+    /**
+	tls_io_cfg_set(WM_IO_PB_25, WM_IO_OPTION6);
+	tls_io_cfg_set(WM_IO_PB_21, WM_IO_OPTION6);
+	tls_io_cfg_set(WM_IO_PB_22, WM_IO_OPTION6);
+	tls_io_cfg_set(WM_IO_PB_27, WM_IO_OPTION6);
+     */
+    if (opts->com_mark & 0x01)
+        tls_io_cfg_set(WM_IO_PB_25, WM_IO_OPTION6);
+    if (opts->com_mark & 0x02)
+        tls_io_cfg_set(WM_IO_PB_21, WM_IO_OPTION6);
+    if (opts->com_mark & 0x04)
+        tls_io_cfg_set(WM_IO_PB_22, WM_IO_OPTION6);
+    if (opts->com_mark & 0x08)
+        tls_io_cfg_set(WM_IO_PB_27, WM_IO_OPTION6);
+    
+    // seg 0-5
+    //if (opts->seg_mark & (1 << 0))
+	//    tls_io_cfg_set(WM_IO_PB_23, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 1))
+	    tls_io_cfg_set(WM_IO_PB_26, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 2))
+	    tls_io_cfg_set(WM_IO_PB_24, WM_IO_OPTION6);
+
+	if (opts->seg_mark & (1 << 3))
+	    tls_io_cfg_set(WM_IO_PA_07, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 4))
+	    tls_io_cfg_set(WM_IO_PA_08, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 5))
+	    tls_io_cfg_set(WM_IO_PA_09, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 6))
+	    tls_io_cfg_set(WM_IO_PA_10, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 7))
+	    tls_io_cfg_set(WM_IO_PA_11, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 8))
+	    tls_io_cfg_set(WM_IO_PA_12, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 9))
+	    tls_io_cfg_set(WM_IO_PA_13, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 10))
+	    tls_io_cfg_set(WM_IO_PA_14, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 11))
+	    tls_io_cfg_set(WM_IO_PA_15, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 12))
+	    tls_io_cfg_set(WM_IO_PB_00, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 13))
+	    tls_io_cfg_set(WM_IO_PB_01, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 14))
+	    tls_io_cfg_set(WM_IO_PB_02, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 15))
+	    tls_io_cfg_set(WM_IO_PB_03, WM_IO_OPTION6);
+
+    if (opts->seg_mark & (1 << 16))
+	    tls_io_cfg_set(WM_IO_PB_04, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 17))
+	    tls_io_cfg_set(WM_IO_PB_05, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 18))
+	    tls_io_cfg_set(WM_IO_PB_06, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 19))
+	    tls_io_cfg_set(WM_IO_PB_07, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 20))
+	    tls_io_cfg_set(WM_IO_PB_08, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 21))
+	    tls_io_cfg_set(WM_IO_PB_09, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 22))
+	    tls_io_cfg_set(WM_IO_PB_10, WM_IO_OPTION6);	
+	if (opts->seg_mark & (1 << 23))
+	    tls_io_cfg_set(WM_IO_PB_11, WM_IO_OPTION6);
+    
+    
+	if (opts->seg_mark & (1 << 24))
+	    tls_io_cfg_set(WM_IO_PB_12, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 25))
+	    tls_io_cfg_set(WM_IO_PB_13, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 26))
+	    tls_io_cfg_set(WM_IO_PB_14, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 27))
+	    tls_io_cfg_set(WM_IO_PB_15, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 28))
+	    tls_io_cfg_set(WM_IO_PB_16, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 29))
+	    tls_io_cfg_set(WM_IO_PB_17, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 30))
+	    tls_io_cfg_set(WM_IO_PB_18, WM_IO_OPTION6);
+	if (opts->seg_mark & (1 << 31))
+	    tls_io_cfg_set(WM_IO_PA_06, WM_IO_OPTION6);
+
+    tls_reg_write32(HR_LCD_COM_EN, opts->com_mark);
+    tls_reg_write32(HR_LCD_SEG_EN, opts->seg_mark);
+
+    tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_LCD);
+    tls_lcd_init(&conf);
+    return 0;
+}
+
+int luat_lcdseg_enable(uint8_t enable) {
+    TLS_LCD_ENABLE(enable == 0 ? 0 : 1);
+    return 0;
+}
+
+int luat_lcdseg_power(uint8_t enable) {
+    TLS_LCD_POWERDOWM(enable == 0 ? 1 : 0);
+    return 0;
+}
+
+int luat_lcdseg_seg_set(uint8_t com, uint32_t seg, uint8_t val) {
+    if (com > 4)
+        return -1;
+    if (seg > 32)
+        return -1;
+    tls_lcd_seg_set(com, seg, val == 0 ? 0 : 1);
+    return 0;
+}

+ 44 - 0
app/port/luat_lib_gtfont.c

@@ -0,0 +1,44 @@
+#include "luat_base.h"
+#include "luat_spi.h"
+
+#include "GT5SLCD2E_1A.h"
+#define LUAT_LOG_TAG "gt"
+#include "luat_log.h"
+
+extern luat_spi_device_t* gt_spi_dev;
+
+static int l_gtfont_init(lua_State* L) {
+    if (gt_spi_dev == NULL) {
+        gt_spi_dev = lua_touserdata(L, 1);
+    }
+    return 0;
+}
+
+static VECFONT_ST fst;
+
+static int l_gtfont_test(lua_State* L) {
+    fst.fontCode = luaL_checkinteger(L, 1);
+    fst.type = luaL_checkinteger(L, 2);
+    fst.size = luaL_checkinteger(L, 3);
+    fst.thick = luaL_checkinteger(L, 4);
+    LLOGD("fontCode %04X type %02X size %02X thick %02X", fst.fontCode, fst.type, fst.size, fst.thick);
+    int w = get_font_st(&fst);
+    LLOGD("get_font_st ret %02X", w);
+
+    // TODO 按位显示出来
+
+    return 0;
+}
+
+#include "rotable.h"
+static const rotable_Reg reg_gtfont[] =
+{
+    { "init" ,          l_gtfont_init , 0},
+    { "test" ,          l_gtfont_test , 0},
+	{ NULL,             NULL ,        0}
+};
+
+LUAMOD_API int luaopen_gtfont( lua_State *L ) {
+    luat_newlib(L, reg_gtfont);
+    return 1;
+}

+ 62 - 0
app/port/luat_lib_nimble.c

@@ -0,0 +1,62 @@
+#include "luat_base.h"
+#include "luat_msgbus.h"
+#include "luat_malloc.h"
+#include "luat_spi.h"
+
+#include "luat_nimble.h"
+
+#define LUAT_LOG_TAG "nimble"
+#include "luat_log.h"
+
+static int l_nimble_init(lua_State* L) {
+    int rc = 0;
+    rc = luat_nimble_init(0xFF);
+    if (rc) {
+        lua_pushboolean(L, 0);
+        lua_pushinteger(L, rc);
+        return 2;
+    }
+    else {
+        lua_pushboolean(L, 1);
+        return 1;
+    }
+}
+
+static int l_nimble_deinit(lua_State* L) {
+    int rc = 0;
+    rc = luat_nimble_deinit();
+    if (rc) {
+        lua_pushboolean(L, 0);
+        lua_pushinteger(L, rc);
+        return 2;
+    }
+    else {
+        lua_pushboolean(L, 1);
+        return 1;
+    }
+}
+
+static int l_nimble_debug(lua_State* L) {
+    int level;
+    if (lua_gettop(L) > 0)
+        level = luat_nimble_trace_level(luaL_checkinteger(L, 1));
+    else
+        level = luat_nimble_trace_level(-1);
+    lua_pushinteger(L, level);
+    return 1;
+}
+
+#include "rotable.h"
+static const rotable_Reg reg_nimble[] =
+{
+	{ "init",           l_nimble_init,      0},
+    { "deinit",         l_nimble_deinit,      0},
+    { "debug",          l_nimble_debug,     0},
+	{ NULL,             NULL ,              0}
+};
+
+LUAMOD_API int luaopen_nimble( lua_State *L ) {
+    luat_newlib(L, reg_nimble);
+    return 1;
+}
+

+ 34 - 0
app/port/luat_log.h

@@ -0,0 +1,34 @@
+
+
+#ifndef LUAT_LOG
+#define LUAT_LOG
+
+#define LUAT_LOG_DEBUG 1
+#define LUAT_LOG_INFO  2
+#define LUAT_LOG_WARN  3
+#define LUAT_LOG_ERROR 4
+#define LUAT_LOG_CLOSE 7
+
+void luat_print(const char* _str);
+void luat_nprint(char *s, size_t l);
+void luat_log_set_uart_port(int port);
+
+void luat_log_set_level(int level);
+int luat_log_get_level(void);
+void luat_log_log(int level, const char* tag, const char* _fmt, ...);
+// void luat_log_debug(const char* tag, const char* _fmt, ...);
+// void luat_log_info(const char* tag, const char* _fmt, ...);
+// void luat_log_warn(const char* tag, const char* _fmt, ...);
+// void luat_log_error(const char* tag, const char* _fmt, ...);
+
+#define LLOGE(format, ...) printf("E/" LUAT_LOG_TAG " " format "\n", ##__VA_ARGS__)
+#define LLOGW(format, ...) printf("W/" LUAT_LOG_TAG " " format "\n", ##__VA_ARGS__)
+#define LLOGI(format, ...) printf("I/" LUAT_LOG_TAG " " format "\n", ##__VA_ARGS__)
+#define LLOGD(format, ...) printf("D/" LUAT_LOG_TAG " " format "\n", ##__VA_ARGS__)
+
+// #define luat_log_error(XTAG, format, ...)   luat_log_log(LUAT_LOG_ERROR, XTAG, format, ##__VA_ARGS__)
+// #define luat_log_warn(XTAG, format, ...)    luat_log_log(LUAT_LOG_WARN, XTAG, format, ##__VA_ARGS__)
+// #define luat_log_info(XTAG, format, ...)    luat_log_log(LUAT_LOG_INFO, XTAG, format, ##__VA_ARGS__)
+// #define luat_log_debug(XTAG, format, ...)   luat_log_log(LUAT_LOG_DEBUG, XTAG, format, ##__VA_ARGS__)
+
+#endif

+ 80 - 0
app/port/luat_malloc_air101.c

@@ -0,0 +1,80 @@
+
+// 这个文件包含 系统heap和lua heap的默认实现
+
+
+#include <stdlib.h>
+#include <string.h>//add for memset
+#include "bget.h"
+#include "luat_malloc.h"
+
+#define LUAT_LOG_TAG "heap"
+#include "luat_log.h"
+#include "wm_mem.h"
+
+//------------------------------------------------
+//  管理系统内存
+
+void* luat_heap_malloc(size_t len) {
+    return tls_mem_alloc(len);
+}
+
+void luat_heap_free(void* ptr) {
+    tls_mem_free(ptr);
+}
+
+void* luat_heap_realloc(void* ptr, size_t len) {
+    return tls_mem_realloc(ptr, len);
+}
+
+void* luat_heap_calloc(size_t count, size_t _size) {
+    return tls_mem_calloc(count, _size);
+}
+//------------------------------------------------
+
+//------------------------------------------------
+// ---------- 管理 LuaVM所使用的内存----------------
+void* __attribute__((section (".ram_run"))) luat_heap_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
+    if (0) {
+        if (ptr) {
+            if (nsize) {
+                // 缩放内存块
+                LLOGD("realloc %p from %d to %d", ptr, osize, nsize);
+            }
+            else {
+                // 释放内存块
+                LLOGD("free %p ", ptr);
+                brel(ptr);
+                return NULL;
+            }
+        }
+        else {
+            // 申请内存块
+            ptr = bget(nsize);
+            LLOGD("malloc %p type=%d size=%d", ptr, osize, nsize);
+            return ptr;
+        }
+    }
+
+    if (nsize)
+    {
+    	void* ptmp = bgetr(ptr, nsize);
+    	if(ptmp == NULL && osize >= nsize)
+    	{
+    		return ptr;
+    	}
+        return ptmp;
+    }
+    brel(ptr);
+    return NULL;
+}
+
+void luat_meminfo_luavm(size_t *total, size_t *used, size_t *max_used) {
+	long curalloc, totfree, maxfree;
+	unsigned long nget, nrel;
+	bstats(&curalloc, &totfree, &maxfree, &nget, &nrel);
+	*used = curalloc;
+	*max_used = bstatsmaxget();
+    *total = curalloc + totfree;
+}
+
+//-----------------------------------------------------------------------------

+ 59 - 0
app/port/luat_mcu_air101.c

@@ -0,0 +1,59 @@
+#include "luat_base.h"
+#include "luat_mcu.h"
+
+#include "wm_include.h"
+#include "wm_cpu.h"
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+/*
+enum CPU_CLK{
+	CPU_CLK_240M = 2,
+	CPU_CLK_160M = 3,
+	CPU_CLK_80M  = 6,
+	CPU_CLK_40M  = 12,
+	CPU_CLK_2M  = 240,
+};
+*/
+int luat_mcu_set_clk(size_t mhz) {
+    switch(mhz) {
+        case 240:
+            tls_sys_clk_set(CPU_CLK_240M);
+            break;
+        case 160:
+            tls_sys_clk_set(CPU_CLK_160M);
+            break;
+        case 80:
+            tls_sys_clk_set(CPU_CLK_80M);
+            break;
+        case 40:
+            tls_sys_clk_set(CPU_CLK_40M);
+            break;
+        case 2:
+            tls_sys_clk_set(CPU_CLK_2M);
+            break;
+        default :
+            return -1;
+    }
+    return 0;
+}
+
+int luat_mcu_get_clk(void) {
+    tls_sys_clk sysclk;
+    tls_sys_clk_get(&sysclk);
+    return sysclk.cpuclk;
+}
+
+static u8 unique_id[18] = {0};
+static u8 unique_id_got = 0;
+const char* luat_mcu_unique_id(size_t* t) {
+    if (!unique_id_got && tls_fls_read_unique_id(unique_id) == 0)
+        unique_id_got = 1;
+    *t = unique_id_got ? unique_id[1]+2 : 0;
+    return unique_id;
+}
+
+long luat_mcu_ticks(void) {
+    return xTaskGetTickCount();
+}

+ 46 - 0
app/port/luat_msgbus_air101.c

@@ -0,0 +1,46 @@
+
+#include "luat_msgbus.h"
+#include "wm_osal.h"
+static tls_os_queue_t *queue = NULL;
+
+void luat_msgbus_init(void)
+{
+    if (queue == NULL)
+    {
+        tls_os_queue_create(&queue, 256);
+    }
+}
+uint32_t luat_msgbus_put(rtos_msg_t *msg, size_t timeout)
+{
+    if (queue == NULL)
+    {
+        return 1;
+    }
+    rtos_msg_t* dst = luat_heap_malloc(sizeof(rtos_msg_t));
+    memcpy(dst, msg, sizeof(rtos_msg_t));
+    int ret = tls_os_queue_send(queue, (void *)dst, sizeof(rtos_msg_t));
+    return ret;
+}
+uint32_t luat_msgbus_get(rtos_msg_t *_msg, size_t timeout)
+{
+    if (queue == NULL)
+    {
+        return 1;
+    }
+    void* msg;
+    int ret = tls_os_queue_receive(queue, (void **)&msg, sizeof(rtos_msg_t), timeout);
+    if (ret == TLS_OS_SUCCESS) {
+        memcpy(_msg, (rtos_msg_t*)msg, sizeof(rtos_msg_t));
+        luat_heap_free(msg);
+        return 0;
+    }
+    return -1;
+}
+uint32_t luat_msgbus_freesize(void)
+{
+    if (queue == NULL)
+    {
+        return 1;
+    }
+    return 1;
+}

+ 222 - 0
app/port/luat_nimble.c

@@ -0,0 +1,222 @@
+#include "luat_base.h"
+#include "luat_nimble.h"
+
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <assert.h>
+
+#include "wm_bt_config.h"
+
+#include "wm_bt.h"
+#include "wm_bt_util.h"
+#include "host/ble_hs.h"
+#include "host/util/util.h"
+#include "nimble/nimble_port.h"
+#include "transport/uart/ble_hci_uart.h"
+#include "nimble/tls_nimble.h"
+
+#include "wm_ble_gap.h"
+#include "wm_ble_uart_if.h"
+// #include "wm_ble_server_wifi_app.h"
+#include "wm_ble_server_api_demo.h"
+// #include "wm_ble_client_api_demo.h"
+// #include "wm_ble_client_api_multi_conn_demo.h"
+
+static bool ble_system_state_on = false;
+static volatile tls_bt_state_t bt_adapter_state = WM_BT_STATE_OFF;
+
+extern tls_bt_log_level_t tls_appl_trace_level;
+
+int tls_bt_util_init(void);
+
+int luat_nimble_trace_level(int level) {
+    if (level >= 0 && level <= 6) {
+        tls_appl_trace_level = (tls_bt_log_level_t)level;
+    }
+    return tls_appl_trace_level;
+}
+
+static void xxx_ble_income(uint8_t *p_data, uint32_t length) {
+    printf("ble income len=%d ", length);
+    for (size_t i = 0; i < length; i++)
+    {
+        printf("%02X ", p_data[i]);
+    }
+    printf("\n");
+}
+
+static void app_adapter_state_changed_callback(tls_bt_state_t status)
+{
+	TLS_BT_APPL_TRACE_DEBUG("adapter status = %s\r\n", status==WM_BT_STATE_ON?"bt_state_on":"bt_state_off");
+
+    bt_adapter_state = status;
+    
+	#if (TLS_CONFIG_BLE == CFG_ON)
+
+    if(status == WM_BT_STATE_ON)
+    {
+    	TLS_BT_APPL_TRACE_VERBOSE("init base application\r\n");
+
+		//at here , user run their own applications;
+        #if 1		
+        //tls_ble_wifi_cfg_init();
+        tls_ble_server_demo_api_init(xxx_ble_income);
+        //tls_ble_client_demo_api_init(NULL);
+        //tls_ble_server_demo_hid_init();
+        //tls_ble_server_hid_uart_init();
+        //tls_ble_client_multi_conn_demo_api_init();
+        #endif        
+
+    }else
+    {
+        TLS_BT_APPL_TRACE_VERBOSE("deinit base application\r\n");
+
+        //here, user may free their application;
+        #if 1
+        // tls_ble_wifi_cfg_deinit(2);
+        tls_ble_server_demo_api_deinit();
+        // tls_ble_client_demo_api_deinit();
+        // tls_ble_client_multi_conn_demo_api_deinit();
+        #endif
+    }
+
+    #endif
+
+}
+
+
+static void
+on_sync(void)
+{
+    //int rc;
+    /* Make sure we have proper identity address set (public preferred) */
+    //rc = ble_hs_util_ensure_addr(1);
+    //assert(rc == 0);
+
+    app_adapter_state_changed_callback(WM_BT_STATE_ON);
+}
+static void
+on_reset(int reason)
+{
+    TLS_BT_APPL_TRACE_DEBUG("Resetting state; reason=%d\r\n", reason);
+    app_adapter_state_changed_callback(WM_BT_STATE_OFF);
+}
+static void
+on_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
+{
+
+    char buf[BLE_UUID_STR_LEN];
+
+    switch (ctxt->op) {
+        case BLE_GATT_REGISTER_OP_SVC:
+            TLS_BT_APPL_TRACE_DEBUG("service,uuid16 %s handle=%d (%04X)\r\n",ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),ctxt->svc.handle, ctxt->svc.handle);
+            break;
+
+        case BLE_GATT_REGISTER_OP_CHR:
+            TLS_BT_APPL_TRACE_DEBUG("charact,uuid16 %s arg %d def_handle=%d (%04X) val_handle=%d (%04X)\r\n",
+                ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
+                (int)ctxt->chr.chr_def->arg,
+                ctxt->chr.def_handle, ctxt->chr.def_handle,
+                ctxt->chr.val_handle, ctxt->chr.val_handle);
+            break;
+
+        case BLE_GATT_REGISTER_OP_DSC:
+            TLS_BT_APPL_TRACE_DEBUG("descrip, uuid16 %s arg %d handle=%d (%04X)\r\n",
+                ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
+                (int)ctxt->dsc.dsc_def->arg,
+                ctxt->dsc.handle, ctxt->dsc.handle);
+            break;
+    }
+
+    return;
+
+}
+
+
+int
+luat_nimble_init(uint8_t uart_idx)
+{
+    if(ble_system_state_on)
+    {
+        return BLE_HS_EALREADY;
+    }
+
+    memset(&ble_hs_cfg, 0, sizeof(ble_hs_cfg));
+
+    /** Security manager settings. */
+    ble_hs_cfg.sm_io_cap = MYNEWT_VAL(BLE_SM_IO_CAP),
+    ble_hs_cfg.sm_oob_data_flag = MYNEWT_VAL(BLE_SM_OOB_DATA_FLAG),
+    ble_hs_cfg.sm_bonding = MYNEWT_VAL(BLE_SM_BONDING),
+    ble_hs_cfg.sm_mitm = MYNEWT_VAL(BLE_SM_MITM),
+    ble_hs_cfg.sm_sc = MYNEWT_VAL(BLE_SM_SC),
+    ble_hs_cfg.sm_keypress = MYNEWT_VAL(BLE_SM_KEYPRESS),
+    ble_hs_cfg.sm_our_key_dist = MYNEWT_VAL(BLE_SM_OUR_KEY_DIST),
+    ble_hs_cfg.sm_their_key_dist = MYNEWT_VAL(BLE_SM_THEIR_KEY_DIST),
+
+    ble_hs_cfg.sync_cb = on_sync;
+    ble_hs_cfg.reset_cb = on_reset;
+    ble_hs_cfg.shutdown_cb = on_reset; /*same callback as on_reset */
+    ble_hs_cfg.gatts_register_cb = on_svr_register_cb;
+    ble_hs_cfg.store_status_cb = ble_store_util_status_rr;   
+    
+    /* Initialize all packages. */
+    nimble_port_init();
+
+
+
+    /*Application levels code entry*/
+    tls_ble_gap_init();
+    tls_bt_util_init();
+
+    /*Initialize the vuart interface and enable controller*/
+    ble_hci_vuart_init(uart_idx);
+    
+    /* As the last thing, process events from default event queue. */
+    tls_nimble_start();
+    
+    ble_system_state_on = true;
+
+    return 0;
+}
+
+
+int
+luat_nimble_deinit(void)
+{
+    int rc = 0;
+
+    if(!ble_system_state_on)
+    {
+        return BLE_HS_EALREADY;
+    }
+    /*Stop hs system*/
+    rc = nimble_port_stop();
+    assert(rc == 0);
+    
+    /*Stop controller and free vuart resource */
+    rc = ble_hci_vuart_deinit();
+    assert(rc == 0);
+
+    /*Free hs system resource*/
+    nimble_port_deinit();
+    
+    /*Free task stack ptr and free hs task*/
+    tls_nimble_stop();
+
+    /*Application levels resource cleanup*/
+    tls_ble_gap_deinit();
+    tls_bt_util_deinit();
+    
+    ble_system_state_on = false;
+
+    return rc;
+}
+
+
+//----------------------------------------
+// 设置广播数据
+int luat_nimble_gap_adv_set_fields() {
+    
+}
+//----------------------------------------

+ 8 - 0
app/port/luat_nimble.h

@@ -0,0 +1,8 @@
+#include "luat_base.h"
+#include "luat_msgbus.h"
+
+int luat_nimble_trace_level(int level);
+
+int luat_nimble_init(uint8_t uart_idx);
+int luat_nimble_deinit();
+

+ 87 - 0
app/port/luat_pm_air101.c

@@ -0,0 +1,87 @@
+#include "luat_base.h"
+#include "luat_pm.h"
+
+#include "wm_pmu.h"
+#include "wm_regs.h"
+
+#define LUAT_LOG_TAG "pm"
+#include "luat_log.h"
+
+int luat_pm_request(int mode) {
+    if (mode == LUAT_PM_SLEEP_MODE_LIGHT) {
+        tls_pmu_sleep_start();
+        return 0;
+    }
+    else if (mode == LUAT_PM_SLEEP_MODE_DEEP || mode == LUAT_PM_SLEEP_MODE_STANDBY) {
+        tls_pmu_standby_start();
+        return 0;
+    }
+    return -1;
+}
+
+//int luat_pm_release(int mode);
+
+int luat_pm_dtimer_start(int id, size_t timeout) {
+    if (id == 0 && timeout > 0) {
+        // 单位秒
+        tls_pmu_timer0_start((timeout + 999) / 1000);
+        return 0;
+    }
+    else if (id == 1 && timeout > 0) {
+        // 单位毫妙
+        tls_pmu_timer1_start(timeout);
+        return 0;
+    }
+    return -1;
+}
+
+int luat_pm_dtimer_stop(int id) {
+    if (id == 0) {
+        tls_pmu_timer0_stop();
+        return 0;
+    }
+    else if (id == 1) {
+        tls_pmu_timer1_stop();
+        return 0;
+    }
+    return -1;
+}
+
+int luat_pm_dtimer_check(int id) {
+    return -1;
+}
+
+//void luat_pm_cb(int event, int arg, void* args);
+
+extern int rst_sta;
+// extern int wake_src;
+int luat_pm_last_state(int *lastState, int *rtcOrPad) {
+    *rtcOrPad = 0; // 暂不支持
+    if (rst_sta & 0x01) { // bit 0 , watchdog 复位
+        *lastState = 8;
+    }
+    else if (rst_sta & 0x02) { // bit 1, 软件重启
+        *lastState = 3;
+    }
+    else {
+        *lastState = 0;
+    }
+    return 0;
+}
+
+int luat_pm_force(int mode) {
+    return luat_pm_request(mode);
+}
+
+int luat_pm_check(void) {
+    return 0;
+}
+
+int luat_pm_dtimer_wakeup_id(int* id) {
+    return 0;
+}
+
+int luat_pm_dtimer_list(size_t* count, size_t* list) {
+    *count = 0;
+    return 0;
+}

+ 385 - 0
app/port/luat_pwm_air101.c

@@ -0,0 +1,385 @@
+
+#include "luat_base.h"
+#include "luat_pwm.h"
+
+#define LUAT_LOG_TAG "luat.pwm"
+#include "luat_log.h"
+
+#include "wm_type_def.h"
+#include "wm_cpu.h"
+#include "wm_regs.h"
+#include "wm_dma.h"
+#include "wm_pwm.h"
+#include "wm_io.h"
+#include "luat_msgbus.h"
+
+uint32_t pwmDmaCap0[10]={0}; 
+uint32_t pwmDmaCap4[10]={0}; 
+
+int l_pwm_dma_capture(lua_State *L, void* ptr) {
+	int pwmH,pwmL,pulse;
+    // 给 sys.publish方法发送数据
+    rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
+    int channel = msg->arg1;
+	if (channel ==0){
+		pwmH = (int)(pwmDmaCap0[5]>>16);
+		pwmL = (int)(pwmDmaCap0[5]&0x0000ffff);
+		pulse = pwmH*100/(pwmH+pwmL);
+	}else if(channel ==4){
+		pwmH = (int)(pwmDmaCap4[5]>>16);
+		pwmL = (int)(pwmDmaCap4[5]&0x0000ffff);
+		pulse = pwmH*100/(pwmH+pwmL);
+	}
+	lua_getglobal(L, "sys_pub");
+    if (lua_isnil(L, -1)) {
+        lua_pushinteger(L, 0);
+        return 1;
+    }
+	lua_pushstring(L, "PWM_CAPTURE");
+	lua_pushinteger(L, channel);
+	lua_pushinteger(L, pulse);
+	lua_pushinteger(L, pwmH);
+	lua_pushinteger(L, pwmL);
+	lua_call(L, 5, 0);
+    return 0;
+}
+
+static void pwm_dma_callback(void * channel)
+{
+	rtos_msg_t msg={0};
+	msg.handler = l_pwm_dma_capture;
+	msg.arg1 = (int)channel;
+	luat_msgbus_put(&msg, 0);
+	tls_pwm_stop(channel);
+}
+
+// @return -1 打开失败。 0 打开成功
+int luat_pwm_open(int channel, size_t period, size_t pulse,int pnum) {
+    int ret = -1;
+    switch (channel)
+	{
+#ifdef AIR101
+		case 0:
+			wm_pwm0_config(WM_IO_PB_00);
+			break;
+		case 1:
+			wm_pwm1_config(WM_IO_PB_01);
+			break;
+		case 2:
+			wm_pwm2_config(WM_IO_PB_02);
+			break;
+		case 3:
+			wm_pwm3_config(WM_IO_PB_03);
+			break;
+		case 4:
+			wm_pwm4_config(WM_IO_PA_07);
+			break;
+#else
+		case 00:
+			wm_pwm0_config(WM_IO_PB_00);
+			break;
+		case 10:
+			wm_pwm0_config(WM_IO_PB_19);
+			break;
+		case 20:
+			wm_pwm0_config(WM_IO_PA_02);
+			break;
+		case 30:
+			wm_pwm0_config(WM_IO_PA_10);
+			break;
+		case 40:
+			wm_pwm0_config(WM_IO_PB_12);
+			break;
+		case 01:
+			wm_pwm1_config(WM_IO_PB_01);
+			break;
+		case 11:
+			wm_pwm1_config(WM_IO_PB_20);
+			break;
+		case 21:
+			wm_pwm1_config(WM_IO_PA_03);
+			break;
+		case 31:
+			wm_pwm1_config(WM_IO_PA_11);
+			break;
+		case 41:
+			wm_pwm1_config(WM_IO_PB_13);
+			break;
+		case 02:
+			wm_pwm2_config(WM_IO_PA_00);
+			break;
+		case 12:
+			wm_pwm2_config(WM_IO_PB_02);
+			break;
+		case 22:
+			wm_pwm2_config(WM_IO_PA_12);
+			break;
+		case 32:
+			wm_pwm2_config(WM_IO_PB_14);
+			break;
+		case 42:
+			wm_pwm2_config(WM_IO_PB_24);
+			break;
+		case 03:
+			wm_pwm3_config(WM_IO_PA_01);
+			break;
+		case 13:
+			wm_pwm3_config(WM_IO_PB_03);
+			break;
+		case 23:
+			wm_pwm3_config(WM_IO_PA_13);
+			break;
+		case 33:
+			wm_pwm3_config(WM_IO_PB_15);
+			break;
+		case 43:
+			wm_pwm3_config(WM_IO_PB_25);
+			break;
+		case 04:
+			wm_pwm4_config(WM_IO_PA_04);
+			break;
+		case 14:
+			wm_pwm4_config(WM_IO_PA_07);
+			break;
+		case 24:
+			wm_pwm4_config(WM_IO_PA_14);
+			break;
+		case 34:
+			wm_pwm4_config(WM_IO_PB_16);
+			break;
+		case 44:
+			wm_pwm4_config(WM_IO_PB_26);
+			break;
+#endif
+		// TODO 再选一组PWM0~PWM4
+		default:
+			break;
+	}
+#ifdef AIR103
+	channel = channel%10;
+#endif
+    tls_pwm_stop(channel);
+    ret = tls_pwm_init(channel, period, pulse*2.55, pnum);
+    if(ret != WM_SUCCESS)
+        return ret;
+    tls_pwm_start(channel);
+    return 0;
+}
+
+int luat_pwm_capture(int channel,int freq) {
+	uint8_t dmaCh;
+	struct tls_dma_descriptor DmaDesc;
+	tls_sys_clk sysclk;
+	tls_sys_clk_get(&sysclk);
+    switch (channel){
+#ifdef AIR101
+		case 0:
+			memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
+			wm_pwm0_config(WM_IO_PB_00);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+		case 4:
+			memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
+			wm_pwm4_config(WM_IO_PA_07);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+#else
+		case 00:
+			channel = channel%10;
+			memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
+			wm_pwm0_config(WM_IO_PB_00);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+		case 10:
+			channel = channel%10;
+			memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
+			wm_pwm0_config(WM_IO_PB_19);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+		case 20:
+			memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
+			wm_pwm0_config(WM_IO_PA_02);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+		case 30:
+			channel = channel%10;
+			memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
+			wm_pwm0_config(WM_IO_PA_10);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+		case 40:
+			channel = channel%10;
+			memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
+			wm_pwm0_config(WM_IO_PB_12);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+		case 04:
+			channel = channel%10;
+			memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
+			wm_pwm4_config(WM_IO_PA_04);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+		case 14:
+			channel = channel%10;
+			memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
+			wm_pwm4_config(WM_IO_PA_07);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+		case 24:
+			channel = channel%10;
+			memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
+			wm_pwm4_config(WM_IO_PA_14);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+		case 34:
+			channel = channel%10;
+			memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
+			wm_pwm4_config(WM_IO_PB_16);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+		case 44:
+			channel = channel%10;
+			memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
+			wm_pwm4_config(WM_IO_PB_26);
+			tls_pwm_stop(channel);
+			dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
+			DmaDesc.src_addr = HR_PWM_CAPDAT;
+			DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
+			DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
+			DmaDesc.valid = TLS_DMA_DESC_VALID;
+			DmaDesc.next = NULL;
+			tls_dma_start(dmaCh, &DmaDesc, 0);
+			tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
+			tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
+			tls_pwm_start(channel); 
+			return 0;
+#endif
+		// TODO 再选一组PWM0~PWM4
+		default:
+			break;
+	}
+    return -1;
+}
+
+// @return -1 关闭失败。 0 关闭成功
+int luat_pwm_close(int channel) {
+    int ret = -1;
+#ifdef AIR103
+	channel = channel%10;
+#endif
+    ret = tls_pwm_stop(channel);
+    if(ret != WM_SUCCESS)
+        return ret;
+    return 0;
+}
+

+ 57 - 0
app/port/luat_rtc_air101.c

@@ -0,0 +1,57 @@
+#include "luat_rtc.h"
+#include "luat_msgbus.h"
+#include "wm_rtc.h"
+
+#define LUAT_LOG_TAG "rtc"
+#include "luat_log.h"
+
+extern int Base_year;
+
+static int luat_rtc_handler(lua_State *L, void* ptr) {
+    lua_getglobal(L, "sys_pub");
+    if (lua_isfunction(L, -1)) {
+        lua_pushstring(L, "RTC_IRQ");
+        lua_call(L, 1, 0);
+    }
+    return 0;
+}
+
+static void luat_rtc_cb(void *arg) {
+    //LLOGI("rtc irq");
+    rtos_msg_t msg;
+    msg.handler = luat_rtc_handler;
+    luat_msgbus_put(&msg, 0);
+}
+
+int luat_rtc_set(struct tm *tblock) {
+    if (tblock == NULL)
+        return -1;
+    tblock->tm_year -= Base_year;
+    tblock->tm_mon--;
+    tls_set_rtc(tblock);
+    return 0;
+}
+
+int luat_rtc_get(struct tm *tblock) {
+    if (tblock == NULL)
+        return -1;
+    tls_get_rtc(tblock);
+    tblock->tm_year += Base_year;
+    tblock->tm_mon++;
+    return 0;
+}
+
+int luat_rtc_timer_start(int id, struct tm *tblock) {
+    if (id || tblock == NULL)
+        return -1;
+    tblock->tm_year -= Base_year;
+    tblock->tm_mon--;
+    tls_rtc_isr_register(luat_rtc_cb, NULL);
+    tls_rtc_timer_start(tblock);
+}
+
+int luat_rtc_timer_stop(int id) {
+    if (id)
+        return -1;
+    tls_rtc_timer_stop();
+}

+ 80 - 0
app/port/luat_sdio_air101.c

@@ -0,0 +1,80 @@
+
+#include "luat_base.h"
+#include "luat_sdio.h"
+
+#define LUAT_LOG_TAG "luat.sdio"
+#include "luat_log.h"
+
+#include "wm_sdio_host.h"
+#include "luat_fs.h"
+#include "ff.h"
+
+FATFS fs;
+BYTE work[FF_MAX_SS];
+
+#ifdef LUAT_USE_FS_VFS
+extern const struct luat_vfs_filesystem vfs_fs_fatfs;
+#endif
+
+int luat_sdio_init(int id){
+	if (id == 0) {
+		wm_sdio_host_config(0);
+		return 0;
+	}
+#ifdef AIR103
+	else if (id == 1) {
+		wm_sdio_host_config(1);
+		return 0;
+	}
+#endif
+	return -1;
+}
+
+int luat_sdio_sd_read(int id, int rca, char* buff, size_t offset, size_t len){
+	return wm_sd_card_blocks_read(rca, offset, buff, len);
+}
+
+int luat_sdio_sd_write(int id, int rca, char* buff, size_t offset, size_t len){
+	return wm_sd_card_blocks_write(rca, offset, buff, len);
+}
+
+int luat_sdio_sd_mount(int id, int *rca, char* path,int auto_format){
+	FRESULT res_sd;
+	res_sd = f_mount(&fs, "/", 1);
+	if (res_sd) {
+		LLOGD("mount ret = %d", res_sd);
+		if (res_sd == FR_NO_FILESYSTEM && auto_format) {
+			res_sd = f_mkfs("/", 0, work, sizeof(work));
+			if(res_sd == FR_OK){
+				res_sd = f_mount(NULL, "/", 1);
+				res_sd = f_mount(&fs, "/", 1);
+			}
+			else {
+				LLOGD("format ret = %d", res_sd);
+			}
+		}
+	}
+	if (res_sd != FR_OK) {
+		return res_sd;
+	}
+#ifdef LUAT_USE_FS_VFS
+	luat_vfs_reg(&vfs_fs_fatfs);
+	luat_fs_conf_t conf = {
+		.busname = &fs,
+		.type = "fatfs",
+		.filesystem = "fatfs",
+		.mount_point = path, 
+	};
+	luat_fs_mount(&conf);
+#endif
+	return 0;
+}
+
+int luat_sdio_sd_unmount(int id, int rca){
+	return f_mount(NULL, "/", 1);
+}
+
+int luat_sdio_sd_format(int id, int rca){
+	f_mkfs("/", 0, work, sizeof(work));
+	return 0;
+}

+ 66 - 0
app/port/luat_sfd_onchip_air101.c

@@ -0,0 +1,66 @@
+#include "luat_base.h"
+#include "luat_sfd.h"
+
+#ifdef LUAT_SFD_ONCHIP
+
+#define LUAT_LOG_TAG "onchip"
+#include "luat_log.h"
+
+#include "wm_include.h"
+#include "wm_flash_map.h"
+#include "wm_internal_flash.h"
+
+int sfd_onchip_init (void* userdata) {
+    sfd_onchip_t* onchip = (sfd_onchip_t*)userdata;
+    if (onchip == NULL)
+        return -1;
+    return 0;
+}
+
+int sfd_onchip_status (void* userdata) {
+    return 0;
+}
+
+int sfd_onchip_read (void* userdata, char* buff, size_t offset, size_t len) {
+    int ret;
+    sfd_onchip_t* onchip = (sfd_onchip_t*)userdata;
+    if (onchip == NULL)
+        return -1;
+    ret = tls_fls_read(offset + onchip->addr, (u8 *)buff, len);
+    if (ret != TLS_FLS_STATUS_OK)
+    {
+        return -1;
+    }
+    return 0;
+}
+
+int sfd_onchip_write (void* userdata, const char* buff, size_t offset, size_t len) {
+    int ret;
+    sfd_onchip_t* onchip = (sfd_onchip_t*)userdata;
+    if (onchip == NULL)
+        return -1;
+    ret = tls_fls_write(offset + onchip->addr, (u8 *)buff, len);
+    if (ret != TLS_FLS_STATUS_OK)
+    {
+        return -1;
+    }
+    return 0;
+}
+int sfd_onchip_erase (void* userdata, size_t offset, size_t len) {
+    int ret;
+    sfd_onchip_t* onchip = (sfd_onchip_t*)userdata;
+    if (onchip == NULL)
+        return -1;
+    ret = tls_fls_erase(offset + onchip->addr);
+    if (ret != TLS_FLS_STATUS_OK)
+    {
+        return -1;
+    }
+    return 0;
+}
+
+int sfd_onchip_ioctl (void* userdata, size_t cmd, void* buff) {
+    return 0;
+}
+
+#endif

+ 53 - 0
app/port/luat_shell_air101.c

@@ -0,0 +1,53 @@
+#include "luat_shell.h"
+#include "wm_include.h"
+
+#define LUAT_LOG_TAG "luat.shell"
+#include "luat_log.h"
+
+static int drv = -1;
+#define CONSOLE_BUF_SIZE   512
+
+typedef struct console_st
+{
+    size_t rx_data_len;
+    char rx_buf[CONSOLE_BUF_SIZE];		/*uart rx*/
+} console;
+
+static console 	ShellConsole;
+
+void luat_shell_write(char* buff, size_t len) {
+    if (drv > -1 && len >= 0) {
+        tls_uart_write(drv, buff, len);
+    }
+}
+
+char* luat_shell_read(size_t *len) {
+    if(ShellConsole.rx_data_len == 0)
+    {
+        *len = 0;
+        return NULL;
+    }
+    if (ShellConsole.rx_data_len > CONSOLE_BUF_SIZE)
+        ShellConsole.rx_data_len = CONSOLE_BUF_SIZE;
+    int ret = tls_uart_read(drv, ShellConsole.rx_buf, ShellConsole.rx_data_len);
+    *len = ret;
+    return ShellConsole.rx_buf;
+}
+
+void luat_shell_notify_recv(void) {
+    ShellConsole.rx_data_len = 0;
+}
+
+int16_t demo_console_rx(uint16_t len, void* user_data){
+    ShellConsole.rx_data_len += len;
+    luat_shell_notify_read();
+    return 0;
+}
+
+void luat_shell_poweron(int _drv) {
+    drv = _drv;
+    memset(ShellConsole.rx_buf, 0, CONSOLE_BUF_SIZE + 1);
+    tls_uart_rx_callback_register(drv,(int16_t(*)(uint16_t, void*))demo_console_rx, NULL);
+    luat_shell_notify_recv();
+}
+

+ 161 - 0
app/port/luat_spi_air101.c

@@ -0,0 +1,161 @@
+
+
+#include "luat_base.h"
+#include "luat_spi.h"
+
+#include "wm_include.h"
+
+#include "wm_hostspi.h"
+#include "wm_gpio_afsel.h"
+#include "wm_cpu.h"
+
+#define LUAT_LOG_TAG "luat.spi"
+#include "luat_log.h"
+
+int luat_spi_device_config(luat_spi_device_t* spi_dev) {
+    unsigned int clk;
+    uint8_t TLS_SPI_MODE = 0x00 ;
+    clk = spi_dev->spi_config.bandrate;
+    tls_sys_clk sysclk;
+    tls_sys_clk_get(&sysclk);
+    if(clk / (UNIT_MHZ/2) > sysclk.apbclk)
+        clk = sysclk.apbclk * (UNIT_MHZ/2);
+    if(spi_dev->spi_config.CPHA)
+        TLS_SPI_MODE |= SPI_CPHA;
+    if(spi_dev->spi_config.CPOL)
+        TLS_SPI_MODE |= SPI_CPOL;
+    return tls_spi_setup(TLS_SPI_MODE, TLS_SPI_CS_LOW, clk);
+}
+
+int luat_spi_bus_setup(luat_spi_device_t* spi_dev){
+    int bus_id = spi_dev->bus_id;
+    if (bus_id == 0){
+        wm_spi_ck_config(WM_IO_PB_02);
+        wm_spi_di_config(WM_IO_PB_03);
+        wm_spi_do_config(WM_IO_PB_05);
+        return 0;
+    }
+    #ifdef AIR103
+    else if (bus_id == 1) { // 本质上是mode=1,不是spi1,该模式下psram可用
+	    wm_spi_ck_config(WM_IO_PB_15);
+	    wm_spi_di_config(WM_IO_PB_16);
+	    wm_spi_do_config(WM_IO_PB_17);
+    }
+    else if (bus_id == 2) { // 本质上是mode=2,不是spi2,该模式下psram可用
+	    wm_spi_ck_config(WM_IO_PB_24);
+	    wm_spi_di_config(WM_IO_PB_25);
+	    wm_spi_do_config(WM_IO_PB_26);
+    }
+    #endif
+    else{
+        LLOGD("spi_bus error");
+        return -1;
+    }
+    tls_spi_trans_type(SPI_BYTE_TRANSFER);
+}
+
+//初始化配置SPI各项参数,并打开SPI
+//成功返回0
+int luat_spi_setup(luat_spi_t* spi) {
+    int ret;
+    unsigned int clk;
+    uint8_t TLS_SPI_MODE = 0x00 ;
+    if (spi->id == 0) {
+	    // 兼容CS=0,默认配置, 也兼容CS为GPIO20的配置,其他配置不受控,自然不应该配置CS脚
+        if (spi->cs == 0 || spi->cs == WM_IO_PB_04)
+	        wm_spi_cs_config(WM_IO_PB_04);
+            wm_spi_ck_config(WM_IO_PB_02);
+            wm_spi_di_config(WM_IO_PB_03);
+            wm_spi_do_config(WM_IO_PB_05);
+    }
+    #ifdef AIR103
+    else if (spi->id == 1) { // 本质上是mode=1,不是spi1,该模式下psram可用
+        if (spi->cs == 0 || spi->cs == WM_IO_PB_14)
+	        wm_spi_cs_config(WM_IO_PB_14);
+	    wm_spi_ck_config(WM_IO_PB_15);
+	    wm_spi_di_config(WM_IO_PB_16);
+	    wm_spi_do_config(WM_IO_PB_17);
+    }
+    else if (spi->id == 2) { // 本质上是mode=2,不是spi2,该模式下psram可用
+        if (spi->cs == 0 || spi->cs == WM_IO_PB_23)
+	        wm_spi_cs_config(WM_IO_PB_23);
+	    wm_spi_ck_config(WM_IO_PB_24);
+	    wm_spi_di_config(WM_IO_PB_25);
+	    wm_spi_do_config(WM_IO_PB_26);
+    }
+    #endif
+    else {
+        return -1;
+    }
+
+    if(spi->CPHA)
+        TLS_SPI_MODE |= SPI_CPHA;
+    if(spi->CPOL)
+        TLS_SPI_MODE |= SPI_CPOL;
+    clk = spi->bandrate;
+
+    tls_sys_clk sysclk;
+    tls_sys_clk_get(&sysclk);
+    if(clk / (UNIT_MHZ/2) > sysclk.apbclk)
+        clk = sysclk.apbclk * (UNIT_MHZ/2);
+
+    tls_spi_trans_type(SPI_BYTE_TRANSFER);
+    ret = tls_spi_setup(TLS_SPI_MODE, TLS_SPI_CS_LOW, clk);
+
+    return ret;
+}
+
+//关闭SPI,成功返回0
+int luat_spi_close(int spi_id) {
+    return 0;
+}
+//收发SPI数据,返回接收字节数
+int luat_spi_transfer(int spi_id, const char* send_buf, size_t send_length, char* recv_buf, size_t recv_length){
+    tls_spi_read_with_cmd(send_buf, send_length, recv_buf, recv_length);
+    return recv_length;
+}
+//收SPI数据,返回接收字节数
+int luat_spi_recv(int spi_id, char* recv_buf, size_t length) {
+    int ret;
+    if(length <= SPI_DMA_BUF_MAX_SIZE)
+    {
+        ret = tls_spi_read(recv_buf,length);
+    }
+    else
+    {
+        size_t i;
+        for(i=0;i<length;i+=SPI_DMA_BUF_MAX_SIZE)
+        {
+            ret = tls_spi_read((u8*)(recv_buf+i), length - i > SPI_DMA_BUF_MAX_SIZE ? SPI_DMA_BUF_MAX_SIZE : length - i);
+            if(ret != TLS_SPI_STATUS_OK)
+                break;
+        }
+    }
+    if (ret == TLS_SPI_STATUS_OK)
+        return length;
+    else
+        return -1;
+}
+//发SPI数据,返回发送字节数
+int luat_spi_send(int spi_id, const char* send_buf, size_t length) {
+    int ret;
+    if(length <= SPI_DMA_BUF_MAX_SIZE)
+    {
+        ret = tls_spi_write(send_buf, length);
+    }
+    else
+    {
+        size_t i;
+        for(i=0;i<length;i+=SPI_DMA_BUF_MAX_SIZE)
+        {
+            ret = tls_spi_write((const u8*)(send_buf+i), length - i > SPI_DMA_BUF_MAX_SIZE ? SPI_DMA_BUF_MAX_SIZE : length - i);
+            if(ret != TLS_SPI_STATUS_OK)
+                break;
+        }
+    }
+    if (ret == TLS_SPI_STATUS_OK)
+        return length;
+    else
+        return -1;
+}
+

+ 93 - 0
app/port/luat_timer_air101.c

@@ -0,0 +1,93 @@
+
+#include "luat_base.h"
+#include "luat_malloc.h"
+#include "luat_timer.h"
+#include "luat_msgbus.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include "wm_osal.h"
+#define LUAT_LOG_TAG "luat.timer"
+#include "luat_log.h"
+
+#define FREERTOS_TIMER_COUNT 64
+static luat_timer_t* timers[FREERTOS_TIMER_COUNT] = {0};
+
+static void luat_timer_callback(void *ptmr, void *parg) {
+    // LLOGD("timer callback");
+    rtos_msg_t msg;
+    luat_timer_t *timer = (luat_timer_t*)parg;
+    msg.handler = timer->func;
+    msg.ptr = timer;
+    msg.arg1 = 0;
+    msg.arg2 = 0;
+    luat_msgbus_put(&msg, 1);
+    // LLOGD("timer msgbus re=%ld", re);
+}
+
+static int nextTimerSlot() {
+    for (size_t i = 0; i < FREERTOS_TIMER_COUNT; i++)
+    {
+        if (timers[i] == NULL) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int luat_timer_start(luat_timer_t* timer) {
+    tls_os_timer_t *os_timer = NULL;
+    int timerIndex;
+    int ret;
+    // LLOGD(">>luat_timer_start timeout=%ld", timer->timeout);
+    timerIndex = nextTimerSlot();
+    // LLOGD("timer id=%ld", timerIndex);
+    if (timerIndex < 0) {
+        return 1; // too many timer!!
+    }
+    if (timer->timeout < (1000 / configTICK_RATE_HZ))
+        timer->timeout = 1000 / configTICK_RATE_HZ;
+    ret =  tls_os_timer_create(&os_timer, luat_timer_callback, timer,(timer->timeout)/(1000 / configTICK_RATE_HZ), timer->repeat ? 1 : 0, NULL);
+    // LLOGD("timer id=%ld, osTimerNew=%08X", timerIndex, (int)timer);
+    if (TLS_OS_SUCCESS != ret)
+    {
+       return 1;
+    }
+    timers[timerIndex] = timer;
+    timer->os_timer = os_timer;
+    tls_os_timer_start(os_timer);
+    return 0;
+}
+
+int luat_timer_stop(luat_timer_t* timer) {
+    if (!timer)
+        return 1;
+    for (size_t i = 0; i < FREERTOS_TIMER_COUNT; i++)
+    {
+        if (timers[i] == timer) {
+            timers[i] = NULL;
+            break;
+        }
+    }
+    tls_os_timer_stop(timer->os_timer);
+    tls_os_timer_delete(timer->os_timer);
+    return 0;
+}
+
+luat_timer_t* luat_timer_get(size_t timer_id) {
+    for (size_t i = 0; i < FREERTOS_TIMER_COUNT; i++)
+    {
+        if (timers[i] && timers[i]->id == timer_id) {
+            return timers[i];
+        }
+    }
+    return NULL;
+}
+
+
+int luat_timer_mdelay(size_t ms) {
+    if (ms >= (1000 / configTICK_RATE_HZ)) {
+        vTaskDelay(ms / (1000 / configTICK_RATE_HZ));
+    }
+    return 0;
+}
+

+ 177 - 0
app/port/luat_uart_air101.c

@@ -0,0 +1,177 @@
+#include "luat_base.h"
+#include "luat_malloc.h"
+#include "luat_msgbus.h"
+#include "luat_uart.h"
+#define LUAT_LOG_TAG "luat.uart.101"
+#include "luat_log.h"
+
+#include "wm_include.h"
+#include "wm_uart.h"
+#include "wm_gpio_afsel.h"
+#include "stdio.h"
+//串口数量,编号从0开始
+#define MAX_DEVICE_COUNT 5
+//存放串口设备句柄
+static uint8_t serials_buff_len[MAX_DEVICE_COUNT] ={TLS_UART_RX_BUF_SIZE};
+extern struct tls_uart_port uart_port[TLS_UART_MAX];
+
+int luat_uart_exist(int uartid)
+{
+    if (uartid < 0 || uartid >= MAX_DEVICE_COUNT)
+    {
+        return 0;
+    }
+    return 1;
+}
+
+static s16 uart_input_cb(u16 len, void* user_data)
+{
+    int uartid = (int)user_data;
+    //不是fifo超时回调
+    if(uartid <= MAX_DEVICE_COUNT)
+    {
+        //未读取长度够不够?
+        if(CIRC_CNT(uart_port[uartid].recv.head, uart_port[uartid].recv.tail, TLS_UART_RX_BUF_SIZE)
+            < (serials_buff_len[uartid] - 200))
+            return 0;
+    }
+    else//是fifo超时回调
+    {
+        uartid /= 10;
+    }
+
+    rtos_msg_t msg;
+    msg.handler = l_uart_handler;
+    msg.ptr = NULL;
+    msg.arg1 = uartid;
+    msg.arg2 = CIRC_CNT(uart_port[uartid].recv.head, uart_port[uartid].recv.tail, TLS_UART_RX_BUF_SIZE);
+    luat_msgbus_put(&msg, 1);
+    return 0;
+}
+
+//串口发送完成事件回调
+static s16 uart_sent_cb(struct tls_uart_port *port)
+{
+    tls_uart_free_tx_sent_data(port);
+    rtos_msg_t msg;
+    msg.handler = l_uart_handler;
+    msg.arg1 = port->uart_no;
+    msg.arg2 = 0;
+    msg.ptr = NULL;
+    luat_msgbus_put(&msg, 1);
+    return 0;
+}
+
+int luat_uart_setup(luat_uart_t *uart)
+{
+    int ret;
+    tls_uart_options_t opt = {0};
+    if (!luat_uart_exist(uart->id))
+    {
+        return -1;
+    }
+
+    opt.baudrate = uart->baud_rate;
+    opt.charlength = (uart->data_bits)-5;
+    opt.paritytype = uart->parity;
+    opt.flow_ctrl = TLS_UART_FLOW_CTRL_NONE;
+    opt.stopbits = (uart->stop_bits)-1;
+
+    switch (uart->id)
+    {
+    case TLS_UART_0:
+        wm_uart0_rx_config(WM_IO_PB_20);
+        wm_uart0_tx_config(WM_IO_PB_19);
+        break;
+    case TLS_UART_1:
+        wm_uart1_rx_config(WM_IO_PB_07);
+        wm_uart1_tx_config(WM_IO_PB_06);
+        break;
+    case TLS_UART_2:
+        wm_uart2_rx_config(WM_IO_PB_03);
+        wm_uart2_tx_scio_config(WM_IO_PB_02);
+        break;
+    case TLS_UART_3:
+        wm_uart3_rx_config(WM_IO_PB_01);
+        wm_uart3_tx_config(WM_IO_PB_00);
+        break;
+    case TLS_UART_4:
+        wm_uart4_rx_config(WM_IO_PB_05);
+        wm_uart4_tx_config(WM_IO_PB_04);
+        break;
+    case 5:
+        wm_uart5_rx_config(WM_IO_PA_13);
+        wm_uart5_tx_config(WM_IO_PA_12);
+        break;
+    default:
+        break;
+    }
+
+    ret = tls_uart_port_init(uart->id, &opt, 0);
+    if (ret !=  WM_SUCCESS)
+    {
+       return ret; //初始化失败
+    }
+    if(uart->bufsz > TLS_UART_RX_BUF_SIZE)
+        uart->bufsz = TLS_UART_RX_BUF_SIZE;
+    if(uart->bufsz < 1024)
+        uart->bufsz = 1024;
+    serials_buff_len[uart->id] = uart->bufsz;
+
+    return ret;
+
+}
+
+
+int luat_uart_write(int uartid, void *data, size_t length)
+{
+    int ret = 0;
+    //printf("uid:%d,data:%s,length = %d\r\n",uartid, (char *)data, length);
+    if (!luat_uart_exist(uartid))
+    {
+        return 0;
+    }
+    ret = tls_uart_write(uartid, data,length);
+
+    return ret;
+}
+
+int luat_uart_read(int uartid, void *buffer, size_t length)
+{
+    int ret = 0;
+    if (!luat_uart_exist(uartid))
+    {
+        return 0;
+    }
+    ret =  tls_uart_read(uartid,(u8 *) buffer,(u16)length);
+    return ret;
+}
+
+int luat_uart_close(int uartid)
+{
+    if (!luat_uart_exist(uartid))
+    {
+        return 0;
+    }
+    // tls_uart_port_init(uartid,NULL,0);
+    return 0;
+}
+
+int luat_setup_cb(int uartid, int received, int sent)
+{
+    if (!luat_uart_exist(uartid))
+    {
+        return -1;
+    }
+    if (received)
+    {
+        tls_uart_rx_callback_register(uartid,(s16(*)(u16, void*))uart_input_cb, (void*)uartid);
+    }
+
+    if (sent)
+    {
+        tls_uart_tx_callback_register(uartid, (s16(*)(struct tls_uart_port *))uart_sent_cb);
+    }
+
+    return 0;
+}

+ 27 - 0
app/port/luat_wdt_air101.c

@@ -0,0 +1,27 @@
+
+#include "luat_base.h"
+#include "luat_wdt.h"
+
+#include "wm_include.h"
+#include "wm_watchdog.h"
+
+int luat_wdt_init(size_t timeout) {
+    if (timeout < 1000)
+        timeout = 1000;
+    tls_watchdog_init(timeout * 1000);
+    return 0;
+}
+
+int luat_wdt_set_timeout(size_t timeout) {
+    return luat_wdt_init(timeout);
+}
+
+int luat_wdt_feed(void) {
+    tls_watchdog_clr();
+    return 0;
+}
+
+int luat_wdt_close(void) {
+    tls_watchdog_deinit();
+    return 0;
+}

+ 3 - 0
build_xmake.bat

@@ -0,0 +1,3 @@
+@echo off
+xmake
+pause

+ 403 - 0
demo/console/wm_demo_console.h

@@ -0,0 +1,403 @@
+/*****************************************************************************
+*
+* File Name : wm_demo_cmd.h
+*
+* Description: demo command header
+*
+* Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd.
+* All rights reserved.
+*****************************************************************************/
+#ifndef __WM_DEMO_CMD_H__
+#define __WM_DEMO_CMD_H__
+
+#include <string.h>
+#include "wm_include.h"
+#include "wm_watchdog.h"
+#include "wm_config.h"
+
+/*****************************************************************
+	EXTERN FUNC
+*****************************************************************/
+extern int demo_connect_net(void *, ...);
+extern int demo_socket_client(void *, ...);
+extern int demo_socket_server(void *, ...);
+extern int demo_oneshot(void *, ...);
+extern int demo_socket_config(void *, ...);
+extern int demo_webserver_config(void *, ...);
+extern int demo_create_softap(void *, ...);
+extern int uart_demo(void *, ...);
+extern int ntp_demo(void *, ...);
+extern int ntp_set_server_demo(void *, ...);
+extern int ntp_query_cfg(void *, ...);
+extern int flash_demo(void *, ...);
+extern int Socket_Client_Demo(void *, ...);
+extern int sck_c_send_data_demo(void *, ...);
+extern int socket_server_demo(void *, ...);
+extern int sck_s_send_data_demo(void *, ...);
+extern int socket_udp_demo(void *, ...);
+extern int udp_send_data_demo(void *, ...);
+
+extern int apsta_demo(void *, ...);
+extern int apsta_socket_demo(void *, ...);
+extern int gpio_demo(void *, ...);
+extern int gpio_isr_test(void *, ...);
+extern int pwm_demo(void *, ...);
+extern int crypt_hard_demo(void *, ...);
+extern int wm_7816_demo(void *, ...);
+extern int rsa_demo(void *, ...);
+extern int slave_spi_demo(void *, ...);
+//extern int master_spi_demo(void *, ...);
+extern int master_spi_recv_data(void *, ...);
+extern int master_spi_send_data(void *, ...);
+extern int pmu_timer0_demo(void *, ...);
+extern int pmu_timer1_demo(void *, ...);
+extern int rtc_demo(void *, ...);
+extern int timer_demo(void *, ...);
+extern int http_fwup_demo(void *, ...);
+extern int http_get_demo(void *, ...);
+extern int http_post_demo(void *, ...);
+extern int http_put_demo(void *, ...);
+extern int socket_server_demo(void *, ...);
+extern int sck_s_send_data_demo(void *, ...);
+extern int CreateMCastDemoTask(void *, ...);
+extern int adc_input_voltage_demo(void *, ...);
+extern int adc_chip_temperature_demo(void*,...);
+extern int sd_card_test(void *, ...);
+
+extern int demo_wps_pbc(void *, ...);
+extern int demo_wps_pin(void *, ...);
+extern int demo_wps_get_pin(void *, ...);
+
+
+extern int demo_iperf_auto_test(void *, ...);
+extern int CreateSSLServerDemoTask(void *, ...);
+extern int lwsDemoTest(void *, ...);
+extern int tls_i2s_io_init(void);
+extern int tls_i2s_demo(void *, ...);
+extern int i2c_demo(void *, ...);
+extern int scan_demo(void *, ...);
+
+extern int https_demo(void *, ...);
+extern int mqtt_demo(void *, ...);
+extern int fatfs_test(void *, ...);
+extern int mbedtls_demo(void *, ...);
+
+extern int dsp_demo(void *,...);
+
+#if DEMO_BT
+extern int demo_bt_enable(void *, ...);
+extern int demo_bt_destroy(void *, ...);
+#if (TLS_CONFIG_BLE == CFG_ON)
+extern int demo_ble_server_on(void *, ...);
+extern int demo_ble_server_off(void *, ...);
+extern int demo_ble_client_on(void *, ...);
+extern int demo_ble_client_off(void *, ...);
+
+extern int demo_ble_scan(void *,...);
+extern int demo_ble_adv(void *,...);
+#endif
+
+#if (TLS_CONFIG_BR_EDR== CFG_ON)
+extern int demo_bt_app_on(void *, ...);
+extern int demo_bt_app_off(void *, ...);
+#endif
+
+#endif
+
+#if DEMO_TOUCHSENSOR
+extern int demo_touchsensor(void *, ...);
+#endif
+
+/*****************************************************************
+		LOCAL FUNC
+*****************************************************************/
+static void demo_console_show_info(char *buf);
+static int demo_console_show_help(void *p, ...);
+static int  demo_sys_reset(void *p, ...);
+
+/*****************************************************************
+		LOCAL TYPE
+*****************************************************************/
+typedef struct demo_console_st
+{
+    int rx_data_len;
+    u8 *rx_buf;		/*uart rx*/
+    u16 rptr;
+    u8 MsgNum;
+} Demo_Console;
+
+struct demo_console_info_t
+{
+    char *cmd;
+    int (*callfn)(void *, ...);
+    short type;/* perbit: 0-string, 1-number */
+    short param_cnt;
+    char *info;
+};
+
+#define DEMO_CONSOLE_CMD		1		//��������cmd
+#define DEMO_CONSOLE_SHORT_CMD	2		//CMD��һ���֣�û�н�����
+#define DEMO_CONSOLE_WRONG_CMD  3
+
+#define DEMO_BUF_SIZE		TLS_UART_RX_BUF_SIZE
+
+const char HTTP_POST[] = "t-httppost";
+const char HTTP_PUT[] = "t-httpput";
+
+
+struct demo_console_info_t  console_tbl[] =
+{
+    //To Do When Add New Demo
+#if DEMO_CONNECT_NET
+    {"t-connect", 	demo_connect_net, 0, 2, "Test connecting ap;t-connect(\"ssid\",\"pwd\"); For open ap, pwd should be empty"},
+    {"t-oneshot",     demo_oneshot,  0, 0, "Test Oneshot  configuration"},
+    //	{"t-socketcfg",  demo_socket_config, 0, 0, "Test socket configuration"},
+    {"t-webcfg",      demo_webserver_config, 0, 0, "Test web server configuration"},
+#endif
+
+#if DEMO_APSTA
+    {"t-apsta", 	apsta_demo, 0x0, 4, "Test connecting with AP by apsta mode;"},
+    {"t-asskt", 	apsta_socket_demo, 0x0, 0, "Test socket communication in apsta mode;"},
+#endif
+
+#if DEMO_SOFT_AP
+    {"t-softap", 	demo_create_softap, 0x1C, 5, "Test softap create & station join monitor;"},
+#endif
+
+#if DEMO_WPS
+    {"t-wps-get-pin",  demo_wps_get_pin,   0x0,    0, "Test WPS get pin"},
+    {"t-wps-start-pin",  demo_wps_pin,   0x0,    0, "Test WPS start pin"},
+    {"t-wps-start-pbc",  demo_wps_pbc,   0x0,    0, "Test WPS start pbc"},
+#endif
+
+#if DEMO_SCAN
+    {"t-scan",	scan_demo,	0x0,	0,  "Test wifi scan"},
+#endif
+
+/************************************************************************/
+
+#if DEMO_UARTx
+    {"t-uart", 	uart_demo, 0x7, 3, "Test uart tx/rx; For example t-uart=(9600,0,0),baudrate 9600 ,parity none and 1 stop bit"},
+#endif
+
+#if DEMO_GPIO
+    {"t-gpioirq", 	gpio_isr_test,	0x0,    0, "Test gpio interrupt services"},
+    {"t-gpio", 	    gpio_demo,	    0x0,    0, "Test gpio read and write"},
+#endif
+
+#if DEMO_FLASH
+    {"t-flash", 	flash_demo,		0x0, 0, 	"Test Read/Write Flash "},
+#endif
+
+#if DEMO_ENCRYPT
+    {"t-crypt",   	crypt_hard_demo,	0x0,    0, "Test Encryption/Decryption API"},
+#endif
+
+#if DEMO_RSA
+    {"t-rsa",   	rsa_demo,	0x0,    0, "Test RSA Encryption/Decryption API"},
+#endif
+
+#if DEMO_RTC
+    {"t-rtc",  rtc_demo,   0x0,    0, "Test rtc"},
+#endif
+
+#if DEMO_TIMER
+    {"t-timer",  timer_demo,   0x0,    0, "Test timer"},
+#endif
+
+#if DEMO_PWM
+    {"t-pwm",   	pwm_demo,	0x1F,    5, "Test PWM output, for example t-pwm=(0,20,99,1,0) to test ALLSYC mode."},
+#endif
+
+#if DEMO_PMU
+    {"t-pmuT0",   	pmu_timer0_demo,	0x1,    1, "Test power management unit with timer0"},
+    {"t-pmuT1",   	pmu_timer1_demo,	0x1,    1, "Test power management unit with timer1"},
+#endif
+
+#if DEMO_I2C
+    {"t-i2c",   	i2c_demo,	0x1,    1, "Test I2C module, for example t-i2c to W&R AT24CXX."},
+#endif
+
+#if DEMO_I2S
+    {"t-i2sioinit", tls_i2s_io_init,	0,    0, "Initialize I2S IO."},
+    {"t-i2s",   	tls_i2s_demo,	0x3F,    6, "Test I2S module, for example t-i2s=(0,1,44100,16,0,0) to send data."},
+#endif
+
+#if DEMO_MASTER_SPI
+    {"t-mspi-s", 	master_spi_send_data, 0x3, 2,   "Test SPI Master sending data(Note: need another module acts as a client device)"},
+    {"t-mspi-r", 	master_spi_recv_data, 0x3, 2,   "Test SPI Master receiving data(Note: need another module acts as a client device)"},
+#endif
+
+#if DEMO_SLAVE_SPI
+    {"t-sspi", 	slave_spi_demo, 0x1, 1,   "Test slave HSPI,t-sspi=(0),(Note: need another module support as a master device)"},
+#endif
+
+#if DEMO_SDIO_HOST
+    {"t-sdh",  sd_card_test,   0x0,    0, "Test sdio host write & read sd card"},
+#endif
+
+#if DEMO_ADC
+    {"t-adctemp",  adc_chip_temperature_demo,   0x0,    0, "(ADC)Test chip temperature"},
+    {"t-adcvolt",  adc_input_voltage_demo,   0x1,    1, "(ADC)Test input voltage,0-PA1(chan0), 1-PA4(chan1),8-different"},    
+#endif
+
+#if DEMO_7816
+	{"t-7816",	wm_7816_demo,	0x0,	0, "Test 7816 tx/rx function"},
+#endif
+
+/************************************************************************/
+
+#if DEMO_STD_SOCKET_CLIENT
+    {"t-sockc", 	Socket_Client_Demo,	0x1,    2, "Test data stream as [STANDARD SOCKET] CLIENT(working after connecting with AP successfully)"},
+    {"t-skcsnd", 	sck_c_send_data_demo,	0x3,    2, "Test socket client send data, len:send len, uart_trans: is or not use uart retransmission"},
+#endif
+
+#if DEMO_STD_SOCKET_SERVER
+    {"t-socks", 	socket_server_demo,	0x1,    1, "Test data stream as [STANDARD SOCKET] SERVER(working after connecting with AP successfully)"},
+    {"t-skssnd", 	sck_s_send_data_demo,	0x7,    3, "Test socket server send data skt_no:socket num, len:send len, uart_trans: is or not use uart retransmission"},
+#endif
+
+#if DEMO_SOCKET_CLIENT_SERVER
+	{"t-client",    demo_socket_client,0x4,4,"Test socket client; t-client(\"ssid\",\"pwd\",port,\"ip\")"},
+	{"t-server",    demo_socket_server,0x4,3,"Test socket server; t-server(\"ssid\",\"pwd\",port,)"},
+#endif
+
+#if DEMO_UDP
+    {"t-udp",   	socket_udp_demo,	0x3,    3, "Test data stream as UDP(working after connecting with AP successfully)"},
+    {"t-sndudp",   	udp_send_data_demo,	0x1,    1, "Test udp send data"},
+#endif
+
+#if DEMO_UDP_MULTI_CAST
+	{"t-mcast", CreateMCastDemoTask,	0x0,	1, "Test Multicast data stream"},
+#endif
+
+#if DEMO_NTP
+    {"t-ntp", 	ntp_demo, 0x0, 0,   "Test NTP"},
+    {"t-setntps", ntp_set_server_demo, 0x0, 3, "Set NTP server ip;For example:t-setntps(\"cn.ntp.org.cn\", \"ntp.sjtu.edu.cn\", \"192.168.1.101\"),max server num is 3"},
+    {"t-queryntps", ntp_query_cfg, 0x0, 0, "Query the NTP server domain"},
+#endif
+
+#if DEMO_HTTP
+    {"t-httpfwup",  http_fwup_demo,	0x0,    1, "Test firmware update via HTTP, like this t-httpfwup=(http://192.168.1.100:8080/xt804_SEC.img)"},
+    {"t-httpget", 	http_get_demo,	0x0,    1, "Test HTTP get method, like this t-httpget"},
+    {(char *)HTTP_POST,  http_post_demo,	0x0,    1, "Test HTTP post method, like this t-httppost=(user=winnermicro)"},
+    {(char *)HTTP_PUT,   http_put_demo,  0x0,    1, "Test HTTP put method, like this t-httpput=(user=winnermicro)"},
+#endif
+
+#if DEMO_SSL_SERVER
+    {"t-ssl-server",  CreateSSLServerDemoTask,   0x0,    1, "Test ssl server,remember to turn on TLS_CONFIG_SERVER_SIDE_SSL"},
+#endif
+
+#if DEMO_WEBSOCKETS
+    {"t-websockets", lwsDemoTest, 0x0,    0, "websockets demo test"},
+#endif
+
+#if DEMO_HTTPS
+    {"t-https",	https_demo,	0x0,	0,  "Test https request"},
+#endif
+
+#if DEMO_MBEDTLS
+    {"t-mbedtls",	mbedtls_demo,	0x0,	0,  "Test mbedtls ssl"},
+#endif
+
+#if DEMO_MQTT
+    {"t-mqtt",	mqtt_demo,	0x0,	0,  "Test mqtt"},
+#endif
+
+#if DEMO_FATFS
+	{"t-fatfs",	fatfs_test,	0x0,	0,  "Test fatfs on sd card"},
+#endif 
+
+#if DEMO_IPERF_AUTO_TEST
+	{"t-iperf",  demo_iperf_auto_test,	 0x7E,	  7, "Iperf auto test"},
+#endif
+
+#if DEMO_DSP
+	{"t-dsp",  dsp_demo,	 0x1,	  1, "DSP demo:0-fir,1-matrix,2-rfft,3-sin,4-variance"},
+#endif
+
+#if DEMO_BT
+    {"t-bt-on",	demo_bt_enable,	0x0,	0,                  "Test enable bt system"},
+    {"t-bt-off",	demo_bt_destroy,	0x0,	0,          "Test destroy bt system"},
+#if (TLS_CONFIG_BLE == CFG_ON)    
+    {"t-ble-server-on",	demo_ble_server_on,	0x0,	0,      "Test enable ble server"},
+    {"t-ble-server-off",	demo_ble_server_off,	0x0,	0,  "Test disable ble server"},
+    {"t-ble-client-on",	demo_ble_client_on,	0x0,	0,      "Test enable ble client"},
+    {"t-ble-client-off",	demo_ble_client_off,	0x0,	0,  "Test disable ble client"},
+    {"t-ble-adv", demo_ble_adv, 0x01, 1, "Test start connectable/unconnectable/stop ble advertisement,eg: t-ble-adv=(1/2/0)"},
+    {"t-ble-scan",demo_ble_scan, 0x01, 1, "Test start/stop ble scan,eg: t-ble-scan=(1/0)"},
+#endif  
+
+#if (TLS_CONFIG_BR_EDR == CFG_ON)    
+    {"t-bt-demo-on",	demo_bt_app_on,	0x0,	0,      "Test enable bt app on"},
+    {"t-bt-demo-off",	demo_bt_app_off,	0x0,	0,  "Test disable bt app off"},
+#endif 
+
+#endif
+
+#if DEMO_TOUCHSENSOR
+	{"t-touch", demo_touchsensor, 0x1, 1, "Test Touch sensor function,0:all, 1:touch sensor 1... 15:touch sensor 15"},
+#endif
+
+    //����̨����ʾ�����һ��������Ҫ��������ʾ�ڿ���̨�ϣ���Ҫ���ڸ��е�����
+    {"demohelp", 	demo_console_show_help,	0, 0,	"Display Help information"},
+    //��������������ڲ����ԣ�����ʾ�ڿ���̨��
+    {"reset", 		demo_sys_reset, 0, 0, "Reset System"},
+    //���һ�������������ʱ�жϽ�����ʶ
+    {"lastcmd", 	NULL,	0, 0,			"Table Terminal Flag; MUST BE THE LAST ONE"}
+};
+
+static void demo_console_show_info(char *buf)
+{
+    char *p = NULL;
+    char *p1 = NULL;
+
+    p = buf;
+    p1 = strchr(p, '\n');
+    if(NULL == p1)
+    {
+        printf("%s\n", p);
+        return;
+    }
+
+    while(p1 != NULL)
+    {
+        *p1 = '\0';
+        printf("%s\n", p);
+        printf("%-30s", "   ");
+        p = p1 + 1;
+        p1 = strchr(p, '\n');
+    }
+    printf("%s\n", p);
+}
+
+static int demo_console_show_help(void *p, ...)
+{
+    int i;
+
+    printf("\n%-10s", "Sequence");
+    printf("%-20s", "Command");
+    printf("%s", "Description");
+    printf("\n------------------------------------------------------------------------------------\n");
+    for(i = 0; ; i ++)
+    {
+        printf("%-10d", i + 1);
+        printf("%-20s", console_tbl[i].cmd);
+        //printf("%s\n",console_tbl[i].info);
+        demo_console_show_info(console_tbl[i].info);
+        if(0 == strcmp(console_tbl[i].cmd, "demohelp"))
+            break;
+    }
+    printf("------------------------------------------------------------------------------------\n");
+
+    return WM_SUCCESS;
+}
+
+int demo_sys_reset(void *p, ...)
+{
+    tls_sys_reset();
+    return WM_SUCCESS;
+}
+
+#endif /*__WM_DEMO_CMD_H__*/
+

+ 0 - 0
demo/wm_demo.h


+ 79 - 0
include/app/wm_at_ri_init.h

@@ -0,0 +1,79 @@
+/**
+ * @file    wm_at_ri_init.h
+ *
+ * @brief   AT_RI task and interface resource initial Module
+ *
+ * @author  winnermicro
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef WM_AT_RI_H
+#define WM_AT_RI_H
+
+/**
+ * @defgroup APP_APIs APP APIs
+ * @brief APP APIs
+ */
+
+/**
+ * @addtogroup APP_APIs
+ * @{
+ */
+
+/**
+ * @defgroup AT_RI_APIs AT_RI APIs
+ * @brief AT_RI command APIs
+ */
+
+/**
+ * @addtogroup AT_RI_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to initialize hostif task
+ 				   used by AT&RI Command
+ *
+ * @param          None
+ *
+ * @retval         0     success
+ * @retval         other failed
+ *
+ * @note           Usually the system will call this api at power on.
+ */
+int tls_hostif_init(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @brief          This function is used to initialize high speed SPI
+ *
+ * @param          None
+ *
+ * @retval         0     success
+ * @retval         other failed
+ *
+ * @note           Users can decide to call this api or not according to his application.
+ */
+int tls_hspi_init(void);
+
+/**
+ * @brief          This function is used to initialize UART
+ *
+ * @param          None
+ *
+ * @return         None
+ *
+ * @note           Usually the system will call this api at power on.
+ */
+void tls_uart_init(void);
+
+#endif /* WM_AT_RI_H */
+

+ 91 - 0
include/app/wm_crypto.h

@@ -0,0 +1,91 @@
+/**
+ * @file    wm_crypto.h
+ *
+ * @brief   crypto driver module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_CRYPTO_H
+#define WM_CRYPTO_H
+
+/**
+ * @brief	Encrypt plain data by 128 AES crypto
+ * @param[in] key	the key for encryption
+ * @param[in] iv	the IV value for encryption 
+ * @param[in] data  where the plain data stored 
+ * @param[in] data_len length of the plain data to be encrypted
+ * @retval 0 finish Encryption successfully
+ * @retval -1 Error
+ * @note Encrypted data will be placed into the plain @data area
+ *
+ */
+ int  aes_128_cbc_encrypt (const u8 *key, const u8 *iv, u8 *data, size_t data_len) ;
+
+/**
+ * @brief	Decrypt data by 128 AES crypto
+ * @param[in] key	the key for encryption
+ * @param[in] iv	the IV value for encryption 
+ * @param[in] data  where the plain data stored 
+ * @param[in] data_len length of the plain data to be decrypted
+ * @retval 0 finish Decryption successfully
+ * @retval -1 Error
+ * @note plain data will be placed into the encrypted @data area 
+ *
+ */
+int  aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data,
+						 size_t data_len);
+
+/**
+ * @brief	XOR RC4 stream to given data with skip-stream-start
+ * @param[in] key		RC4 key
+ * @param[in] keylen	RC4 key length 
+ * @param[in] data  	data to be XOR'ed with RC4 stream 
+ * @param[in] data_len  length of the plain data to be encrypted
+ * @retval 0 finish Encryption/Decryption successfully
+ * @retval -1 Error
+ * @note this function should be used for Encryption & Decryption both For the Encryption, the plain @data
+ *       will be replaced by the encrypted output, and vice versa;
+ */
+int rc4(const u8 *key, size_t keylen, u8 *data, size_t data_len);
+
+
+/**
+ * @brief	MD5 hash for data vector
+ * @param[in] addr		Pointers to the data area
+ * @param[in] len		Lengths of the data block 
+ * @param[in] mac  		Buffer for the hash (16 bytes) 
+ * @retval 0 finish caculation successfully
+ * @retval -1 Error
+ * @note 
+ */
+int md5(const u8 *addr, int len, u8 *mac);
+
+/**
+ * @brief	HMAC-MD5 over data buffer (RFC 2104)
+ * @param[in] key			Key for HMAC operations 
+ * @param[in] keylen		Length of the key in bytes  
+ * @param[in] data  		data to be caculated  
+ * @param[in] data_len		Lengths of the data block 
+ * @param[in] mac	  		Buffer for the hash (16 bytes) 
+ * @retval 0 finish caculation successfully
+ * @retval -1 Error
+ * @note 
+ */
+int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac);
+
+/**
+ * @brief	SHA1 hash for data vector
+ * @param[in] addr			Pointers to the data area
+ * @param[in] len 			Lengths of the data block 
+ * @param[in] mac	  		Buffer for the hash (16 bytes) 
+ * @retval 0 finish caculation successfully
+ * @retval -1 Error
+ * @note 
+ */
+
+int sha1(const u8 *addr, int len, u8 *mac);
+
+#endif
+

+ 91 - 0
include/app/wm_dhcp_server.h

@@ -0,0 +1,91 @@
+/**
+ * @file    wm_dhcp_server.h
+ *
+ * @brief   DHCP SERVER
+ *
+ * @author  winnermicro
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef WM_DHCP_SERVER_H
+#define WM_DHCP_SERVER_H
+
+/**
+ * @defgroup APP_APIs APP APIs
+ * @brief APP APIs
+ */
+
+/**
+ * @addtogroup APP_APIs
+ * @{
+ */
+
+/**
+ * @defgroup DHCPS_APIs DHCPS APIs
+ * @brief DHCP server APIs
+ */
+
+/**
+ * @addtogroup DHCPS_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to start DHCP Server for a network
+                   interface
+ *
+ * @param          None
+ *
+ * @retval         WM_SUCCESS     success
+ * @retval         WM_FAILED	  failed
+ *
+ * @note           None
+ */
+s8 tls_dhcps_start(void);
+
+/**
+ * @brief          This function is used to stop DHCP server
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_dhcps_stop(void);
+
+/**
+ * @brief          This function is used to get station's IP address by
+                   MAC address
+ *
+ * @param[in]      *mac  STA's MAC address
+ *
+ * @retval         ip_addr     STA's IP address
+ * @retval         NULL		   Not found match IP with MAC address
+ *
+ * @note           None
+ */
+ip_addr_t *tls_dhcps_getip(const u8 *mac);
+
+/**
+ * @brief          This function is used to set DHCP server's DNS address
+ *
+ * @param[in]      numdns    the index of the DNS server to set must be 0 or 1
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_dhcps_setdns(u8 numdns);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_DHCP_SERVER_H */
+

+ 66 - 0
include/app/wm_dns_server.h

@@ -0,0 +1,66 @@
+/**
+ * @file    wm_dns_server.h
+ *
+ * @brief   DNS SERVER
+ *
+ * @author  winnermicro
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef WM_DNS_SERVER_H
+#define WM_DNS_SERVER_H
+
+/**
+ * @defgroup APP_APIs APP APIs
+ * @brief APP APIs
+ */
+
+/**
+ * @addtogroup APP_APIs
+ * @{
+ */
+
+/**
+ * @defgroup DNSS_APIs DNSS APIs
+ * @brief DNS server APIs
+ */
+
+/**
+ * @addtogroup DNSS_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to start DNS service
+ *
+ * @param[in]      *dnsname    Specify the server's dns name
+ *
+ * @retval         WM_SUCCESS     success
+ * @retval         WM_FAILED	  failed
+ *
+ * @note           None
+ */
+s8 tls_dnss_start(u8 *dnsname);
+
+/**
+ * @brief          This function is used to stop DNS service
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_dnss_stop(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_DNS_SERVER_H */
+

+ 486 - 0
include/app/wm_http_client.h

@@ -0,0 +1,486 @@
+/**
+ * @file    wm_http_client.h
+ *
+ * @brief   Http client APIs
+ *
+ * @author  wanghf
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_HTTP_CLIENT_H
+#define WM_HTTP_CLIENT_H
+
+#include "wm_config.h"
+#include "wm_type_def.h"
+#ifdef BOOL
+#undef BOOL
+#endif
+#ifdef UCHAR
+#undef UCHAR
+#endif
+#ifdef CHAR
+#undef CHAR
+#endif
+#ifdef UINT16
+#undef UINT16
+#endif
+#ifdef INT16
+#undef INT16
+#endif
+#ifdef UINT32
+#undef UINT32
+#endif
+#ifdef INT32
+#undef INT32
+#endif
+#ifdef UINT64
+#undef UINT64
+#endif
+#ifdef INT64
+#undef INT64
+#endif
+#ifdef ULONG
+#undef ULONG
+#endif
+#ifdef LONG
+#undef LONG
+#endif
+#define VOID                    void
+typedef int BOOL;
+typedef unsigned char           UCHAR;
+//typedef signed char             CHAR;
+typedef char                    CHAR;
+typedef unsigned short          UINT16; 
+typedef signed short            INT16;
+typedef unsigned int            UINT32;
+typedef signed int              INT32;
+typedef unsigned long long      UINT64;
+typedef long long               INT64;
+typedef unsigned long           ULONG;
+typedef signed long             LONG;
+
+
+/* HTTP Status, API Return codes */
+/** HTTP Success status */
+#define HTTP_CLIENT_SUCCESS                 0
+/** Unknown error */
+#define HTTP_CLIENT_UNKNOWN_ERROR           1
+/** an Invalid handle or possible bad pointer was passed to a function */
+#define HTTP_CLIENT_ERROR_INVALID_HANDLE    2
+/** Buffer too small or a failure while in memory allocation */
+#define HTTP_CLIENT_ERROR_NO_MEMORY         3
+/** an attempt to use an invalid socket handle was made */
+#define HTTP_CLIENT_ERROR_SOCKET_INVALID    4
+/** Can't send socket parameters */
+#define HTTP_CLIENT_ERROR_SOCKET_CANT_SET   5
+/** Error while resolving host name */
+#define HTTP_CLIENT_ERROR_SOCKET_RESOLVE    6
+/** Error while connecting to the remote server */
+#define HTTP_CLIENT_ERROR_SOCKET_CONNECT    7
+/** socket time out error */
+#define HTTP_CLIENT_ERROR_SOCKET_TIME_OUT   8
+/** Error while receiving data */
+#define HTTP_CLIENT_ERROR_SOCKET_RECV       9
+/** Error while sending data */
+#define HTTP_CLIENT_ERROR_SOCKET_SEND       10
+/** Error while receiving the remote HTTP headers */
+#define HTTP_CLIENT_ERROR_HEADER_RECV       11
+/** Could not find element within header */
+#define HTTP_CLIENT_ERROR_HEADER_NOT_FOUND  12
+/** The headers search clue was too large for the internal API buffer */
+#define HTTP_CLIENT_ERROR_HEADER_BIG_CLUE   13
+/** No content length was specified for the outgoing data. the caller should
+    specify chunking mode in the session creation */
+#define HTTP_CLIENT_ERROR_HEADER_NO_LENGTH  14
+/** The HTTP chunk token that was received from the server was too big and possibly wrong */
+#define HTTP_CLIENT_ERROR_CHUNK_TOO_BIG     15
+/** Could not authenticate with the remote host */
+#define HTTP_CLIENT_ERROR_AUTH_HOST         16
+/** Could not authenticate with the remote proxy */
+#define HTTP_CLIENT_ERROR_AUTH_PROXY        17
+/** Bad or not supported HTTP verb was passed to a function */
+#define HTTP_CLIENT_ERROR_BAD_VERB          18
+/** a function received a parameter that was too large */
+#define HTTP_CLIENT_ERROR_LONG_INPUT        19
+/** The session state prevents the current function from proceeding */
+#define HTTP_CLIENT_ERROR_BAD_STATE         20
+/** Could not parse the chunk length while in chunked transfer */
+#define HTTP_CLIENT_ERROR_CHUNK             21
+/** Could not parse curtail elements from the URL (such as the host name, HTTP prefix act') */
+#define HTTP_CLIENT_ERROR_BAD_URL           22
+/** Could not detect key elements in the received headers */
+#define HTTP_CLIENT_ERROR_BAD_HEADER        23
+/** Error while attempting to resize a buffer */
+#define HTTP_CLIENT_ERROR_BUFFER_RSIZE      24
+/** Authentication schema is not supported */
+#define HTTP_CLIENT_ERROR_BAD_AUTH          25
+/** The selected authentication schema does not match the server response */
+#define HTTP_CLIENT_ERROR_AUTH_MISMATCH     26
+/** an element was missing while parsing the digest authentication challenge */
+#define HTTP_CLIENT_ERROR_NO_DIGEST_TOKEN   27
+/** Digest algorithem could be MD5 or MD5-sess other types are not supported */
+#define HTTP_CLIENT_ERROR_NO_DIGEST_ALG     28
+/** Binding error */
+#define HTTP_CLIENT_ERROR_SOCKET_BIND		29
+/** Tls negotiation error */
+#define HTTP_CLIENT_ERROR_TLS_NEGO			30
+/** Feature is not (yet) implemented */
+#define HTTP_CLIENT_ERROR_NOT_IMPLEMENTED   64
+/** HTTP end of stream message */
+#define HTTP_CLIENT_EOS                     1000
+
+// HTTP Session flags (Public flags)
+#define HTTP_CLIENT_FLAG_KEEP_ALIVE         0x00000001 // Set the keep alive header
+#define HTTP_CLIENT_FLAG_SEND_CHUNKED       0x00000002 // The outgoing should chunked
+#define HTTP_CLIENT_FLAG_NO_CACHE           0x00000004 // Set the no cache header
+#define HTTP_CLIENT_FLAG_ASYNC              0x00000008 // Currently not implemented 
+#define HTTP_CLIENT_FLAG_MULTIPART_FORM       0x00000010 // The outgoing should multipart/form-data
+
+// HTTP Type Definitions 
+typedef UINT32          HTTP_SESSION_HANDLE;
+typedef UINT32          HTTP_CLIENT_SESSION_FLAGS;
+/******************************************************************************
+*
+*  Section      : HTTP API structures
+*
+******************************************************************************/
+
+/* HTTP Type Definitions */
+/** http seesion handle */
+typedef u32 tls_http_session_handle_t;
+/** http seesion flags */
+typedef u32 tls_http_session_flags_t;
+
+/** HTTP Supported authentication methods */
+typedef enum _HTTP_AUTH_SCHEMA
+{
+    AuthSchemaNone      = 0,
+    AuthSchemaBasic,
+    AuthSchemaDigest,
+    AuthSchemaKerberos,
+    AuthNotSupported
+
+} HTTP_AUTH_SCHEMA;
+/** HTTP supported verbs */
+typedef enum _HTTP_VERB
+{
+    VerbGet             = 0,
+    VerbHead,
+    VerbPost,
+    VerbPut,
+    VerbFwup,
+    VerbNotSupported
+    // Note: others verb such as connect and put are currently not supported
+
+} HTTP_VERB;
+/** Data structure that the caller can request at any time that will include
+    some information regarding the session */
+typedef struct _HTTP_CLIENT
+{
+    UINT32        HTTPStatusCode;                 // HTTP Status code (200 OK)
+    UINT32		    RequestBodyLengthSent;          // Total bytes sent (body only)
+    UINT32		    ResponseBodyLengthReceived;     // Total bytes received (body only)
+    UINT32		    TotalResponseBodyLength;        // as extracted from the “content-length" header
+    UINT32        HttpState;
+} HTTP_CLIENT;
+
+/** HTTP parameters */
+typedef struct _HTTPParameters
+{
+    CHAR*                  Uri;        
+    CHAR*                  ProxyHost;  
+    UINT32                  UseProxy ;  
+    UINT32                  ProxyPort;
+    UINT32                  Verbose;
+    CHAR*                  UserName;
+    CHAR*                  Password;
+    HTTP_AUTH_SCHEMA      AuthType;
+
+} HTTPParameters;
+
+#if TLS_CONFIG_HTTP_CLIENT_TASK
+/** the callback function of http clent for received */
+typedef void  (*http_client_recv_callback_fn)(HTTP_SESSION_HANDLE pSession, CHAR * data, UINT32 totallen, UINT32 datalen);
+/** the callback function of http clent for err */
+typedef void  (*http_client_err_callback_fn)(HTTP_SESSION_HANDLE pSession, int err);
+
+/** message of the http client */
+typedef struct _http_client_msg
+{
+    HTTP_SESSION_HANDLE pSession;
+    HTTPParameters param;
+    HTTP_VERB method;
+    CHAR* sendData;
+    UINT32      dataLen;
+    http_client_recv_callback_fn recv_fn;
+    http_client_err_callback_fn err_fn;
+} http_client_msg;
+#endif
+
+/**
+ * @defgroup APP_APIs APP APIs
+ * @brief APP APIs
+ */
+
+/**
+ * @addtogroup APP_APIs
+ * @{
+ */
+
+/**
+ * @defgroup HTTPC_APIs HTTPC APIs
+ * @brief HTTP client APIs
+ */
+
+/**
+ * @addtogroup HTTPC_APIs
+ * @{
+ */
+
+
+/******************************************************************************
+*
+*  Section      : HTTP API public interface
+*
+******************************************************************************/
+
+/**
+ * @brief          Allocate memory for a new HTTP Session
+ *
+ * @param[in]      Flags    HTTP Session internal API flags, 0 should be passed here
+ *
+ * @retval         0        failed
+ * @retval         other    HTTP Session handle
+ *
+ * @note           None
+ */
+HTTP_SESSION_HANDLE     HTTPClientOpenRequest         (HTTP_CLIENT_SESSION_FLAGS Flags);
+/**
+ * @brief          Closes the active connection and free the corresponding memory
+ *
+ * @param[in]      *pSession                HTTP Session handle
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientCloseRequest        (HTTP_SESSION_HANDLE *pSession);
+/**
+ * @brief          Sets the HTTP authentication schema
+ *
+ * @param[in]      pSession                 HTTP Session handle
+ * @param[in]      AuthSchema             HTTP Supported authentication methods
+ * @param[in]      *pReserved               Reserved parameter
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientSetAuth             (HTTP_SESSION_HANDLE pSession, HTTP_AUTH_SCHEMA AuthSchema, void *pReserved);
+/**
+ * @brief          Sets credentials for the target host
+ *
+ * @param[in]      pSession                 HTTP Session handle
+ * @param[in]      *pUserName              User name
+ * @param[in]      *pPassword               Password
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientSetCredentials      (HTTP_SESSION_HANDLE pSession, CHAR *pUserName, CHAR *pPassword);
+/**
+ * @brief          Sets all the proxy related parameters
+ *
+ * @param[in]      pSession        HTTP Session handle
+ * @param[in]      *pProxyName    The host name
+ * @param[in]      nPort           The proxy port number
+ * @param[in]      *pUserName     User name for proxy authentication (can be null)
+ * @param[in]      *pPassword      User password for proxy authentication (can be null)
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientSetProxy            (HTTP_SESSION_HANDLE pSession, CHAR *pProxyName, UINT16 nPort, CHAR *pUserName, CHAR *pPassword);
+/**
+ * @brief          Sets the HTTP verb for the outgoing request
+ *
+ * @param[in]      pSession                 HTTP Session handle
+ * @param[in]      HttpVerb               HTTP supported verbs
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientSetVerb             (HTTP_SESSION_HANDLE pSession, HTTP_VERB HttpVerb);
+/**
+ * @brief          Add headers into the outgoing request
+ *
+ * @param[in]      pSession                 HTTP Session
+ * @param[in]      *pHeaderName            The Header name
+ * @param[in]      *pHeaderData            The header data
+ * @param[in]      nInsert                  Reserved, could be any
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientAddRequestHeaders   (HTTP_SESSION_HANDLE pSession, CHAR *pHeaderName, CHAR *pHeaderData, BOOL nInsert);
+/**
+ * @brief          This function builds the request headers, performs a DNS resolution,
+ *                 opens the connection (if it was not opened yet by a previous request
+ *                 or if it has closed) and sends the request headers
+ *
+ * @param[in]      pSession      HTTP Session handle
+ * @param[in]      *pUrl         The requested URL
+ * @param[in]      *pData        Data to post to the server
+ * @param[in]      nDataLength     Length of posted data
+ * @param[in]      TotalLength    Valid only when http method is post
+ *                              TRUE:  Post data to http server.
+ *                              FALSE: In a post request without knowing the total
+ *                                     length in advance so return error or use chunking.
+ * @param[in]      nTimeout     Operation timeout
+ * @param[in]      nClientPort  Client side port 0 for none
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientSendRequest         (HTTP_SESSION_HANDLE pSession, CHAR *pUrl, VOID *pData, UINT32 nDataLength, BOOL TotalLength, UINT32 nTimeout,UINT32 nClientPort);
+/**
+ * @brief          Write data to the remote server
+ *
+ * @param[in]      pSession                 HTTP Session handle
+ * @param[in]      *pBuffer                 Data to write to the server
+ * @param[in]      nBufferLength              Length of wtitten data
+ * @param[in]      nTimeout                Timeout for the operation
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientWriteData           (HTTP_SESSION_HANDLE pSession, VOID *pBuffer, UINT32 nBufferLength, UINT32 nTimeout);
+/**
+ * @brief          Receives the response header on the connection and parses it.
+ *                 Performs any required authentication.
+ *
+ * @param[in]      pSession                 HTTP Session handle
+ * @param[in]      nTimeout                Timeout for the operation
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientRecvResponse        (HTTP_SESSION_HANDLE pSession, UINT32 nTimeout);
+/**
+ * @brief          Read data from the server. Parse out the chunks data
+ *
+ * @param[in]      pSession           HTTP Session handle
+ * @param[out]     *pBuffer           A pointer to a buffer that will be filled with the servers response
+ * @param[in]      nBytesToRead     The size of the buffer (numbers of bytes to read)
+ * @param[in]      nTimeout          Operation timeout in seconds
+ * @param[out]     *nBytesRecived    Count of the bytes that were received in this operation
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientReadData            (HTTP_SESSION_HANDLE pSession, VOID *pBuffer, UINT32 nBytesToRead, UINT32 nTimeout, UINT32 *nBytesRecived);
+/**
+ * @brief          Fill the users structure with the session information
+ *
+ * @param[in]      pSession                 HTTP Session handle
+ * @param[out]     *HTTPClient            The session information
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientGetInfo             (HTTP_SESSION_HANDLE pSession, HTTP_CLIENT *HTTPClient);
+/**
+ * @brief          Initiate the headr searching functions and find the first header
+ *
+ * @param[in]      pSession           HTTP Session handle
+ * @param[in]      *pSearchClue      Search clue
+ * @param[out]     *pHeaderBuffer    A pointer to a buffer that will be filled with the header name and value
+ * @param[out]     *nLength           Count of the bytes that were received in this operation
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientFindFirstHeader     (HTTP_SESSION_HANDLE pSession, CHAR *pSearchClue,CHAR *pHeaderBuffer, UINT32 *nLength);
+/**
+ * @brief          Find the next header.
+ *
+ * @param[in]      pSession           HTTP Session handle
+ * @param[out]     *pHeaderBuffer    A pointer to a buffer that will be filled with the header name and value
+ * @param[out]     *nLength           Count of the bytes that were received in this operation
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientGetNextHeader       (HTTP_SESSION_HANDLE pSession, CHAR *pHeaderBuffer, UINT32 *nLength);
+/**
+ * @brief          Terminate a headers search session
+ *
+ * @param[in]      pSession                 HTTP Session handle
+ *
+ * @retval         HTTP_CLIENT_SUCCESS     success
+ * @retval         other                   failed
+ *
+ * @note           None
+ */
+UINT32                  HTTPClientFindCloseHeader     (HTTP_SESSION_HANDLE pSession);
+
+#if TLS_CONFIG_HTTP_CLIENT_TASK
+/**
+ * @brief          initialize task of the http client
+ *
+ * @param          None
+ *
+ * @retval         WM_SUCCESS     success
+ * @retval         WM_FAILED      failed
+ *
+ * @note           None
+ */
+int http_client_task_init(void);
+
+/**
+ * @brief          post message to the task of http client
+ *
+ * @param[in]      msg      pointer to the message
+ *
+ * @retval         ERR_OK     success
+ * @retval         other      failed
+ *
+ * @note           None
+ */
+int http_client_post(http_client_msg * msg);
+#endif /* TLS_CONFIG_HTTP_CLIENT_TASK */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_HTTP_CLIENT_H */
+

+ 15 - 0
include/app/wm_netif.h

@@ -0,0 +1,15 @@
+/**
+ * @file    wm_netif.h
+ *
+ * @brief   ETHERNET INIT Interface
+ *
+ * @author  winnermicro
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_NETIF_H
+#define WM_NETIF_H
+#include "wm_config.h"
+#include "wm_netif2.0.3.h"
+#endif /* WM_NETIF_H */
+

+ 437 - 0
include/app/wm_netif2.0.3.h

@@ -0,0 +1,437 @@
+/**
+ * @file    wm_netif2.0.3.h
+ *
+ * @brief   netif203 module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+ 
+#ifndef WM_NETIF2_0_3_H
+#define WM_NETIF2_0_3_H
+
+#include "wm_config.h"
+#include "wm_type_def.h"
+#include "wm_sockets.h"
+#include "wm_wifi.h"
+#include "wm_params.h"
+
+/** MACRO for callback EVENT to join AP or create soft-AP successfully  */
+#define	NETIF_WIFI_JOIN_SUCCESS         0x1
+/** MACRO for callback EVENT to fail to join AP */
+#define  NETIF_WIFI_JOIN_FAILED          0x2
+/** MACRO for callback EVENT to disconnect from AP or destroy soft-AP */
+#define	NETIF_WIFI_DISCONNECTED         0x3
+/** MACRO for callbck EVENT to get IP address */
+#define	NETIF_IP_NET_UP                 0x4
+/** MACRO for callback EVNET to create AP successfully */
+#define	NETIF_WIFI_SOFTAP_SUCCESS    0x5
+/** MACRO for callback EVNET to create soft-AP failed */
+#define	NETIF_WIFI_SOFTAP_FAILED     0x6
+/** MACRO for callback EVNET to close soft-AP */
+#define	NETIF_WIFI_SOFTAP_CLOSED          0x7
+/** MACRO for callback EVNET to inform soft ap's net */
+#define	NETIF_IP_NET2_UP                0x8
+
+#define NETIF_IPV6_NET_UP           0x9
+
+/** These are the values for ip_addr_t.type */
+#define IPADDR_TYPE_V4                0U
+#define IPADDR_TYPE_V6                6U
+#define IPADDR_TYPE_ANY               46U
+
+#define IPV6_ADDR_MAX_NUM       3       
+
+#if 0
+struct ip_addr {
+  u32_t addr;
+};
+
+typedef struct ip_addr ip_addr_t;	
+#endif
+#if 0
+struct ip4_addr {
+  u32_t addr;
+};
+typedef struct ip4_addr ip4_addr_t;
+
+struct ip6_addr {
+  u32_t addr[4];
+};
+typedef struct ip6_addr ip6_addr_t;
+
+#if (TLS_CONFIG_IPV4 && TLS_CONFIG_IPV6)
+typedef struct _ip_addr {
+  union {
+    ip6_addr_t ip6;
+    ip4_addr_t ip4;
+  } u_addr;
+  u8_t type;
+} ip_addr_t;
+#else
+#if TLS_CONFIG_IPV4
+typedef ip4_addr_t ip_addr_t;
+#else	  
+typedef ip6_addr_t ip_addr_t;
+#endif
+#endif
+#endif
+struct tls_ethif {
+    ip_addr_t ip_addr;
+    ip_addr_t netmask;
+    ip_addr_t gw;
+#if TLS_CONFIG_IPV6
+    ip_addr_t ip6_addr[IPV6_ADDR_MAX_NUM];
+#endif
+    ip_addr_t dns1;
+    ip_addr_t dns2;
+    u8 status;              //0:net down; 1:net up
+#if TLS_CONFIG_IPV6
+    u8 ipv6_status[IPV6_ADDR_MAX_NUM];      //0:net down; 1:net up
+#endif
+};
+
+//type defination of netif status changed callback.
+typedef void (*tls_netif_status_event_fn)(u8 status);
+
+/**
+ * @defgroup APP_APIs APP APIs
+ * @brief APP APIs
+ */
+
+/**
+ * @addtogroup APP_APIs
+ * @{
+ */
+
+/**
+ * @defgroup NETIF_APIs NETIF APIs
+ * @brief network interface APIs
+ */
+
+/**
+ * @addtogroup NETIF_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to initialize TCP/IP Stack
+ *
+ * @param[in]      None
+ *
+ * @retval         0     success
+ * @retval         other failed
+ *
+ * @note           None
+ */
+int tls_ethernet_init(void);
+
+/**
+ * @brief          This function is used to get IP information stored in
+                   tls_ethif struct
+ *
+ * @param[in]      None
+ *
+ * @retval         tls_ethif *     Pointer to struct tls_ethif
+ *
+ * @note           None
+ */
+struct tls_ethif * tls_netif_get_ethif(void);
+
+/**
+ * @brief          This function is used to set tls_ethif status
+ *
+ * @param[in]      status  net status, 0-up, 1-down
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_netif_set_status(u8 status);
+
+/**
+ * @brief          This function is used to start DHCP Client
+ *
+ * @param[in]      None
+ *
+ * @retval         0     success
+ * @retval         Minus failed
+ *
+ * @note           None
+ */
+err_t tls_dhcp_start(void);
+
+/**
+ * @brief          This function is used to stop DHCP client
+ *
+ * @param[in]      None
+ *
+ * @retval         0     success
+ * @retval         Minus failed
+ *
+ * @note           None
+ */
+err_t tls_dhcp_stop(void);
+
+/**
+ * @brief          This function is used to change IP information
+ *
+ * @param[in]      *ipaddr     IP address
+ * @param[in]      *netmask    netmask
+ * @param[in]      *gw         default gateway
+ *
+ * @retval         0     success
+ * @retval         Minus failed
+ *
+ * @note           None
+ */
+err_t tls_netif_set_addr(ip_addr_t *ipaddr,
+                        ip_addr_t *netmask,
+                        ip_addr_t *gw);
+
+/**
+ * @brief          This function is used to set dns servers
+ *
+ * @param[in]      numdns     index of the DNS server to set
+ 							  must be < DNS_MAX_SERVERS
+ * @param[in]      *dnsserver IP address of the DNS server to set
+ *
+ * @return         None
+ *
+ * @note           None
+ */ 
+void tls_netif_dns_setserver(u8 numdns, ip_addr_t *dnsserver);
+
+/**
+ * @brief          This function is used to bring up an interface,available
+                   for processing traffic
+ *
+ * @param[in]      None
+ *
+ * @retval         0     success
+ * @retval         Minus failed
+ *
+ * @note           None
+ */
+err_t tls_netif_set_up(void);
+
+/**
+ * @brief          This function is used to bring down an interface,disabling
+ 				   any traffic processing
+ *
+ * @param[in]      None
+ *
+ * @retval         0     success
+ * @retval         Minus failed
+ *
+ * @note           None
+ */ 
+err_t tls_netif_set_down(void);
+
+/**
+ * @brief          This function is used to add netif status changed callback
+                   to event list,if exists, do nothing
+ *
+ * @param[in]      event_fn    pointer to tls_netif_status_event_fn
+ *
+ * @retval         0     success
+ * @retval         Minus failed
+ *
+ * @note           None
+ */
+err_t tls_netif_add_status_event(tls_netif_status_event_fn event_fn);
+
+/**
+ * @brief          This function is used to remove netif status changed
+                   callback function from event list,if not exists, do nothing
+ *
+ * @param[in]      event_fn    pointer to tls_netif_status_event_fn
+ *
+ * @retval         0     success
+ * @retval         Minus failed
+ *
+ * @note           None
+ */
+err_t tls_netif_remove_status_event(tls_netif_status_event_fn event_fn);
+
+/**
+ * @brief          This function is used to get pointer of netif
+ *
+ * @param[in]      None
+ *
+ * @retval         pointer of netif
+ *
+ * @note           None
+ */ 
+struct netif *tls_get_netif(void);
+
+#if TLS_CONFIG_AP
+/**
+ * @brief          Start DHCP Server for a network interface
+ * *
+ * @retval         DHCPS_ERR_SUCCESS - No error
+ * @retval         DHCPS_ERR_MEM - Out of memory
+ * @retval         DHCPS_ERR_LINKDOWN - The NI is inactive
+ *
+ * @note           None
+ */
+INT8S tls_dhcps_start(void);
+
+/**
+ * @brief          This function is used to stop DHCP Server
+ *
+ * @param[in]      None
+ *
+ * @retval         None
+ *
+ * @note           None
+ */
+void tls_dhcps_stop(void);
+
+/**
+ * @brief          Start the dns server's service
+ * *
+ * @retval         DHCPS_ERR_SUCCESS - No error
+ * @retval         DHCPS_ERR_MEM - Out of memory
+ * @retval         DHCPS_ERR_LINKDOWN - The NI is inactive
+ * @retval		   DNSS_ERR_PARAM - Input parameter error
+ *
+ * @note           None
+ */
+INT8S tls_dnss_start(INT8U * DnsName);
+
+/**
+ * @brief          Stop the dns server's service
+ *
+ * @param[in]      None
+ *
+ * @retval         None
+ *
+ * @note           None
+ */
+void tls_dnss_stop(void);
+
+/**
+ * @brief          Get station's ip address by mac address
+ *
+ * @param[in]      mac    station's mac address
+ *
+ * @retval         ip_addr   station's ip address
+ *
+ * @note           None
+ */
+ip_addr_t *tls_dhcps_getip(const u8_t *mac);
+
+/**
+ * @brief          Get station's mac address by ip address
+ *
+ * @param[in]      ip    station's ip address
+ *
+ * @retval         u8*   station's mac address
+ *
+ * @note           None
+ */
+u8 *tls_dhcps_getmac(const ip_addr_t *ip);
+#endif //TLS_CONFIG_AP
+
+#if TLS_CONFIG_RMMS
+/**
+ * @brief          Start remote manager server.
+ * *
+ * @retval         DHCPS_ERR_SUCCESS - No error
+ * @retval         DHCPS_ERR_MEM - Out of memory
+ * @retval         DHCPS_ERR_LINKDOWN - The NIF is inactive
+ *
+ * @note           None
+ */
+INT8S tls_rmms_start(void);
+
+/**
+ * @brief          Disable remote manager server
+ *
+ * @param[in]      None
+ *
+ * @retval         None
+ *
+ * @note           None
+ */
+void tls_rmms_stop(void);
+#endif
+
+#if TLS_CONFIG_AP
+/**
+ * @brief          This is used to bring up an interface for APSTA,available
+                   for processing traffic
+ *
+ * @param[in]      None
+ *
+ * @retval         0     success
+ * @retval         Minus failed
+ *
+ * @note           Can only be used at APSTA mode
+ */
+err_t tls_netif2_set_up(void);
+
+/**
+ * @brief          This function is used to bring down an interface for APSTA, disabling 
+                   any traffic processing
+ *
+ * @param[in]      None
+ *
+ * @retval         0     success
+ * @retval         Minus failed
+ *
+ * @note           Can only be used at APSTA mode
+ */
+err_t tls_netif2_set_down(void);
+
+/**
+ * @brief          This function is used to change IP information for
+                   a network interface for APSTA
+ *
+ * @param[in]      *ipaddr     IP address
+ * @param[in]      *netmask    netmask
+ * @param[in]      *gw         default gateway
+ *
+ * @retval         0     success
+ * @retval         Minus failed
+ *
+ * @note           Can only be used at APSTA mode
+ */
+err_t tls_netif2_set_addr(ip_addr_t *ipaddr,
+                          ip_addr_t *netmask,
+                          ip_addr_t *gw);
+/*************************************************************************** 
+* Function: tls_dhcps_setdns
+* Description: Set dhcp server's dns address.
+* 
+* Input:  numdns:     the index of the DNS server to set must be less than DNS_MAX_SERVERS
+* 
+* Output: None
+* 
+* Return: None
+* 
+* Date : 2015-3-10
+****************************************************************************/
+/**
+ * @brief          Set dhcp server's dns address
+ *
+ * @param[in]      numdns the index of the DNS server to set must be less than DNS_MAX_SERVERS
+ *
+ * @retval         None
+ *
+ * @note           Can only be used at APSTA mode
+ */
+void tls_dhcps_setdns(u8_t numdns);
+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif //WM_NETIF_H

+ 80 - 0
include/app/wm_ntp.h

@@ -0,0 +1,80 @@
+/**
+ * @file    wm_ntp.h
+ *
+ * @brief   ntp module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef WM_NTP_H
+#define WM_NTP_H
+
+#include "wm_type_def.h"
+
+/**
+ * @defgroup APP_APIs APP APIs
+ * @brief APP APIs
+ */
+
+/**
+ * @addtogroup APP_APIs
+ * @{
+ */
+
+/**
+ * @defgroup NTP_APIs NTP APIs
+ * @brief NTP APIs
+ */
+
+/**
+ * @addtogroup NTP_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to get network time.
+ *
+ * @param          None
+ *
+ * @retval         time value
+ *
+ * @note           None
+ */
+u32 tls_ntp_client(void);
+
+/**
+ * @brief          This function is used to set ntp servers.
+ *
+ * @param[in]      *ipaddr      xxx.xxx.xxx.xxx
+ * @param[in]      server_no    max num is three
+ *
+ * @retval         WM_SUCCESS     success
+ * @retval         WM_FAILED failed
+ *
+ * @note           None
+ */
+int tls_ntp_set_server(char *ipaddr, int server_no);
+
+/**
+ * @brief          This function is used to query params of the ntp servers 
+ *
+ *
+ * @retval         WM_SUCCESS     success
+ * @retval         WM_FAILED failed
+ *
+ * @note           None
+ */
+int tls_ntp_query_sntpcfg(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_NTP_H */
+

+ 159 - 0
include/app/wm_ssl_server.h

@@ -0,0 +1,159 @@
+#ifndef _SSL_SERVER_H_
+#define _SSL_SERVER_H_
+
+#include "wm_config.h"
+#include "HTTPClientWrapper.h"
+
+#if 1//for doxygen
+//#if TLS_CONFIG_SERVER_SIDE_SSL
+
+#if TLS_CONFIG_USE_POLARSSL
+#include "polarssl/config.h"
+#include "polarssl/ssl.h"
+
+#error "PolaSSL does not support ssl server now!"
+#elif TLS_CONFIG_USE_MBEDTLS
+typedef void tls_ssl_key_t;
+#endif
+//key type for tls_ssl_server_init
+#define KEY_RSA	1
+#define	KEY_ECC	2
+#define KEY_DH	3
+
+/**
+ * @defgroup APP_APIs APP APIs
+ * @brief APP APIs
+ */
+
+/**
+ * @addtogroup APP_APIs
+ * @{
+ */
+
+/**
+ * @defgroup SSL_SERVER_APIs SSL SERVER APIs
+ * @brief SSL Server APIs
+ */
+
+/**
+ * @addtogroup SSL_SERVER_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to initialize SSL Server
+ *
+ * @param[in]      *arg     proto version: 0 - sslv3
+ *                                         1 - tls1.0
+ *                                         2 - tls1.1
+ *                                         3 - tls1.2
+ *
+ * @retval         0     success
+ * @retval         other failed
+ *
+ * @note           None
+ */
+int tls_ssl_server_init(void * arg);
+
+/**
+ * @brief          This function is used to set SSL keys
+ *
+ * @param[in]      **keys     SSL key pointer
+ * @param[in]      *certBuf   SSL certificate
+ * @param[in]      certLen    SSL certificate length
+ * @param[in]      *privBuf   SSL private key
+ * @param[in]      privLen    SSL private key length
+ * @param[in]      *CAbuf     CA certificate
+ * @param[in]      CAlen      CA certificate length
+ * @param[in]      keyType    key type: KEY_RSA,KEY_ECC,KEY_DH
+ *
+ * @retval         0     success
+ * @retval         other failed
+ *
+ * @note           None
+ */
+int tls_ssl_server_load_keys(tls_ssl_key_t **keys, unsigned char *certBuf,
+			int32 certLen, unsigned char *privBuf, int32 privLen,
+			unsigned char *CAbuf, int32 CAlen, int keyType);
+
+/**
+ * @brief          This function is used to set SSL Server working
+ *
+ * @param[in]      **ssl_p      SSL hanlde
+ * @param[in]      fd           socket number
+ * @param[in]      *keys        SSL keys
+ *
+ * @retval         0     success
+ * @retval         other failed
+ *
+ * @note           None
+ */
+int tls_ssl_server_handshake(tls_ssl_t **ssl_p, int fd, tls_ssl_key_t *keys);
+
+/**
+ * @brief          This function is used to send data
+ *
+ * @param[in]      *ssl         SSL hanlde
+ * @param[in]      s            socket number
+ * @param[in]      *sndbuf      send buffer
+ * @param[in]      len          send length
+ * @param[in]      flags        some flags
+ *
+ * @retval         > 0     success
+ * @retval         <=0     failed
+ *
+ * @note           None
+ */
+int tls_ssl_server_send(tls_ssl_t *ssl, int s,char *sndbuf, int len,int flags);
+
+/**
+ * @brief          This function is used to receive data
+ *
+ * @param[in]      *ssl         SSL hanlde
+ * @param[in]      s            socket number
+ * @param[in]      *buf         receive buffer
+ * @param[in]      len          receive buffer length
+ * @param[in]      flags        some flags
+ *
+ * @retval         > 0     success
+ * @retval         <=0     failed
+ *
+ * @note           None
+ */
+int tls_ssl_server_recv(tls_ssl_t *ssl,int s,char *buf, int len,int flags);
+
+/**
+ * @brief          This function is used to close connection
+ *
+ * @param[in]      *ssl         SSL hanlde
+ * @param[in]      s            socket number
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_ssl_server_close_conn(tls_ssl_t *ssl, int s);
+
+/**
+ * @brief          This function is used to close SSL Server
+ *
+ * @param[in]      *keys        SSL keys
+ *
+ * @retval         0         success
+ * @retval         other     failed
+ *
+ * @note           None
+ */
+int tls_ssl_server_close(tls_ssl_key_t * keys);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /*TLS_CONFIG_SERVER_SIDE_SSL*/
+#endif /*_SSL_SERVER_H_*/
+

+ 65 - 0
include/app/wm_webserver.h

@@ -0,0 +1,65 @@
+/**
+ * @file    wm_webserver.h
+ *
+ * @brief   WEB SERVER
+ *
+ * @author  winnermicro
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef __WEBSERVER_H__
+#define __WEBSERVER_H__
+
+/**
+ * @defgroup APP_APIs APP APIs
+ * @brief APP APIs
+ */
+
+/**
+ * @addtogroup APP_APIs
+ * @{
+ */
+
+/**
+ * @defgroup WEB_APIs WEB APIs
+ * @brief WEB server APIs
+ */
+
+/**
+ * @addtogroup WEB_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to start WEB SERVER service
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_webserver_init(void);
+
+/**
+ * @brief          This function is used to deinit WEB SERVER service
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_webserver_deinit(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /*__WEBSERVER_H__*/
+

+ 291 - 0
include/app/wm_wifi_oneshot.h

@@ -0,0 +1,291 @@
+/**
+ * @file    wm_wifi_oneshot.h
+ *
+ * @brief   Wi-Fi OneShot
+ *
+ * @author  winnermicro
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef WM_WIFI_ONESHOT_H
+#define WM_WIFI_ONESHOT_H
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wm_type_def.h>
+#if (GCC_COMPILE==1)
+#include "wm_ieee80211_gcc.h"
+#else
+#include <wm_ieee80211.h>
+#endif
+#include "wm_config.h"
+#include "wm_bt_config.h"
+
+/**   DEBUG USE MAC FILTER START   */
+#define CONFIG_ONESHOT_MAC_FILTER               0
+extern int tls_filter_module_srcmac(u8 *mac);
+
+
+
+#define ONESHOT_ON                              1
+#define ONESHOT_OFF                             0
+
+/* ONE SHOT */
+/** UDP MULTICAST ONE SHOT */
+#define TLS_CONFIG_UDP_ONE_SHOT          ONESHOT_ON
+
+/** WinnerMicro ONSHOT */
+#define TLS_CONFIG_UDP_LSD_SPECIAL	 	(ONESHOT_ON&& TLS_CONFIG_UDP_ONE_SHOT)
+
+/** AP ONESHOT */
+#define TLS_CONFIG_AP_MODE_ONESHOT      (ONESHOT_ON && TLS_CONFIG_AP)
+#define TLS_CONFIG_WEB_SERVER_MODE      (ONESHOT_ON && TLS_CONFIG_AP_MODE_ONESHOT)
+#define TLS_CONFIG_SOCKET_MODE          (ONESHOT_ON && TLS_CONFIG_AP_MODE_ONESHOT)
+
+
+/** AIRKISS ONESHOT */
+#define TLS_CONFIG_AIRKISS_MODE_ONESHOT (ONESHOT_OFF && TLS_CONFIG_UDP_ONE_SHOT)
+#define AIRKISS_USE_SELF_WRITE                 1
+
+
+/** BLE ONESHOT */
+#define TLS_CONFIG_BLE_WIFI_ONESHOT  (ONESHOT_ON && (WM_BLE_INCLUDED == CFG_ON || WM_NIMBLE_INCLUDED == CFG_ON))
+
+typedef enum{
+	ONESHOT_SCAN_START,
+	ONESHOT_SCAN_FINISHED,
+	ONESHOT_SWITCH_CHANNEL,
+	ONESHOT_STOP_TMP_CHAN_SWITCH,	
+	ONESHOT_STOP_CHAN_SWITCH,
+	ONESHOT_HANDSHAKE_TIMEOUT,
+	ONESHOT_RECV_TIMEOUT,	
+	ONESHOT_RECV_ERR,
+	ONESHOT_STOP_DATA_CLEAR,
+	ONESHOT_NET_UP,
+	AP_SOCK_S_MSG_SOCKET_RECEIVE_DATA,
+	AP_WEB_S_MSG_RECEIVE_DATA,
+	AP_SOCK_S_MSG_SOCKET_CREATE,
+	AP_SOCK_S_MSG_WJOIN_FAILD,	
+}ONESHOT_MSG_ENUM;
+
+/**
+ * @defgroup APP_APIs APP APIs
+ * @brief APP APIs
+ */
+
+/**
+ * @addtogroup APP_APIs
+ * @{
+ */
+
+/**
+ * @defgroup Oneshot_APIs Oneshot APIs
+ * @brief Wi-Fi oneshot APIs
+ */
+
+/**
+ * @addtogroup Oneshot_APIs
+ * @{
+ */
+
+/**
+ * @brief		  This function is used to set oneshot flag.
+ *
+ * @param[in]	  flag, 0: one shot closed
+ *                      1: one shot open
+ *                      2: AP+socket
+ *                      3: AP+WEBSERVER
+ *                      4: bt
+ *
+ * @param[out]    None
+ * 
+ * @retval	      0: success
+ *                  -1: failed
+ *
+ * @note		  None
+ */
+int tls_wifi_set_oneshot_flag(u8 flag);
+
+/**
+ * @brief		  This function is used to get oneshot flag.
+ *
+ * @param[in]	  None 
+ *
+ * @param[out]    None
+ * 
+ * @retval	      0: one shot closed
+ *                1: one shot open
+ *                2: AP+socket
+ *                3: AP+WEBSERVER
+ *                4: bt
+ *
+ * @note		  None
+ */
+int tls_wifi_get_oneshot_flag(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @brief          Handle wild packets coming from the air.
+ *
+ * @param[in]      *hdr     point to ieee80211 data header
+ * @param[in]      data_len data len of ieee80211 data
+ *
+ * @retval         no mean
+ *
+ * @note           None
+ */
+u8 tls_wifi_dataframe_recv(struct ieee80211_hdr *hdr, u32 data_len);
+
+#if TLS_CONFIG_AIRKISS_MODE_ONESHOT
+/**
+ * @brief          This function is used to acknowledge app when airkiss process is done.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void oneshot_airkiss_send_reply(void);
+/**
+ * @brief          This function is used to deal with airkiss's
+ 				   wild packet
+ *
+ * @param[in]      *data       ieee80211 packet
+ * @param[in]      data_len    packet length
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_airkiss_recv(u8 *data, u16 data_len);
+/**
+ * @brief          This function is used to start airkiss
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_airkiss_start(void);
+/**
+ * @brief          This function is used to stop airkiss
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_airkiss_stop(void);
+
+/**
+ * @brief          This function is used to change channel for airkiss
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_oneshot_airkiss_change_channel(void);
+#endif /*TLS_CONFIG_AIRKISS_MODE_ONESHOT*/
+
+/**
+ * @brief          This function is used to init oneshot task
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           Not in use now
+ */
+int wm_oneshot_task_init(void);
+
+/**
+ * @brief          This function is used to stop oneshot timer
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_oneshot_switch_channel_tim_stop(struct ieee80211_hdr *hdr);
+
+/**
+ * @brief          This function is used to stop oneshot temp timer
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_oneshot_switch_channel_tim_temp_stop(void);
+
+/**
+ * @brief          handle if use bssid to connect wifi.
+ *
+ * @param[in]      *ssid      : ap name to connect
+ * @param[in]      *ssid_len: ap name's length to connect
+ * @param[in]      *bssid    : ap bssid
+ *
+ * @retval         no mean
+ *
+ * @note           None
+ */
+int tls_oneshot_if_use_bssid(u8 *ssid, u8 *ssid_len, u8 *bssid);
+
+/**
+ * @brief          Find channel according to ssid
+ *
+ * @param[in]      *ssid     ssid to be compared
+ * @param[in]       ssid_len  ssid length
+ * @param[out]     chlist    chlist to be add according to ssid info
+ *
+ * @retval          None
+ *
+ * @note           None
+ */
+void tls_oneshot_find_chlist(u8 *ssid, u8 ssid_len, u16 *chlist);
+
+/**
+ * @brief		  This function is to deal with oneshot event according netif status.
+ *
+ * @param[in]	  status:net status
+ *
+ * @param[out]     None
+ *
+ * @retval	        None
+ *
+ * @note		        None
+ */
+void wm_oneshot_netif_status_event(u8 status );
+
+#if TLS_CONFIG_WEB_SERVER_MODE
+/**
+ * @brief		   This function is used to send web config msg to oneshot task.
+ *
+ * @param[in]	  None 
+ *
+ * @param[out]    None
+ * 
+ * @retval	   None
+ *
+ * @note		   None
+ */
+void tls_oneshot_send_web_connect_msg(void);
+#endif
+
+#endif /*WM_WIFI_ONESHOT_H*/
+

+ 16 - 0
include/arch/xt804/csi_config.h

@@ -0,0 +1,16 @@
+#ifndef __CSI_CONFIG_H__
+#define __CSI_CONFIG_H__
+#define CONFIG_CHIP_SL04 1
+#define CONFIG_KERNEL_FREERTOS 1
+//#define CONFIG_KERNEL_NONE 1
+#define CONFIG_HAVE_VIC 1
+#define CONFIG_SEPARATE_IRQ_SP 1
+#define CONFIG_ARCH_INTERRUPTSTACK 4096
+#define CONFIG_IRQ_VECTOR_SIZE   256
+#define USE_UART0_PRINT            1
+
+#ifdef CONFIG_KERNEL_NONE
+#define CONFIG_SYSTEM_SECURE  1
+#endif
+
+#endif

+ 1612 - 0
include/arch/xt804/csi_core/core_804.h

@@ -0,0 +1,1612 @@
+/*
+ * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/******************************************************************************
+ * @file     core_804.h
+ * @brief    CSI 804 Core Peripheral Access Layer Header File
+ * @version  V1.0
+ * @date     02. June 2017
+ ******************************************************************************/
+
+#ifndef __CORE_804_H_GENERIC
+#define __CORE_804_H_GENERIC
+
+#include <stdint.h>
+#include "csi_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ *                 CSI definitions
+ ******************************************************************************/
+/**
+  \ingroup Ck804
+  @{
+ */
+
+/*  CSI CK804 definitions */
+#define __CK804_CSI_VERSION_MAIN  (0x04U)                                      /*!< [31:16] CSI HAL main version */
+#define __CK804_CSI_VERSION_SUB   (0x1EU)                                      /*!< [15:0]  CSI HAL sub version */
+#define __CK804_CSI_VERSION       ((__CK804_CSI_VERSION_MAIN << 16U) | \
+                                   __CK804_CSI_VERSION_SUB           )         /*!< CSI HAL version number */
+
+#ifndef __CK80X
+#define __CK80X                (0x03U)                                         /*!< CK80X Core */
+#endif
+
+/* __FPU_USED indicates whether an FPU is used or not. */
+#define __FPU_USED       1U
+
+#if defined ( __GNUC__ )
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CK804_H_GENERIC */
+
+#ifndef __CSI_GENERIC
+
+#ifndef __CORE_CK804_H_DEPENDANT
+#define __CORE_CK804_H_DEPENDANT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#ifndef __CK804_REV
+#define __CK804_REV               0x0000U
+#endif
+
+#ifndef __VIC_PRIO_BITS
+#define __VIC_PRIO_BITS           2U
+#endif
+
+#ifndef __Vendor_SysTickConfig
+#define __Vendor_SysTickConfig    1U
+#endif
+
+#ifndef __GSR_GCR_PRESENT
+#define __GSR_GCR_PRESENT         0U
+#endif
+
+#ifndef __MPU_PRESENT
+#define __MPU_PRESENT             1U
+#endif
+
+#ifndef __ICACHE_PRESENT
+#define __ICACHE_PRESENT          1U
+#endif
+
+#ifndef __DCACHE_PRESENT
+#define __DCACHE_PRESENT          1U
+#endif
+
+#include <csi_gcc.h>
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CSI_glob_defs CSI Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+#define     __I      volatile             /*!< Defines 'read only' permissions */
+#else
+#define     __I      volatile const       /*!< Defines 'read only' permissions */
+#endif
+#define     __O      volatile             /*!< Defines 'write only' permissions */
+#define     __IO     volatile             /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define     __IM     volatile const       /*! Defines 'read only' structure member permissions */
+#define     __OM     volatile             /*! Defines 'write only' structure member permissions */
+#define     __IOM    volatile             /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group CK804 */
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core VIC Register
+  - Core Cache Register
+  - Core CoreTIM Register
+ ******************************************************************************/
+/**
+  \defgroup CSI_core_register Defines and Type Definitions
+  \brief Type definitions and defines for CK80X processor based devices.
+*/
+
+/**
+  \ingroup    CSI_core_register
+  \defgroup   CSI_CORE  Status and Control Registers
+  \brief      Core Register type definitions.
+  @{
+ */
+
+/**
+  \brief  Access Processor Status Register(PSR)struct definition.
+ */
+typedef union {
+    struct {
+        uint32_t C: 1;                       /*!< bit:      0  Conditional code/Carry flag */
+        uint32_t _reserved0: 5;              /*!< bit:  2.. 5  Reserved */
+        uint32_t IE: 1;                      /*!< bit:      6  Interrupt effective control bit */
+        uint32_t IC: 1;                      /*!< bit:      7  Interrupt control bit */
+        uint32_t EE: 1;                      /*!< bit:      8  Abnormally effective control bit */
+        uint32_t MM: 1;                      /*!< bit:      9  Unsymmetrical masking bit */
+        uint32_t _reserved1: 6;              /*!< bit: 10..15  Reserved */
+        uint32_t VEC: 8;                     /*!< bit: 16..23  Abnormal event vector value */
+        uint32_t _reserved2: 1;              /*!< bit:     24  Reserved */
+        uint32_t SV: 1;                      /*!< bit:     25  Stacked valid */
+        uint32_t SD: 1;                      /*!< bit:     26  Stacked dirty */
+        uint32_t SC: 1;                      /*!< bit:     27  Secure call bit */
+        uint32_t HS: 1;                      /*!< bit:     28  Hardware stacked bit */
+        uint32_t SP: 1;                      /*!< bit:     29  Secure pending bit */
+        uint32_t T: 1;                       /*!< bit:     30  TEE mode bit */
+        uint32_t S: 1;                       /*!< bit:     31  Superuser mode set bit */
+    } b;                                   /*!< Structure    Access by bit */
+    uint32_t w;                            /*!< Type         Access by whole register */
+} PSR_Type;
+
+/* PSR Register Definitions */
+#define PSR_S_Pos                          31U                                            /*!< PSR: S Position */
+#define PSR_S_Msk                          (1UL << PSR_S_Pos)                             /*!< PSR: S Mask */
+
+#define PSR_T_Pos                          30U                                            /*!< PSR: T Position */
+#define PSR_T_Msk                          (1UL << PSR_T_Pos)                             /*!< PSR: T Mask */
+
+#define PSR_VEC_Pos                        16U                                            /*!< PSR: VEC Position */
+#define PSR_VEC_Msk                        (0x7FUL << PSR_VEC_Pos)                        /*!< PSR: VEC Mask */
+
+#define PSR_MM_Pos                         9U                                             /*!< PSR: MM Position */
+#define PSR_MM_Msk                         (1UL << PSR_MM_Pos)                            /*!< PSR: MM Mask */
+
+#define PSR_EE_Pos                         8U                                             /*!< PSR: EE Position */
+#define PSR_EE_Msk                         (1UL << PSR_EE_Pos)                            /*!< PSR: EE Mask */
+
+#define PSR_IC_Pos                         7U                                             /*!< PSR: IC Position */
+#define PSR_IC_Msk                         (1UL << PSR_IC_Pos)                            /*!< PSR: IC Mask */
+
+#define PSR_IE_Pos                         6U                                             /*!< PSR: IE Position */
+#define PSR_IE_Msk                         (1UL << PSR_IE_Pos)                            /*!< PSR: IE Mask */
+
+#define PSR_C_Pos                          0U                                             /*!< PSR: C Position */
+#define PSR_C_Msk                          (1UL << PSR_C_Pos)                             /*!< PSR: C Mask */
+
+/**
+  \brief Consortium definition for accessing Cache Configuration Registers(CCR, CR<18, 0>).
+ */
+typedef union {
+    struct {
+        uint32_t MP: 1;                      /*!< bit:  0.. 1  memory protection settings */
+        uint32_t _reserved0: 6;              /*!< bit:  2.. 6  Reserved */
+        uint32_t BE: 1;                      /*!< bit:      7  Endian mode */
+        uint32_t SCK: 3;                     /*!< bit:  8..10  the clock ratio of the system and the processor */
+        uint32_t _reserved1: 2;              /*!< bit: 11..12  Reserved */
+        uint32_t BE_V2: 1;                   /*!< bit:     13  V2 Endian mode */
+        uint32_t _reserved2: 18;             /*!< bit: 14..31  Reserved */
+    } b;                                   /*!< Structure    Access by bit */
+    uint32_t w;                            /*!< Type         Access by whole register */
+} CCR_Type;
+
+/* CCR Register Definitions */
+#define CCR_BE_V2_Pos                     13U                                            /*!< CCR: BE_V2 Position */
+#define CCR_BE_V2_Msk                     (0x1UL << CCR_BE_V2_Pos)                       /*!< CCR: BE_V2 Mask */
+
+#define CCR_SCK_Pos                       8U                                             /*!< CCR: SCK Position */
+#define CCR_SCK_Msk                       (0x3UL << CCR_SCK_Pos)                         /*!< CCR: SCK Mask */
+
+#define CCR_BE_Pos                        7U                                             /*!< CCR: BE Position */
+#define CCR_BE_Msk                        (0x1UL << CCR_BE_Pos)                          /*!< CCR: BE Mask */
+
+#define CCR_MP_Pos                        0U                                             /*!< CCR: MP Position */
+#define CCR_MP_Msk                        (0x3UL << CCR_MP_Pos)                          /*!< CCR: MP Mask */
+
+/**
+  \brief  Consortium definition for accessing high ease access permission configutation registers(CAPR, CR<19,0>)
+ */
+typedef union {
+    struct {
+        uint32_t X0: 1;                      /*!< bit:      0  Non executable attribute setting */
+        uint32_t X1: 1;                      /*!< bit:      1  Non executable attribute setting */
+        uint32_t X2: 1;                      /*!< bit:      2  Non executable attribute setting */
+        uint32_t X3: 1;                      /*!< bit:      3  Non executable attribute setting */
+        uint32_t X4: 1;                      /*!< bit:      4  Non executable attribute setting */
+        uint32_t X5: 1;                      /*!< bit:      5  Non executable attribute setting */
+        uint32_t X6: 1;                      /*!< bit:      6  Non executable attribute setting */
+        uint32_t X7: 1;                      /*!< bit:      7  Non executable attribute setting */
+        uint32_t AP0: 2;                     /*!< bit:  8.. 9  access permissions settings bit */
+        uint32_t AP1: 2;                     /*!< bit: 10..11  access permissions settings bit */
+        uint32_t AP2: 2;                     /*!< bit: 12..13  access permissions settings bit */
+        uint32_t AP3: 2;                     /*!< bit: 14..15  access permissions settings bit */
+        uint32_t AP4: 2;                     /*!< bit: 16..17  access permissions settings bit */
+        uint32_t AP5: 2;                     /*!< bit: 18..19  access permissions settings bit */
+        uint32_t AP6: 2;                     /*!< bit: 20..21  access permissions settings bit */
+        uint32_t AP7: 2;                     /*!< bit: 22..23  access permissions settings bit */
+        uint32_t S0: 1;                      /*!< bit:     24  Security property settings */
+        uint32_t S1: 1;                      /*!< bit:     25  Security property settings */
+        uint32_t S2: 1;                      /*!< bit:     26  Security property settings */
+        uint32_t S3: 1;                      /*!< bit:     27  Security property settings */
+        uint32_t S4: 1;                      /*!< bit:     28  Security property settings */
+        uint32_t S5: 1;                      /*!< bit:     29  Security property settings */
+        uint32_t S6: 1;                      /*!< bit:     30  Security property settings */
+        uint32_t S7: 1;                      /*!< bit:     31  Security property settings */
+    } b;                                   /*!< Structure    Access by bit */
+    uint32_t w;                            /*!< Type         Access by whole register */
+} CAPR_Type;
+
+/* CAPR Register Definitions */
+#define CAPR_S7_Pos                        31U                                            /*!< CAPR: S7 Position */
+#define CAPR_S7_Msk                        (1UL << CAPR_S7_Pos)                           /*!< CAPR: S7 Mask */
+
+#define CAPR_S6_Pos                        30U                                            /*!< CAPR: S6 Position */
+#define CAPR_S6_Msk                        (1UL << CAPR_S6_Pos)                           /*!< CAPR: S6 Mask */
+
+#define CAPR_S5_Pos                        29U                                            /*!< CAPR: S5 Position */
+#define CAPR_S5_Msk                        (1UL << CAPR_S5_Pos)                           /*!< CAPR: S5 Mask */
+
+#define CAPR_S4_Pos                        28U                                            /*!< CAPR: S4 Position */
+#define CAPR_S4_Msk                        (1UL << CAPR_S4_Pos)                           /*!< CAPR: S4 Mask */
+
+#define CAPR_S3_Pos                        27U                                            /*!< CAPR: S3 Position */
+#define CAPR_S3_Msk                        (1UL << CAPR_S3_Pos)                           /*!< CAPR: S3 Mask */
+
+#define CAPR_S2_Pos                        26U                                            /*!< CAPR: S2 Position */
+#define CAPR_S2_Msk                        (1UL << CAPR_S2_Pos)                           /*!< CAPR: S2 Mask */
+
+#define CAPR_S1_Pos                        25U                                            /*!< CAPR: S1 Position */
+#define CAPR_S1_Msk                        (1UL << CAPR_S1_Pos)                           /*!< CAPR: S1 Mask */
+
+#define CAPR_S0_Pos                        24U                                            /*!< CAPR: S0 Position */
+#define CAPR_S0_Msk                        (1UL << CAPR_S0_Pos)                           /*!< CAPR: S0 Mask */
+
+#define CAPR_AP7_Pos                       22U                                            /*!< CAPR: AP7 Position */
+#define CAPR_AP7_Msk                       (0x3UL << CAPR_AP7_Pos)                        /*!< CAPR: AP7 Mask */
+
+#define CAPR_AP6_Pos                       20U                                            /*!< CAPR: AP6 Position */
+#define CAPR_AP6_Msk                       (0x3UL << CAPR_AP6_Pos)                        /*!< CAPR: AP6 Mask */
+
+#define CAPR_AP5_Pos                       18U                                            /*!< CAPR: AP5 Position */
+#define CAPR_AP5_Msk                       (0x3UL << CAPR_AP5_Pos)                        /*!< CAPR: AP5 Mask */
+
+#define CAPR_AP4_Pos                       16U                                            /*!< CAPR: AP4 Position */
+#define CAPR_AP4_Msk                       (0x3UL << CAPR_AP4_Pos)                        /*!< CAPR: AP4 Mask */
+
+#define CAPR_AP3_Pos                       14U                                            /*!< CAPR: AP3 Position */
+#define CAPR_AP3_Msk                       (0x3UL << CAPR_AP3_Pos)                        /*!< CAPR: AP3 Mask */
+
+#define CAPR_AP2_Pos                       12U                                            /*!< CAPR: AP2 Position */
+#define CAPR_AP2_Msk                       (0x3UL << CAPR_AP2_Pos)                        /*!< CAPR: AP2 Mask */
+
+#define CAPR_AP1_Pos                       10U                                            /*!< CAPR: AP1 Position */
+#define CAPR_AP1_Msk                       (0x3UL << CAPR_AP1_Pos)                        /*!< CAPR: AP1 Mask */
+
+#define CAPR_AP0_Pos                       8U                                             /*!< CAPR: AP0 Position */
+#define CAPR_AP0_Msk                       (0x3UL << CAPR_AP0_Pos)                        /*!< CAPR: AP0 Mask */
+
+#define CAPR_X7_Pos                        7U                                             /*!< CAPR: X7 Position */
+#define CAPR_X7_Msk                        (0x1UL << CAPR_X7_Pos)                         /*!< CAPR: X7 Mask */
+
+#define CAPR_X6_Pos                        6U                                             /*!< CAPR: X6 Position */
+#define CAPR_X6_Msk                        (0x1UL << CAPR_X6_Pos)                         /*!< CAPR: X6 Mask */
+
+#define CAPR_X5_Pos                        5U                                             /*!< CAPR: X5 Position */
+#define CAPR_X5_Msk                        (0x1UL << CAPR_X5_Pos)                         /*!< CAPR: X5 Mask */
+
+#define CAPR_X4_Pos                        4U                                             /*!< CAPR: X4 Position */
+#define CAPR_X4_Msk                        (0x1UL << CAPR_X4_Pos)                         /*!< CAPR: X4 Mask */
+
+#define CAPR_X3_Pos                        3U                                             /*!< CAPR: X3 Position */
+#define CAPR_X3_Msk                        (0x1UL << CAPR_X3_Pos)                         /*!< CAPR: X3 Mask */
+
+#define CAPR_X2_Pos                        2U                                             /*!< CAPR: X2 Position */
+#define CAPR_X2_Msk                        (0x1UL << CAPR_X2_Pos)                         /*!< CAPR: X2 Mask */
+
+#define CAPR_X1_Pos                        1U                                             /*!< CAPR: X1 Position */
+#define CAPR_X1_Msk                        (0x1UL << CAPR_X1_Pos)                         /*!< CAPR: X1 Mask */
+
+#define CAPR_X0_Pos                        0U                                             /*!< CAPR: X0 Position */
+#define CAPR_X0_Msk                        (0x1UL << CAPR_X0_Pos)                         /*!< CAPR: X0 Mask */
+
+/**
+  \brief  Consortium definition for accessing control register(PACR, CR<20,0>).
+ */
+typedef union {
+    struct {
+        uint32_t E: 1;                       /*!< bit:      0  Effective setting of protected area */
+        uint32_t size: 5;                    /*!< bit:  1.. 5  Size of protected area */
+        uint32_t _reserved0: 6;              /*!< bit:  6.. 11 Reserved */
+        uint32_t base_addr: 20;              /*!< bit:  10..31 The high position of the address of a protected area */
+    } b;                                   /*!< Structure    Access by bit */
+    uint32_t w;                            /*!< Type         Access by whole register */
+} PACR_Type;
+
+/* PACR Register Definitions */
+#define PACR_BASE_ADDR_Pos                 12U                                            /*!< PACR: base_addr Position */
+#define PACR_BASE_ADDR_Msk                 (0xFFFFFUL << PACR_BASE_ADDR_Pos)              /*!< PACR: base_addr Mask */
+
+#define PACR_SIZE_Pos                      1U                                             /*!< PACR: Size Position */
+#define PACR_SIZE_Msk                      (0x1FUL << PACR_SIZE_Pos)                      /*!< PACR: Size Mask */
+
+#define PACR_E_Pos                         0U                                             /*!< PACR: E Position */
+#define PACR_E_Msk                         (0x1UL << PACR_E_Pos)                          /*!< PACR: E Mask */
+
+/**
+  \brief  Consortium definition for accessing protection area selection register(PRSR,CR<21,0>).
+ */
+typedef union {
+    struct {
+        uint32_t RID: 3;                     /*!< bit:  0.. 2  Protected area index value */
+        uint32_t _reserved0: 29;             /*!< bit:  3..31  Reserved */
+    } b;                                     /*!< Structure    Access by bit */
+    uint32_t w;                              /*!< Type         Access by whole register */
+} PRSR_Type;
+
+/* PRSR Register Definitions */
+#define PRSR_RID_Pos                       0U                                            /*!< PRSR: RID Position */
+#define PRSR_RID_Msk                       (0x7UL << PRSR_RID_Pos)                       /*!< PRSR: RID Mask */
+
+/**
+  \brief  Consortium definition for CPU Hint Register(CHR, CR<31,0>).
+ */
+typedef union {
+    struct {
+        uint32_t _reserved0: 1;              /*!< bit:  0      Reserved */
+        uint32_t BE: 1;                      /*!< bit:  1      System bus support burst transer */
+        uint32_t IPE: 1;                     /*!< bit:  2      Instruction prefetch function enable */
+        uint32_t RPE: 1;                     /*!< bit:  3      Function return instruction RTS will speculate execution */
+        uint32_t IAE: 1;                     /*!< bit:  4      Interrupt response acceleration enable */
+        uint32_t _reserved1: 9;              /*!< bit:  5..13  Reserved */
+        uint32_t ISE: 1;                     /*!< bit: 14      Interrupt SP enable */
+        uint32_t HS_EXP: 1;                  /*!< bit: 15      Exception bit for TEE world switch */
+        uint32_t SRST_VAL: 16;               /*!< bit: 16..31  Software reset decision value */
+    } b;
+    uint32_t w;
+} CHR_Type;
+
+/* CHR Register Definitions */
+#define CHR_BE_Pos                         1U                                            /*!< CHR: BE Position */
+#define CHR_BE_Msk                         (1UL << CHR_BE_Pos)                           /*!< CHR: BE Mask */
+#define CHR_IPE_Pos                        1U                                            /*!< CHR: IPE Position */
+#define CHR_IPE_Msk                        (1UL << CHR_IPE_Pos)                          /*!< CHR: IPE Mask */
+#define CHR_RPE_Pos                        1U                                            /*!< CHR: RPE Position */
+#define CHR_RPE_Msk                        (1UL << CHR_RPE_Pos)                          /*!< CHR: RPE Mask */
+#define CHR_IAE_Pos                        4U                                            /*!< CHR: IAE Position */
+#define CHR_IAE_Msk                        (0x1UL << CHR_IAE_Pos)                        /*!< CHR: IAE Mask */
+#define CHR_ISE_Pos                        14U                                           /*!< CHR: ISE Position */
+#define CHR_ISE_Msk                        (0x1UL << CHR_ISE_Pos)                        /*!< CHR: ISE Mask */
+#define CHR_HS_EXP_Pos                     15U                                           /*!< CHR: HS_EXP Position */
+#define CHR_HS_EXP_Msk                     (0x1UL << CHR_HS_EXP_Pos)                     /*!< CHR: HS_EXP Mask */
+#define CHR_SRST_VAL_Pos                   16U                                           /*!< CHR: SRST_VAL Position */
+#define CHR_SRST_VAL_Mask                  (0xFFFFUL << CHR_SRST_VAL_Pos)                /*!< CHR: SRST_VAL Mask */
+
+/*@} end of group CSI_CORE */
+
+
+/**
+  \ingroup    CSI_core_register
+  \defgroup   CSI_VIC Vectored Interrupt Controller (VIC)
+  \brief      Type definitions for the VIC Registers
+  @{
+ */
+
+/**
+  \brief Access to the structure of a vector interrupt controller.
+ */
+typedef struct {
+    __IOM uint32_t ISER[4U];               /*!< Offset: 0x000 (R/W)  Interrupt set enable register */
+    uint32_t RESERVED0[12U];
+    __IOM uint32_t IWER[4U];               /*!< Offset: 0x040 (R/W)  Interrupt wake-up set register */
+    uint32_t RESERVED1[12U];
+    __IOM uint32_t ICER[4U];               /*!< Offset: 0x080 (R/W)  Interrupt clear enable register */
+    uint32_t RESERVED2[12U];
+    __IOM uint32_t IWDR[4U];               /*!< Offset: 0x0c0 (R/W)  Interrupt wake-up clear register */
+    uint32_t RESERVED3[12U];
+    __IOM uint32_t ISPR[4U];               /*!< Offset: 0x100 (R/W)  Interrupt set pend register */
+    uint32_t RESERVED4[12U];
+    __IOM uint32_t ISSR[4U];               /*!< Offset: 0x140 (R/W)  Security interrupt set register */
+    uint32_t RESERVED5[12U];
+    __IOM uint32_t ICPR[4U];               /*!< Offset: 0x180 (R/W)  Interrupt clear pend register */
+    uint32_t RESERVED6[12U];
+    __IOM uint32_t ICSR[4U];               /*!< Offset: 0x1c0 (R/W)  Security interrupt clear register */
+    uint32_t RESERVED7[12U];
+    __IOM uint32_t IABR[4U];               /*!< Offset: 0x200 (R/W)  Interrupt answer stateregister */
+    uint32_t RESERVED8[60U];
+    __IOM uint32_t IPR[32U];               /*!< Offset: 0x300 (R/W)  Interrupt priority register */
+    uint32_t RESERVED9[480U];
+    __IM  uint32_t ISR;                    /*!< Offset: 0xB00 (R/ )  Interrupt state register */
+    __IOM uint32_t IPTR;                   /*!< Offset: 0xB04 (R/W)  Interrupt priority thershold register */
+    __IOM uint32_t TSPEND;                 /*!< Offset: 0xB08 (R/W)  Task pending register */
+    __IOM uint32_t TSABR;                  /*!< Offset: 0xB0c (R/W)  Tspend acknowledge register */
+    __IOM uint32_t TSPR;                   /*!< Offset: 0xB10 (R/W)  Tspend priority register */
+} VIC_Type;
+
+/*@} end of group CSI_VIC */
+
+/**
+  \ingroup    CSI_core_register
+  \defgroup   CSI_CACHE
+  \brief      Type definitions for the cache Registers
+  @{
+ */
+
+/**
+  \brief On chip cache structure.
+ */
+typedef struct
+{
+  __IOM uint32_t CER;                    /*!< Offset: 0x000 (R/W)  Cache enable register */
+  __IOM uint32_t CIR;                    /*!< Offset: 0x004 (R/W)  Cache invalid register */
+  __IOM uint32_t CRCR[4U];               /*!< Offset: 0x008 (R/W)  Cache Configuration register */
+        uint32_t RSERVED0[1015U];
+  __IOM uint32_t CPFCR;                  /*!< Offset: 0xFF4 (R/W)  Cache performance analisis control register */
+  __IOM uint32_t CPFATR;                 /*!< Offset: 0xFF8 (R/W)  Cache access times register */
+  __IOM uint32_t CPFMTR;                 /*!< Offset: 0xFFC (R/W)  Cache missing times register */
+} CACHE_Type;
+
+/* CACHE Register Definitions */
+#define CACHE_CER_EN_Pos                       0U                                            /*!< CACHE CER: EN Position */
+#define CACHE_CER_EN_Msk                       (0x1UL << CACHE_CER_EN_Pos)                   /*!< CACHE CER: EN Mask */
+
+#define CACHE_CER_CFIG_Pos                     1U                                            /*!< CACHE CER: CFIG Position */
+#define CACHE_CER_CFIG_Msk                     (0x1UL << CACHE_CER_CFIG_Pos)                 /*!< CACHE CER: CFIG Mask */
+
+#define CACHE_CER_WB_Pos                       2U                                            /*!< CACHE CER: WB Position */
+#define CACHE_CER_WB_Msk                       (0x1UL << CACHE_CER_WB_Pos)                   /*!< CACHE CER: WB Mask */
+
+#define CACHE_CER_DCW_Pos                      4U                                            /*!< CACHE CER: DCW Position */
+#define CACHE_CER_DCW_Msk                      (0x1UL << CACHE_CER_DCW_Pos)                  /*!< CACHE CER: DCW Mask */
+
+#define CACHE_CER_WA_Pos                       5U                                            /*!< CACHE CER: WA Position */
+#define CACHE_CER_WA_Msk                       (0x1UL << CACHE_CER_WA_Pos)                   /*!< CACHE CER: WA Mask */
+
+#define CACHE_CIR_INV_ALL_Pos                  0U                                            /*!< CACHE CIR: INV_ALL Position */
+#define CACHE_CIR_INV_ALL_Msk                  (0x1UL << CACHE_CIR_INV_ALL_Pos)              /*!< CACHE CIR: INV_ALL Mask */
+
+#define CACHE_CIR_INV_ONE_Pos                  1U                                            /*!< CACHE CIR: INV_ONE Position */
+#define CACHE_CIR_INV_ONE_Msk                  (0x1UL << CACHE_CIR_INV_ONE_Pos)              /*!< CACHE CIR: INV_ONE Mask */
+
+#define CACHE_CIR_CLR_ALL_Pos                  2U                                            /*!< CACHE CIR: CLR_ALL Position */
+#define CACHE_CIR_CLR_ALL_Msk                  (0x1UL << CACHE_CIR_CLR_ALL_Pos)              /*!< CACHE CIR: CLR_ALL Mask */
+
+#define CACHE_CIR_CLR_ONE_Pos                  3U                                            /*!< CACHE CIR: CLR_ONE Position */
+#define CACHE_CIR_CLR_ONE_Msk                  (0x1UL << CACHE_CIR_CLR_ONE_Pos)              /*!< CACHE CIR: CLR_ONE Mask */
+
+#define CACHE_CIR_INV_ADDR_Pos                 4U                                            /*!< CACHE CIR: INV_ADDR Position */
+#define CACHE_CIR_INV_ADDR_Msk                 (0xFFFFFFFUL << CACHE_CIR_INV_ADDR_Pos)       /*!< CACHE CIR: INV_ADDR Mask */
+
+#define CACHE_CRCR_EN_Pos                      0U                                            /*!< CACHE CRCR: EN Position */
+#define CACHE_CRCR_EN_Msk                      (0x1UL << CACHE_CRCR_EN_Pos)                  /*!< CACHE CRCR: EN Mask */
+
+#define CACHE_CRCR_SIZE_Pos                    1U                                            /*!< CACHE CRCR: Size Position */
+#define CACHE_CRCR_SIZE_Msk                    (0x1FUL << CACHE_CRCR_SIZE_Pos)               /*!< CACHE CRCR: Size Mask */
+
+#define CACHE_CRCR_SE_Pos                      6U                                            /*!< CACHE CRCR: SE Position */
+#define CACHE_CRCR_SE_Msk                      (0x1UL << CACHE_CRCR_SE_Pos)                  /*!< CACHE CRCR: SE Mask */
+
+#define CACHE_CRCR_BASE_ADDR_Pos               10U                                           /*!< CACHE CRCR: base addr Position */
+#define CACHE_CRCR_BASE_ADDR_Msk               (0x3FFFFFUL << CACHE_CRCR_BASE_ADDR_Pos)      /*!< CACHE CRCR: base addr Mask */
+
+#define CACHE_CPFCR_PFEN_Pos                   0U                                            /*!< CACHE CPFCR: PFEN Position */
+#define CACHE_CPFCR_PFEN_Msk                   (0x1UL << CACHE_CPFCR_PFEN_Pos)               /*!< CACHE CPFCR: PFEN Mask */
+
+#define CACHE_CPFCR_PFRST_Pos                  1U                                            /*!< CACHE CPFCR: PFRST Position */
+#define CACHE_CPFCR_PFRST_Msk                  (0x1UL << CACHE_CPFCR_PFRST_Pos)              /*!< CACHE CPFCR: PFRST Mask */
+
+#define CACHE_CRCR_4K                          0xB                                           /* 01011 */
+#define CACHE_CRCR_8K                          0xC                                           /* 01100 */
+#define CACHE_CRCR_16K                         0xD                                           /* 01101 */
+#define CACHE_CRCR_32K                         0xE                                           /* 01110 */
+#define CACHE_CRCR_64K                         0xF                                           /* 01111 */
+#define CACHE_CRCR_128K                        0x10                                          /* 10000 */
+#define CACHE_CRCR_256K                        0x11                                          /* 10001 */
+#define CACHE_CRCR_512K                        0x12                                          /* 10010 */
+#define CACHE_CRCR_1M                          0x13                                          /* 10011 */
+#define CACHE_CRCR_2M                          0x14                                          /* 10100 */
+#define CACHE_CRCR_4M                          0x15                                          /* 10101 */
+#define CACHE_CRCR_8M                          0x16                                          /* 10110 */
+#define CACHE_CRCR_16M                         0x17                                          /* 10111 */
+#define CACHE_CRCR_32M                         0x18                                          /* 11000 */
+#define CACHE_CRCR_64M                         0x19                                          /* 11001 */
+#define CACHE_CRCR_128M                        0x1A                                          /* 11010 */
+#define CACHE_CRCR_256M                        0x1B                                          /* 11011 */
+#define CACHE_CRCR_512M                        0x1C                                          /* 11100 */
+#define CACHE_CRCR_1G                          0x1D                                          /* 11101 */
+#define CACHE_CRCR_2G                          0x1E                                          /* 11110 */
+#define CACHE_CRCR_4G                          0x1F                                          /* 11111 */
+
+/*@} end of group CSI_CACHE */
+
+
+/**
+  \ingroup  CSI_core_register
+  \defgroup CSI_SysTick     System Tick Timer (CORET)
+  \brief    Type definitions for the System Timer Registers.
+  @{
+ */
+
+/**
+  \brief  The data structure of the access system timer.
+ */
+typedef struct {
+    __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  Control register */
+    __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  Backfill register */
+    __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  Current register */
+    __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  Calibration register */
+} CORET_Type;
+
+/* CORET Control / Status Register Definitions */
+#define CORET_CTRL_COUNTFLAG_Pos           16U                                            /*!< CORET CTRL: COUNTFLAG Position */
+#define CORET_CTRL_COUNTFLAG_Msk           (1UL << CORET_CTRL_COUNTFLAG_Pos)              /*!< CORET CTRL: COUNTFLAG Mask */
+
+#define CORET_CTRL_CLKSOURCE_Pos           2U                                             /*!< CORET CTRL: CLKSOURCE Position */
+#define CORET_CTRL_CLKSOURCE_Msk           (1UL << CORET_CTRL_CLKSOURCE_Pos)              /*!< CORET CTRL: CLKSOURCE Mask */
+
+#define CORET_CTRL_TICKINT_Pos             1U                                             /*!< CORET CTRL: TICKINT Position */
+#define CORET_CTRL_TICKINT_Msk             (1UL << CORET_CTRL_TICKINT_Pos)                /*!< CORET CTRL: TICKINT Mask */
+
+#define CORET_CTRL_ENABLE_Pos              0U                                             /*!< CORET CTRL: ENABLE Position */
+#define CORET_CTRL_ENABLE_Msk              (1UL /*<< CORET_CTRL_ENABLE_Pos*/)             /*!< CORET CTRL: ENABLE Mask */
+
+    /* CORET Reload Register Definitions */
+#define CORET_LOAD_RELOAD_Pos              0U                                             /*!< CORET LOAD: RELOAD Position */
+#define CORET_LOAD_RELOAD_Msk              (0xFFFFFFUL /*<< CORET_LOAD_RELOAD_Pos*/)      /*!< CORET LOAD: RELOAD Mask */
+
+    /* CORET Current Register Definitions */
+#define CORET_VAL_CURRENT_Pos              0U                                             /*!< CORET VAL: CURRENT Position */
+#define CORET_VAL_CURRENT_Msk              (0xFFFFFFUL /*<< CORET_VAL_CURRENT_Pos*/)      /*!< CORET VAL: CURRENT Mask */
+
+    /* CORET Calibration Register Definitions */
+#define CORET_CALIB_NOREF_Pos              31U                                            /*!< CORET CALIB: NOREF Position */
+#define CORET_CALIB_NOREF_Msk              (1UL << CORET_CALIB_NOREF_Pos)                 /*!< CORET CALIB: NOREF Mask */
+
+#define CORET_CALIB_SKEW_Pos               30U                                            /*!< CORET CALIB: SKEW Position */
+#define CORET_CALIB_SKEW_Msk               (1UL << CORET_CALIB_SKEW_Pos)                  /*!< CORET CALIB: SKEW Mask */
+
+#define CORET_CALIB_TENMS_Pos              0U                                             /*!< CORET CALIB: TENMS Position */
+#define CORET_CALIB_TENMS_Msk              (0xFFFFFFUL /*<< CORET_CALIB_TENMS_Pos*/)      /*!< CORET CALIB: TENMS Mask */
+
+/*@} end of group CSI_SysTick */
+
+/**
+  \ingroup  CSI_core_register
+  \defgroup CSI_DCC
+  \brief    Type definitions for the DCC.
+  @{
+ */
+
+/**
+  \brief  Access to the data structure of DCC.
+ */
+typedef struct {
+    uint32_t RESERVED0[13U];
+    __IOM uint32_t HCR;                    /*!< Offset: 0x034 (R/W) */
+    __IM uint32_t EHSR;                    /*!< Offset: 0x03C (R/ ) */
+    uint32_t RESERVED1[6U];
+    union {
+        __IM uint32_t DERJW;               /*!< Offset: 0x058 (R/ )  Data exchange register CPU read*/
+        __OM uint32_t DERJR;               /*!< Offset: 0x058 ( /W)  Data exchange register CPU writer*/
+    };
+
+} DCC_Type;
+
+#define DCC_HCR_JW_Pos                   18U                                            /*!< DCC HCR: jw_int_en Position */
+#define DCC_HCR_JW_Msk                   (1UL << DCC_HCR_JW_Pos)                        /*!< DCC HCR: jw_int_en Mask */
+
+#define DCC_HCR_JR_Pos                   19U                                            /*!< DCC HCR: jr_int_en Position */
+#define DCC_HCR_JR_Msk                   (1UL << DCC_HCR_JR_Pos)                        /*!< DCC HCR: jr_int_en Mask */
+
+#define DCC_EHSR_JW_Pos                  1U                                             /*!< DCC EHSR: jw_vld Position */
+#define DCC_EHSR_JW_Msk                  (1UL << DCC_EHSR_JW_Pos)                       /*!< DCC EHSR: jw_vld Mask */
+
+#define DCC_EHSR_JR_Pos                  2U                                             /*!< DCC EHSR: jr_vld Position */
+#define DCC_EHSR_JR_Msk                  (1UL << DCC_EHSR_JR_Pos)                       /*!< DCC EHSR: jr_vld Mask */
+
+/*@} end of group CSI_DCC */
+
+/**
+  \ingroup    CSI_core_register
+  \defgroup   CSI_core_bitfield     Core register bit field macros
+  \brief      Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+  @{
+ */
+
+/**
+  \brief   Mask and shift a bit field value for use in a register bit range.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of the bit field.
+  \return           Masked and shifted value.
+*/
+#define _VAL2FLD(field, value)    ((value << field ## _Pos) & field ## _Msk)
+
+/**
+  \brief     Mask and shift a register value to extract a bit filed value.
+  \param[in] field  Name of the register bit field.
+  \param[in] value  Value of register.
+  \return           Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value)    ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CSI_core_bitfield */
+
+/**
+  \ingroup    CSI_core_register
+  \defgroup   CSI_core_base     Core Definitions
+  \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of CK804 Hardware */
+#define TCIP_BASE           (0xE000E000UL)                            /*!< Titly Coupled IP Base Address */
+#define CORET_BASE          (TCIP_BASE +  0x0010UL)                   /*!< CORET Base Address */
+#define VIC_BASE            (TCIP_BASE +  0x0100UL)                   /*!< VIC Base Address */
+#define DCC_BASE            (0xE0011000UL)                            /*!< DCC Base Address */
+#define CACHE_BASE          (TCIP_BASE +  0x1000UL)                   /*!< CACHE Base Address */
+
+#define CORET               ((CORET_Type   *)     CORET_BASE  )       /*!< SysTick configuration struct */
+#define VIC                 ((VIC_Type    *)     VIC_BASE   )         /*!< VIC configuration struct */
+#define DCC                 ((DCC_Type     *)     DCC_BASE    )       /*!< DCC configuration struct */
+#define CACHE               ((CACHE_Type   *)     CACHE_BASE  )       /*!< cache configuration struct */
+
+/*@} */
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core VIC Functions
+  - Core CORET Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/**
+  \defgroup CSI_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+/* ##########################   VIC functions  #################################### */
+/**
+  \ingroup  CSI_Core_FunctionInterface
+  \defgroup CSI_Core_VICFunctions VIC Functions
+  \brief    Functions that manage interrupts and exceptions via the VIC.
+  @{
+ */
+
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn)         (  ((((uint32_t)(int32_t)(IRQn))         )      &  0x03UL) * 8UL)
+#define _IR_IDX(IRQn)            (   (((uint32_t)(int32_t)(IRQn))                >>    5UL)      )
+#define _IP_IDX(IRQn)            (   (((uint32_t)(int32_t)(IRQn))                >>    2UL)      )
+
+extern uint32_t __Vectors[];
+extern uint32_t irq_vectors[];
+
+/*Forward declaration*/
+__STATIC_INLINE void csi_icache_invalid (void);
+
+
+/**
+  \brief   Enable External Interrupt
+  \details Enable a device-specific interrupt in the VIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void csi_vic_enable_irq(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    VIC->ISER[_IR_IDX(IRQn)] = (uint32_t)(1UL << ((uint32_t)(int32_t)IRQn % 32));
+#ifdef CONFIG_SYSTEM_SECURE
+    VIC->ISSR[_IR_IDX(IRQn)] = (uint32_t)(1UL << ((uint32_t)(int32_t)IRQn % 32));
+#endif
+}
+
+/**
+  \brief   Disable External Interrupt
+  \details Disable a device-specific interrupt in the VIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void csi_vic_disable_irq(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    VIC->ICER[_IR_IDX(IRQn)] = (uint32_t)(1UL << ((uint32_t)(int32_t)IRQn % 32));
+}
+
+/**
+  \brief   Enable External Secure Interrupt
+  \details Enable a secure device-specific interrupt in the VIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void csi_vic_enable_sirq(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    VIC->ISSR[_IR_IDX(IRQn)] = (uint32_t)(1UL << ((uint32_t)(int32_t)IRQn % 32));
+}
+
+/**
+  \brief   Disable External Secure Interrupt
+  \details Disable a secure device-specific interrupt in the VIC interrupt controller.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void csi_vic_disable_sirq(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    VIC->ICSR[_IR_IDX(IRQn)] = (uint32_t)(1UL << ((uint32_t)(int32_t)IRQn % 32));
+}
+
+/**
+  \brief   Check Interrupt is Enabled or not
+  \details Read the enabled register in the VIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not enabled.
+  \return             1  Interrupt status is enabled.
+ */
+__STATIC_INLINE uint32_t csi_vic_get_enabled_irq(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    return ((uint32_t)(((VIC->ISER[_IR_IDX(IRQn)] & (1UL << (((uint32_t)(int32_t)IRQn % 32) & 0x7FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+/**
+  \brief   Check Interrupt is Pending or not
+  \details Read the pending register in the VIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt status is not pending.
+  \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t csi_vic_get_pending_irq(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    return ((uint32_t)(((VIC->ISPR[_IR_IDX(IRQn)] & (1UL << (((uint32_t)(int32_t)IRQn % 32) & 0x7FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+/**
+  \brief   Set Pending Interrupt
+  \details Set the pending bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void csi_vic_set_pending_irq(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    VIC->ISPR[_IR_IDX(IRQn)] = (uint32_t)(1UL << ((uint32_t)(int32_t)IRQn % 32));
+}
+
+/**
+  \brief   Clear Pending Interrupt
+  \details Clear the pending bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void csi_vic_clear_pending_irq(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    VIC->ICPR[_IR_IDX(IRQn)] = (uint32_t)(1UL << ((uint32_t)(int32_t)IRQn % 32));
+}
+
+/**
+  \brief   Check Interrupt is Wakeup or not
+  \details Read the wake up register in the VIC and returns the pending bit for the specified interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \return             0  Interrupt is not set as wake up interrupt.
+  \return             1  Interrupt is set as wake up interrupt.
+ */
+__STATIC_INLINE uint32_t csi_vic_get_wakeup_irq(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    return ((uint32_t)(((VIC->IWER[_IR_IDX(IRQn)] & (1UL << (((uint32_t)(int32_t)IRQn % 32) & 0x7FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+/**
+  \brief   Set Wake up Interrupt
+  \details Set the wake up bit of an external interrupt.
+  \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void csi_vic_set_wakeup_irq(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    VIC->IWER[_IR_IDX(IRQn)] = (uint32_t)(1UL << ((uint32_t)(int32_t)IRQn % 32));
+}
+
+/**
+  \brief   Clear Wake up Interrupt
+  \details Clear the wake up bit of an external interrupt.
+  \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void csi_vic_clear_wakeup_irq(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    VIC->IWDR[_IR_IDX(IRQn)] = (uint32_t)(1UL << ((uint32_t)(int32_t)IRQn % 32));
+}
+
+/**
+  \brief   Get Interrupt is Active or not
+  \details Read the active register in the VIC and returns the active bit for the device specific interrupt.
+  \param [in]      IRQn  Device specific interrupt number.
+  \return             0  Interrupt status is not active.
+  \return             1  Interrupt status is active.
+  \note    IRQn must not be negative.
+ */
+__STATIC_INLINE uint32_t csi_vic_get_active(int32_t IRQn)
+{
+    IRQn &= 0x7FUL;
+
+    return ((uint32_t)(((VIC->IABR[_IR_IDX(IRQn)] & (1UL << (((uint32_t)(int32_t)IRQn % 32) & 0x7FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+/**
+  \brief   Set Threshold register
+  \details set the threshold register in the VIC.
+  \param [in]      VectThreshold  specific vector threshold.
+  \param [in]      PrioThreshold  specific priority threshold.
+ */
+__STATIC_INLINE void csi_vic_set_threshold(uint32_t VectThreshold, uint32_t PrioThreshold)
+{
+    VectThreshold &= 0x7FUL;
+
+    if (VectThreshold <= 31) {
+        VIC->IPTR = 0x80000000 | (((VectThreshold + 32) & 0xFF) << 8) | ((PrioThreshold & 0x3) << 6);
+    }
+
+    if (VectThreshold > 31 && VectThreshold < 96) {
+        VIC->IPTR = 0x80000000 | (((VectThreshold + 32) & 0xFF) << 8) | ((PrioThreshold & 0x7) << 5);
+    }
+
+    if (VectThreshold > 95) {
+        VIC->IPTR = 0x80000000 | (((VectThreshold + 32) & 0xFF) << 8) | ((PrioThreshold & 0xF) << 4);
+    }
+}
+
+/**
+  \brief   Set Interrupt Priority
+  \details Set the priority of an interrupt.
+  \note    The priority cannot be set for every core interrupt.
+  \param [in]      IRQn  Interrupt number.
+  \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void csi_vic_set_prio(int32_t IRQn, uint32_t priority)
+{
+    VIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(VIC->IPR[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+                                 (((priority << (8U - __VIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+}
+
+/**
+  \brief   Get Interrupt Priority
+  \details Read the priority of an interrupt.
+           The interrupt number can be positive to specify an external (device specific) interrupt,
+           or negative to specify an internal (core) interrupt.
+  \param [in]   IRQn  Interrupt number.
+  \return             Interrupt Priority.
+                      Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t csi_vic_get_prio(int32_t IRQn)
+{
+    return ((uint32_t)(((VIC->IPR[_IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & (uint32_t)0xFFUL) >> (8U - __VIC_PRIO_BITS)));
+}
+
+
+/**
+  \brief   Set interrupt handler
+  \details Set the interrupt handler according to the interrupt num, the handler will be filled in __Vectors[].
+  \param [in]      IRQn  Interrupt number.
+  \param [in]   handler  Interrupt handler.
+ */
+__STATIC_INLINE void csi_vic_set_vector(int32_t IRQn, uint32_t handler)
+{
+    if (IRQn >= 0 && IRQn < 128) {
+    	irq_vectors[32 + IRQn] = handler;
+    }
+
+    csi_icache_invalid();
+}
+
+/**
+  \brief   Get interrupt handler
+  \details Get the address of interrupt handler function.
+  \param [in]      IRQn  Interrupt number.
+ */
+__STATIC_INLINE uint32_t csi_vic_get_vector(int32_t IRQn)
+{
+    if (IRQn >= 0 && IRQn < 128) {
+        return (uint32_t)irq_vectors[32 + IRQn];
+    }
+
+    return 0;
+}
+
+/*@} end of CSI_Core_VICFunctions */
+
+/* ##################################    SysTick function  ############################################ */
+/**
+  \ingroup  CSI_Core_FunctionInterface
+  \defgroup CSI_Core_SysTickFunctions SysTick Functions
+  \brief    Functions that configure the System.
+  @{
+ */
+
+
+/**
+  \brief   CORE timer Configuration
+  \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+           Counter is in free running mode to generate periodic interrupts.
+  \param [in]  ticks  Number of ticks between two interrupts.
+  \param [in]  IRQn   core timer Interrupt number.
+  \return          0  Function succeeded.
+  \return          1  Function failed.
+  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+           must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t csi_coret_config(uint32_t ticks, int32_t IRQn)
+{
+    if ((ticks - 1UL) > CORET_LOAD_RELOAD_Msk) {
+        return (1UL);                                                   /* Reload value impossible */
+    }
+
+    CORET->LOAD = (uint32_t)(ticks - 1UL);                              /* set reload register */
+    CORET->VAL  = 0UL;                                                  /* Load the CORET Counter Value */
+    CORET->CTRL = CORET_CTRL_CLKSOURCE_Msk |
+                   CORET_CTRL_TICKINT_Msk |
+                   CORET_CTRL_ENABLE_Msk;                               /* Enable CORET IRQ and CORET Timer */
+    return (0UL);                                                       /* Function successful */
+}
+
+/**
+  \brief   get CORE timer reload value
+  \return          CORE timer counter value.
+ */
+__STATIC_INLINE uint32_t csi_coret_get_load(void)
+{
+    return CORET->LOAD;
+}
+
+/**
+  \brief   get CORE timer counter value
+  \return          CORE timer counter value.
+ */
+__STATIC_INLINE uint32_t csi_coret_get_value(void)
+{
+    return CORET->VAL;
+}
+
+/*@} end of CSI_Core_SysTickFunctions */
+
+/* ##################################### DCC function ########################################### */
+/**
+  \ingroup  CSI_Core_FunctionInterface
+  \defgroup CSI_core_DebugFunctions HAD Functions
+  \brief    Functions that access the HAD debug interface.
+  @{
+ */
+
+/**
+  \brief   HAD Send Character
+  \details Transmits a character via the HAD channel 0, and
+           \li Just returns when no debugger is connected that has booked the output.
+           \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+  \param [in]     ch  Character to transmit.
+  \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t csi_had_send_char(uint32_t ch)
+{
+    DCC->DERJR = (uint8_t)ch;
+
+    return (ch);
+}
+
+
+/**
+  \brief   HAD Receive Character
+  \details Inputs a character via the external variable \ref HAD_RxBuffer.
+  \return             Received character.
+  \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t csi_had_receive_char(void)
+{
+    int32_t ch = -1;                           /* no character available */
+
+    if (_FLD2VAL(DCC_EHSR_JW, DCC->EHSR)) {
+        ch = DCC->DERJW;
+    }
+
+    return (ch);
+}
+
+
+/**
+  \brief   HAD Check Character
+  \details Check whether a character is pending for reading in the variable \ref HAD_RxBuffer.
+  \return          0  No character available.
+  \return          1  Character available.
+ */
+__STATIC_INLINE int32_t csi_had_check_char(void)
+{
+    return _FLD2VAL(DCC_EHSR_JW, DCC->EHSR);                              /* no character available */
+}
+
+/*@} end of CSI_core_DebugFunctions */
+
+/* ##########################  Cache functions  #################################### */
+/**
+  \ingroup  CSI_Core_FunctionInterface
+  \defgroup CSI_Core_CacheFunctions Cache Functions
+  \brief    Functions that configure Instruction and Data cache.
+  @{
+ */
+
+/**
+  \brief   Enable I-Cache
+  \details Turns on I-Cache
+  */
+__STATIC_INLINE void csi_icache_enable (void)
+{
+#if (__ICACHE_PRESENT == 1U)
+    CACHE->CIR = CACHE_CIR_INV_ALL_Msk;         /* invalidate all Cache */
+    CACHE->CER |=  (uint32_t)(CACHE_CER_EN_Msk | CACHE_CER_CFIG_Msk);  /* enable all Cache */
+#endif
+}
+
+
+/**
+  \brief   Disable I-Cache
+  \details Turns off I-Cache
+  */
+__STATIC_INLINE void csi_icache_disable (void)
+{
+#if (__ICACHE_PRESENT == 1U)
+    CACHE->CER &=  ~(uint32_t)(CACHE_CER_EN_Msk | CACHE_CER_CFIG_Msk);  /* disable all Cache */
+    CACHE->CIR = CACHE_CIR_INV_ALL_Msk;          /* invalidate all Cache */
+#endif
+}
+
+
+/**
+  \brief   Invalidate I-Cache
+  \details Invalidates I-Cache
+  */
+__STATIC_INLINE void csi_icache_invalid (void)
+{
+#if (__ICACHE_PRESENT == 1U)
+    CACHE->CIR = CACHE_CIR_INV_ALL_Msk;         /* invalidate all Cache */
+#endif
+}
+
+
+/**
+  \brief   Enable D-Cache
+  \details Turns on D-Cache
+  \note    I-Cache also turns on.
+  */
+__STATIC_INLINE void csi_dcache_enable (void)
+{
+#if (__DCACHE_PRESENT == 1U)
+    CACHE->CIR = CACHE_CIR_INV_ALL_Msk;         /* invalidate all Cache */
+    CACHE->CER =  (uint32_t)(CACHE_CER_EN_Msk | CACHE_CER_WB_Msk | CACHE_CER_DCW_Msk) & (~CACHE_CER_CFIG_Msk);  /* enable all Cache */
+#endif
+}
+
+
+/**
+  \brief   Disable D-Cache
+  \details Turns off D-Cache
+  \note    I-Cache also turns off.
+  */
+__STATIC_INLINE void csi_dcache_disable (void)
+{
+#if (__DCACHE_PRESENT == 1U)
+    CACHE->CER &=  ~(uint32_t)CACHE_CER_EN_Msk;  /* disable all Cache */
+    CACHE->CIR = CACHE_CIR_INV_ALL_Msk;          /* invalidate all Cache */
+#endif
+}
+
+
+/**
+  \brief   Invalidate D-Cache
+  \details Invalidates D-Cache
+  \note    I-Cache also invalid
+  */
+__STATIC_INLINE void csi_dcache_invalid (void)
+{
+#if (__DCACHE_PRESENT == 1U)
+    CACHE->CIR = CACHE_CIR_INV_ALL_Msk;         /* invalidate all Cache */
+#endif
+}
+
+
+/**
+  \brief   Clean D-Cache
+  \details Cleans D-Cache
+  \note    I-Cache also cleans
+  */
+__STATIC_INLINE void csi_dcache_clean (void)
+{
+#if (__DCACHE_PRESENT == 1U)
+    CACHE->CIR = _VAL2FLD(CACHE_CIR_CLR_ALL, 1);         /* clean all Cache */
+#endif
+}
+
+
+/**
+  \brief   Clean & Invalidate D-Cache
+  \details Cleans and Invalidates D-Cache
+  \note    I-Cache also flush.
+  */
+__STATIC_INLINE void csi_dcache_clean_invalid (void)
+{
+#if (__DCACHE_PRESENT == 1U)
+    CACHE->CIR = _VAL2FLD(CACHE_CIR_INV_ALL, 1) | _VAL2FLD(CACHE_CIR_CLR_ALL, 1);         /* clean and inv all Cache */
+#endif
+}
+
+
+/**
+  \brief   D-Cache Invalidate by address
+  \details Invalidates D-Cache for the given address
+  \param[in]   addr    address (aligned to 16-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void csi_dcache_invalid_range (uint32_t *addr, int32_t dsize)
+{
+#if (__DCACHE_PRESENT == 1U)
+    int32_t op_size = dsize;
+    uint32_t op_addr = (uint32_t)addr & CACHE_CIR_INV_ADDR_Msk;
+    int32_t linesize = 16;
+
+    op_addr |= _VAL2FLD(CACHE_CIR_INV_ONE, 1);
+
+    while (op_size >= 128) {
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+
+        op_size -= 128;
+    }
+
+    while (op_size > 0) {
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        op_size -= linesize;
+    }
+#endif
+}
+
+
+/**
+  \brief   D-Cache Clean by address
+  \details Cleans D-Cache for the given address
+  \param[in]   addr    address (aligned to 16-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void csi_dcache_clean_range (uint32_t *addr, int32_t dsize)
+{
+#if (__DCACHE_PRESENT == 1)
+    int32_t op_size = dsize;
+    uint32_t op_addr = (uint32_t)addr & CACHE_CIR_INV_ADDR_Msk;
+    int32_t linesize = 16;
+
+    op_addr |= _VAL2FLD(CACHE_CIR_CLR_ONE, 1);
+
+    while (op_size >= 128) {
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+
+        op_size -= 128;
+    }
+
+    while (op_size > 0) {
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        op_size -= linesize;
+    }
+#endif
+}
+
+
+/**
+  \brief   D-Cache Clean and Invalidate by address
+  \details Cleans and invalidates D_Cache for the given address
+  \param[in]   addr    address (aligned to 16-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void csi_dcache_clean_invalid_range (uint32_t *addr, int32_t dsize)
+{
+#if (__DCACHE_PRESENT == 1U)
+    int32_t op_size = dsize;
+    uint32_t op_addr = (uint32_t)addr & CACHE_CIR_INV_ADDR_Msk;
+    int32_t linesize = 16;
+
+    op_addr |= _VAL2FLD(CACHE_CIR_CLR_ONE, 1) | _VAL2FLD(CACHE_CIR_INV_ONE, 1);
+
+    while (op_size >= 128) {
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+
+        op_size -= 128;
+    }
+
+    while (op_size > 0) {
+        CACHE->CIR = op_addr;
+        op_addr += linesize;
+        op_size -= linesize;
+    }
+#endif
+}
+
+/**
+  \brief   setup cacheable range Cache
+  \details setup Cache range
+  */
+__STATIC_INLINE void csi_cache_set_range (uint32_t index, uint32_t baseAddr, uint32_t se, uint32_t size, uint32_t enable)
+{
+    CACHE->CRCR[index] =  ((baseAddr & CACHE_CRCR_BASE_ADDR_Msk) |
+           				   (_VAL2FLD(CACHE_CRCR_SE, se)) |
+                           (_VAL2FLD(CACHE_CRCR_SIZE, size)) |
+                           (_VAL2FLD(CACHE_CRCR_EN, enable)));
+}
+
+/**
+  \brief   Enable cache profile
+  \details Turns on Cache profile
+  */
+__STATIC_INLINE void csi_cache_enable_profile (void)
+{
+    CACHE->CPFCR |=  (uint32_t)CACHE_CPFCR_PFEN_Msk;
+}
+
+/**
+  \brief   Disable cache profile
+  \details Turns off Cache profile
+  */
+__STATIC_INLINE void csi_cache_disable_profile (void)
+{
+    CACHE->CPFCR &=  ~(uint32_t)CACHE_CPFCR_PFEN_Msk;
+}
+
+/**
+  \brief   Reset cache profile
+  \details Reset Cache profile
+  */
+__STATIC_INLINE void csi_cache_reset_profile (void)
+{
+    CACHE->CPFCR |=  (uint32_t)CACHE_CPFCR_PFRST_Msk;
+}
+
+/**
+  \brief   cache access times
+  \details Cache access times
+  \note    every 256 access add 1.
+  \return          cache access times, actual times should be multiplied by 256
+  */
+__STATIC_INLINE uint32_t csi_cache_get_access_time (void)
+{
+    return CACHE->CPFATR;
+}
+
+/**
+  \brief   cache miss times
+  \details Cache miss times
+  \note    every 256 miss add 1.
+  \return          cache miss times, actual times should be multiplied by 256
+  */
+__STATIC_INLINE uint32_t csi_cache_get_miss_time (void)
+{
+    return CACHE->CPFMTR;
+}
+
+/*@} end of CSI_Core_CacheFunctions */
+
+/* ##########################  MPU functions  #################################### */
+/**
+  \ingroup  CSI_Core_FunctionInterface
+  \defgroup CSI_Core_MPUFunctions MPU Functions
+  \brief    Functions that configure MPU.
+  @{
+ */
+
+typedef enum {
+    REGION_SIZE_4KB      = 0xB,
+    REGION_SIZE_8KB      = 0xC,
+    REGION_SIZE_16KB     = 0xD,
+    REGION_SIZE_32KB     = 0xE,
+    REGION_SIZE_64KB     = 0xF,
+    REGION_SIZE_128KB    = 0x10,
+    REGION_SIZE_256KB    = 0x11,
+    REGION_SIZE_512KB    = 0x12,
+    REGION_SIZE_1MB      = 0x13,
+    REGION_SIZE_2MB      = 0x14,
+    REGION_SIZE_4MB      = 0x15,
+    REGION_SIZE_8MB      = 0x16,
+    REGION_SIZE_16MB     = 0x17,
+    REGION_SIZE_32MB     = 0x18,
+    REGION_SIZE_64MB     = 0x19,
+    REGION_SIZE_128MB    = 0x1A,
+    REGION_SIZE_256MB    = 0x1B,
+    REGION_SIZE_512MB    = 0x1C,
+    REGION_SIZE_1GB      = 0x1D,
+    REGION_SIZE_2GB      = 0x1E,
+    REGION_SIZE_4GB      = 0x1F
+} region_size_e;
+
+typedef enum {
+    AP_BOTH_INACCESSIBLE = 0,
+    AP_SUPER_RW_USER_INACCESSIBLE,
+    AP_SUPER_RW_USER_RDONLY,
+    AP_BOTH_RW
+} access_permission_e;
+
+typedef struct {
+    uint32_t nx: 1;               /* instruction fetched excution */
+    access_permission_e ap: 2;    /* super user and normal user access.*/
+    uint32_t s: 1;                /* security */
+} mpu_region_attr_t;
+
+/**
+  \brief  enable mpu.
+  \details
+  */
+__STATIC_INLINE void csi_mpu_enable(void)
+{
+    __set_CCR(__get_CCR() | CCR_MP_Msk);
+}
+
+/**
+  \brief  disable mpu.
+  \details
+  */
+__STATIC_INLINE void csi_mpu_disable(void)
+{
+    __set_CCR(__get_CCR() & (~CCR_MP_Msk));
+}
+
+/**
+  \brief  configure memory protected region.
+  \details
+  \param [in]  idx        memory protected region (0, 1, 2, ..., 7).
+  \param [in]  base_addr  base address must be aligned with page size.
+  \param [in]  size       \ref region_size_e. memory protected region size.
+  \param [in]  attr       \ref region_size_t. memory protected region attribute.
+  \param [in]  enable     enable or disable memory protected region.
+  */
+__STATIC_INLINE void csi_mpu_config_region(uint32_t idx, uint32_t base_addr, region_size_e size,
+                                           mpu_region_attr_t attr, uint32_t enable)
+{
+    if (idx > 7) {
+        return;
+    }
+
+    CAPR_Type capr;
+    PACR_Type pacr;
+    PRSR_Type prsr;
+
+    capr.w = __get_CAPR();
+    pacr.w = __get_PACR();
+    prsr.w = __get_PRSR();
+
+    pacr.b.base_addr = (base_addr >> PACR_BASE_ADDR_Pos) & (0xFFFFF);
+
+    prsr.b.RID = idx;
+    __set_PRSR(prsr.w);
+
+    if (size != REGION_SIZE_4KB) {
+        pacr.w &= ~(((1u << (size -11)) - 1) << 12);
+    }
+
+    pacr.b.size = size;
+
+    capr.w &= ~((0x1 << idx) | (0x3 << (idx * 2 + 8)) | (0x1 << (idx + 24)));
+    capr.w = (capr.w | (attr.nx << idx) | (attr.ap << (idx * 2 + 8)) | (attr.s << (idx + 24)));
+    __set_CAPR(capr.w);
+
+    pacr.b.E = enable;
+    __set_PACR(pacr.w);
+}
+
+/**
+  \brief  enable mpu region by idx.
+  \details
+  \param [in]  idx        memory protected region (0, 1, 2, ..., 7).
+  */
+__STATIC_INLINE void csi_mpu_enable_region(uint32_t idx)
+{
+    if (idx > 7) {
+        return;
+    }
+
+    __set_PRSR((__get_PRSR() & (~PRSR_RID_Msk)) | (idx << PRSR_RID_Pos));
+    __set_PACR(__get_PACR() | PACR_E_Msk);
+}
+
+/**
+  \brief  disable mpu region by idx.
+  \details
+  \param [in]  idx        memory protected region (0, 1, 2, ..., 7).
+  */
+__STATIC_INLINE void csi_mpu_disable_region(uint32_t idx)
+{
+    if (idx > 7) {
+        return;
+    }
+
+    __set_PRSR((__get_PRSR() & (~PRSR_RID_Msk)) | (idx << PRSR_RID_Pos));
+    __set_PACR(__get_PACR() & (~PACR_E_Msk));
+}
+
+/*@} end of CSI_Core_MMUFunctions */
+
+
+/* ##################################    IRQ Functions  ############################################ */
+
+/**
+  \brief   Save the Irq context
+  \details save the psr result before disable irq.
+  \param [in]      irq_num  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE uint32_t csi_irq_save(void)
+{
+    uint32_t result;
+    result = __get_PSR();
+    __disable_irq();
+    return(result);
+}
+
+/**
+  \brief   Restore the Irq context
+  \details restore saved primask state.
+  \param [in]      irq_state  psr irq state.
+ */
+__STATIC_INLINE void csi_irq_restore(uint32_t irq_state)
+{
+    __set_PSR(irq_state);
+}
+
+/*@} end of IRQ Functions */
+
+/**
+  \brief   System Reset
+  \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void csi_system_reset(void)
+{
+    CHR_Type chr;
+
+    chr.w = __get_CHR();
+#ifdef __RESET_CONST
+    chr.b.SRST_VAL = __RESET_CONST;
+#else
+    chr.b.SRST_VAL = 0xABCD;
+#endif
+
+    __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                         buffered write are completed before reset */
+    __set_CHR(chr.w);
+
+    __DSB();                                                          /* Ensure completion of memory access */
+
+    for(;;)                                                           /* wait until reset */
+    {
+        __NOP();
+    }
+}
+
+/* ##################################    Old Interfaces  ############################################ */
+
+/* These interfaces are deprecated */
+#define NVIC_EnableIRQ(IRQn)                               csi_vic_enable_irq(IRQn)
+#define NVIC_DisableIRQ(IRQn)                              csi_vic_disable_irq(IRQn)
+#define NVIC_GetPendingIRQ(IRQn)                           csi_vic_get_pending_irq(IRQn)
+#define NVIC_SetPendingIRQ(IRQn)                           csi_vic_set_pending_irq(IRQn)
+#define NVIC_ClearPendingIRQ(IRQn)                         csi_vic_clear_pending_irq(IRQn)
+#define NVIC_GetWakeupIRQ(IRQn)                            csi_vic_get_wakeup_irq(IRQn)
+#define NVIC_SetWakeupIRQ(IRQn)                            csi_vic_set_wakeup_irq(IRQn)
+#define NVIC_ClearWakeupIRQ(IRQn)                          csi_vic_clear_wakeup_irq(IRQn)
+#define NVIC_GetActive(IRQn)                               csi_vic_get_active(IRQn)
+#define NVIC_SetThreshold(VectThreshold, PrioThreshold)    csi_vic_set_threshold(VectThreshold, PrioThreshold)
+#define NVIC_SetPriority(IRQn, priority)                   csi_vic_set_prio(IRQn, priority)
+#define NVIC_GetPriority(IRQn)                             csi_vic_get_prio(IRQn)
+#define NVIC_SystemReset()                                 csi_system_reset()
+
+#define SysTick_Config(ticks)                              csi_coret_config(ticks, SYS_TICK_IRQn)
+#define CORET_Config(ticks)                                csi_coret_config(ticks, SYS_TICK_IRQn)
+
+#define SCB_EnableICache()                                 csi_icache_enable()
+#define SCB_DisableICache()                                csi_icache_disable()
+#define SCB_InvalidateICache()                             csi_icache_invalid()
+#define SCB_EnableDCache()                                 csi_dcache_enable()
+#define SCB_DisableDCache()                                csi_dcache_disable()
+#define SCB_InvalidateDCache()                             csi_dcache_invalid()
+#define SCB_CleanDCache()                                  csi_dcache_clean()
+#define SCB_CleanInvalidateDCache()                        csi_dcache_clean_invalid()
+#define SCB_InvalidateDCache_by_Addr(addr, dsize)          csi_dcache_invalid_range(addr, dsize)
+#define SCB_CleanDCache_by_Addr(addr, dsize)               csi_dcache_clean_range(addr, dsize)
+#define SCB_CleanInvalidateDCache_by_Addr(addr, dsize)     csi_dcache_clean_invalid_range(addr, dsize)
+#define SCB_Cacheable_Range(index, baseAddr, size, enable) csi_cache_set_range(index, baseAddr, size, enable)
+#define SCB_EnableCacheProfile()                           csi_cache_enable_profile()
+#define SCB_DisableCacheProfile()                          csi_cache_disable_profile()
+#define SCB_ResetCacheProfile()                            csi_cache_reset_profile()
+#define SCB_CacheAccessTime()                              csi_cache_get_access_time()
+#define SCB_CacheMissTime()                                csi_cache_get_miss_time()
+#define SCB_EnableCache()                                  csi_icache_enable();csi_dcache_enable()
+#define SCB_DisableCache()                                 csi_icache_disable();csi_dcache_disable()
+#define SCB_InvalidateCache()                              csi_icache_invalid();csi_dcache_invalid()
+#define SCB_CleanCache()                                   csi_dcache_clean()
+#define SCB_CleanInvalidateCache()                         csi_icache_invalid();csi_dcache_clean();csi_dcache_invalid()
+#define SCB_InvalidateCache_by_Addr(addr, dsize)           csi_dcache_invalid_range(addr, dsize);csi_icache_invalid()
+#define SCB_CleanCache_by_Addr(addr, dsize)                csi_dcache_clean_range(addr, dsize)
+#define SCB_CleanInvalidateCache_by_Addr(addr, dsize)      csi_dcache_clean_invalid_range(addr, dsize)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_804_H_DEPENDANT */
+
+#endif /* __CSI_GENERIC */

+ 63 - 0
include/arch/xt804/csi_core/csi_core.h

@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/******************************************************************************
+ * @file     csi_core.h
+ * @brief    CSI Core Layer Header File
+ * @version  V1.0
+ * @date     02. June 2017
+ ******************************************************************************/
+
+#ifndef _CORE_H_
+#define _CORE_H_
+
+#include <stdint.h>
+
+#if defined(__CK801__) || defined(__E801__)
+#include <core_801.h>
+#elif defined(__CK802__) || defined(__E802__) || defined(__S802__)
+#include <core_802.h>
+#elif defined(__E803__) || defined(__S803__)
+#include <core_803.h>
+#elif defined(__CK803__) || defined(__CK804__) || defined(__E804__) || defined(__E804D__) || defined(__E804F__) || defined (__E804DF__)
+#include <core_804.h>
+#elif defined(__CK805__) || defined(__I805__) || defined(__I805F__)
+#include <core_805.h>
+#elif defined(__CK610__)
+#include <core_ck610.h>
+#elif defined(__CK810__) || defined(__C810__) || defined(__C810V__)
+#include <core_810.h>
+#elif defined(__CK807__) || defined(__C807__) || defined(__C807F__) || defined(__C807FV__)
+#include <core_807.h>
+#elif defined(__riscv)
+#include <core_rv32.h>
+#endif
+
+#ifdef __riscv
+#include <csi_rv32_gcc.h>
+#else
+#include <csi_gcc.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CORE_H_ */

+ 2902 - 0
include/arch/xt804/csi_core/csi_gcc.h

@@ -0,0 +1,2902 @@
+/*
+ * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/******************************************************************************
+ * @file     csi_gcc.h
+ * @brief    CSI Header File for GCC.
+ * @version  V1.0
+ * @date     02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_GCC_H_
+#define _CSI_GCC_H_
+
+#include <stdlib.h>
+
+#ifndef __ASM
+#define __ASM            __asm                                      /*!< asm keyword for GNU Compiler */
+#endif
+
+#ifndef __INLINE
+#define __INLINE         inline                                     /*!< inline keyword for GNU Compiler */
+#endif
+
+#ifndef __ALWAYS_STATIC_INLINE
+#define __ALWAYS_STATIC_INLINE  __attribute__((always_inline)) static inline
+#endif
+
+#ifndef __STATIC_INLINE
+#define __STATIC_INLINE     static inline
+#endif
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CSI_Core_FunctionInterface
+    \defgroup CSI_Core_RegAccFunctions CSI Core Register Access Functions
+  @{
+ */
+/**
+  \brief   Enable IRQ Interrupts
+  \details Enables IRQ interrupts by setting the IE-bit in the PSR.
+           Can only be executed in Privileged modes.
+ */
+__ALWAYS_STATIC_INLINE void __enable_irq(void)
+{
+    __ASM volatile("psrset ie");
+}
+
+/**
+  \brief   Disable IRQ Interrupts
+  \details Disables IRQ interrupts by clearing the IE-bit in the PSR.
+  Can only be executed in Privileged modes.
+ */
+__ALWAYS_STATIC_INLINE void __disable_irq(void)
+{
+    __ASM volatile("psrclr ie");
+}
+
+/**
+  \brief   Get PSR
+  \details Returns the content of the PSR Register.
+  \return               PSR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_PSR(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mfcr %0, psr" : "=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Set PSR
+  \details Writes the given value to the PSR Register.
+  \param [in]    psr  PSR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_PSR(uint32_t psr)
+{
+    __ASM volatile("mtcr %0, psr" : : "r"(psr));
+}
+
+/**
+  \brief   Get SP
+  \details Returns the content of the SP Register.
+  \return               SP Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_SP(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mov %0, sp" : "=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Set SP
+  \details Writes the given value to the SP Register.
+  \param [in]    sp  SP Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_SP(uint32_t sp)
+{
+    __ASM volatile("mov sp, %0" : : "r"(sp): "sp");
+}
+
+/**
+  \brief   Get Int SP
+  \details Returns the content of the Int SP Register.
+  \return               Int SP Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_Int_SP(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mfcr %0, cr<15, 1>" : "=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Set Int SP
+  \details Writes the given value to the Int SP Register.
+  \param [in]    sp  Int SP Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_Int_SP(uint32_t sp)
+{
+    __ASM volatile("mtcr %0, cr<15, 1>" : : "r"(sp));
+}
+
+/**
+  \brief   Get VBR Register
+  \details Returns the content of the VBR Register.
+  \return               VBR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_VBR(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mfcr %0, vbr" : "=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Set VBR
+  \details Writes the given value to the VBR Register.
+  \param [in]    vbr  VBR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_VBR(uint32_t vbr)
+{
+    __ASM volatile("mtcr %0, vbr" : : "r"(vbr));
+}
+
+/**
+  \brief   Get EPC Register
+  \details Returns the content of the EPC Register.
+  \return               EPC Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_EPC(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mfcr %0, epc" : "=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Set EPC
+  \details Writes the given value to the EPC Register.
+  \param [in]    epc  EPC Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_EPC(uint32_t epc)
+{
+    __ASM volatile("mtcr %0, epc" : : "r"(epc));
+}
+
+/**
+  \brief   Get EPSR
+  \details Returns the content of the EPSR Register.
+  \return               EPSR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_EPSR(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mfcr %0, epsr" : "=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Set EPSR
+  \details Writes the given value to the EPSR Register.
+  \param [in]    epsr  EPSR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_EPSR(uint32_t epsr)
+{
+    __ASM volatile("mtcr %0, epsr" : : "r"(epsr));
+}
+
+/**
+  \brief   Get CPUID Register
+  \details Returns the content of the CPUID Register.
+  \return               CPUID Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_CPUID(void)
+{
+    uint32_t result;
+
+#ifdef __CK610
+    __ASM volatile("mfcr %0, cr13" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<13, 0>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Get CCR
+  \details Returns the current value of the CCR.
+  \return               CCR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_CCR(void)
+{
+    register uint32_t result;
+
+#ifdef __CK610
+    __ASM volatile("mfcr %0, cr18\n"  : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<18, 0>\n"  : "=r"(result));
+#endif
+    return (result);
+}
+
+
+/**
+  \brief   Set CCR
+  \details Assigns the given value to the CCR.
+  \param [in]    ccr  CCR value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_CCR(uint32_t ccr)
+{
+#ifdef __CK610
+    __ASM volatile("mtcr %0, cr18\n" : : "r"(ccr));
+#else
+    __ASM volatile("mtcr %0, cr<18, 0>\n" : : "r"(ccr));
+#endif
+}
+
+
+/**
+  \brief   Get DCSR
+  \details Returns the content of the DCSR Register.
+  \return               DCSR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_DCSR(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("mfcr %0, cr14" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<14, 0>" : "=r"(result));
+#endif
+    return (result);
+}
+
+
+/**
+  \brief   Set DCSR
+  \details Writes the given value to the DCSR Register.
+  \param [in]    dcsr  DCSR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_DCSR(uint32_t dcsr)
+{
+#ifdef __CK610
+    __ASM volatile("mtcr %0, cr14" : : "r"(dcsr));
+#else
+    __ASM volatile("mtcr %0, cr<14, 0>" : : "r"(dcsr));
+#endif
+}
+
+
+/**
+  \brief   Get CFR
+  \details Returns the content of the CFR Register.
+  \return               CFR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_CFR(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("mfcr %0, cr17" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<17, 0>" : "=r"(result));
+#endif
+
+    return (result);
+}
+
+
+/**
+  \brief   Set CFR
+  \details Writes the given value to the CFR Register.
+  \param [in]    cfr  CFR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_CFR(uint32_t cfr)
+{
+#ifdef __CK610
+    __ASM volatile("mtcr %0, cr17" : : "r"(cfr));
+#else
+    __ASM volatile("mtcr %0, cr<17, 0>" : : "r"(cfr));
+#endif
+}
+
+
+/**
+  \brief   Get CIR
+  \details Returns the content of the CIR Register.
+  \return               CIR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_CIR(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("mfcr %0, cr22" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<22, 0>" : "=r"(result));
+#endif
+    return (result);
+}
+
+
+/**
+  \brief   Set CIR
+  \details Writes the given value to the CIR Register.
+  \param [in]    cir  CIR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_CIR(uint32_t cir)
+{
+#ifdef __CK610
+    __ASM volatile("mtcr %0, cr22" : : "r"(cir));
+#else
+    __ASM volatile("mtcr %0, cr<22, 0>" : : "r"(cir));
+#endif
+}
+
+
+/**
+  \brief   Get CAPR
+  \details Returns the current value of the CAPR.
+  \return               CAPR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_CAPR(void)
+{
+    register uint32_t result;
+
+#ifdef __CK610
+    __ASM volatile("mfcr %0, cr19\n" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<19, 0>\n" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set CAPR
+  \details Assigns the given value to the CAPR.
+  \param [in]    capr  CAPR value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_CAPR(uint32_t capr)
+{
+#ifdef __CK610
+    __ASM volatile("mtcr %0, cr19\n" : : "r"(capr));
+#else
+    __ASM volatile("mtcr %0, cr<19, 0>\n" : : "r"(capr));
+#endif
+}
+
+
+/**
+  \brief   Set PACR
+  \details Assigns the given value to the PACR.
+
+    \param [in]    pacr  PACR value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_PACR(uint32_t pacr)
+{
+#ifdef __CK610
+    __ASM volatile("mtcr %0, cr20\n" : : "r"(pacr));
+#else
+    __ASM volatile("mtcr %0, cr<20, 0>\n" : : "r"(pacr));
+#endif
+}
+
+
+/**
+  \brief   Get PACR
+  \details Returns the current value of PACR.
+  \return               PACR value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_PACR(void)
+{
+    uint32_t result;
+
+#ifdef __CK610
+    __ASM volatile("mfcr %0, cr20" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<20, 0>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set PRSR
+  \details Assigns the given value to the PRSR.
+
+    \param [in]    prsr  PRSR value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_PRSR(uint32_t prsr)
+{
+#ifdef __CK610
+    __ASM volatile("mtcr %0, cr21\n" : : "r"(prsr));
+#else
+    __ASM volatile("mtcr %0, cr<21, 0>\n" : : "r"(prsr));
+#endif
+}
+
+/**
+  \brief   Get PRSR
+  \details Returns the current value of PRSR.
+  \return               PRSR value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_PRSR(void)
+{
+    uint32_t result;
+
+#ifdef __CK610
+    __ASM volatile("mfcr %0, cr21" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<21, 0>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Get user sp
+  \details Returns the current value of user r14.
+  \return               UR14 value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_UR14(void)
+{
+    uint32_t result;
+
+#ifdef __CK610
+    __ASM volatile("mov %0, sp" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<14, 1>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Get CHR Register
+  \details Returns the content of the CHR Register.
+  \return               CHR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_CHR(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mfcr %0, cr<31, 0>\n" :"=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Set CHR
+  \details Assigns the given value to the CHR.
+  \param [in]    chr  CHR value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_CHR(uint32_t chr)
+{
+    __ASM volatile("mtcr %0, cr<31, 0>\n" : : "r"(chr));
+}
+
+/**
+  \brief   Get HINT
+  \details Returns the content of the HINT Register.
+  \return               HINT Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_HINT(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("mfcr %0, cr<30, 0>" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<31, 0>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set HINT
+  \details Writes the given value to the HINT Register.
+  \param [in]    hint  HINT Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_HINT(uint32_t hint)
+{
+#ifdef __CK610
+    __ASM volatile("mtcr %0, cr<30, 0>" : "=r"(hint));
+#else
+    __ASM volatile("mtcr %0, cr<31, 0>" : : "r"(hint));
+#endif
+}
+
+/**
+  \brief   Get MIR
+  \details Returns the content of the MIR Register.
+  \return               MIR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_MIR(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cprcr %0, cpcr0" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<0, 15>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set MIR
+  \details Writes the given value to the MIR Register.
+  \param [in]    mir  MIR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_MIR(uint32_t mir)
+{
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cpwcr %0, cpcr0" : : "r"(mir));
+#else
+    __ASM volatile("mtcr %0, cr<0, 15>" : : "r"(mir));
+#endif
+}
+
+
+/**
+  \brief   Get MEL0
+  \details Returns the content of the MEL0 Register.
+  \return               MEL0 Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_MEL0(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cprcr %0, cpcr2" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<2, 15>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set MEL0
+  \details Writes the given value to the MEL0 Register.
+  \param [in]    mel0  MEL0 Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_MEL0(uint32_t mel0)
+{
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cpwcr %0, cpcr2" : : "r"(mel0));
+#else
+    __ASM volatile("mtcr %0, cr<2, 15>" : : "r"(mel0));
+#endif
+}
+
+
+/**
+  \brief   Get MEL1
+  \details Returns the content of the MEL1 Register.
+  \return               MEL1 Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_MEL1(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cprcr %0, cpcr3" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<3, 15>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set MEL1
+  \details Writes the given value to the MEL1 Register.
+  \param [in]    mel1  MEL1 Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_MEL1(uint32_t mel1)
+{
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cpwcr %0, cpcr3" : : "r"(mel1));
+#else
+    __ASM volatile("mtcr %0, cr<3, 15>" : : "r"(mel1));
+#endif
+}
+
+
+/**
+  \brief   Get MEH
+  \details Returns the content of the MEH Register.
+  \return               MEH Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_MEH(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cprcr %0, cpcr4" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<4, 15>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set MEH
+  \details Writes the given value to the MEH Register.
+  \param [in]    meh  MEH Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_MEH(uint32_t meh)
+{
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cpwcr %0, cpcr4" : : "b"(meh));
+#else
+    __ASM volatile("mtcr %0, cr<4, 15>" : : "r"(meh));
+#endif
+}
+
+
+/**
+  \brief   Get MPR
+  \details Returns the content of the MPR Register.
+  \return               MPR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_MPR(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cprcr %0, cpcr6" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<6, 15>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set MPR
+  \details Writes the given value to the MPR Register.
+  \param [in]    mpr  MPR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_MPR(uint32_t mpr)
+{
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cpwcr %0, cpcr6" : : "r"(mpr));
+#else
+    __ASM volatile("mtcr %0, cr<6, 15>" : : "r"(mpr));
+#endif
+}
+
+
+/**
+  \brief   Get MCIR
+  \details Returns the content of the MCIR Register.
+  \return               MCIR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_MCIR(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cprcr %0, cpcr8" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<8, 15>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set MCIR
+  \details Writes the given value to the MCIR Register.
+  \param [in]    mcir  MCIR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_MCIR(uint32_t mcir)
+{
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cpwcr %0, cpcr8" : : "r"(mcir));
+#else
+    __ASM volatile("mtcr %0, cr<8, 15>" : : "r"(mcir));
+#endif
+}
+
+
+/**
+  \brief   Get MPGD
+  \details Returns the content of the MPGD Register.
+  \return               MPGD Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_MPGD(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cprcr %0, cpcr29" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<29, 15>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set MPGD
+  \details Writes the given value to the MPGD Register.
+  \param [in]    mpgd  MPGD Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_MPGD(uint32_t mpgd)
+{
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cpwcr %0, cpcr29" : : "r"(mpgd));
+#else
+    __ASM volatile("mtcr %0, cr<29, 15>" : : "r"(mpgd));
+#endif
+}
+
+
+/**
+  \brief   Get MSA0
+  \details Returns the content of the MSA0 Register.
+  \return               MSA0 Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_MSA0(void)
+{
+    uint32_t result;
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cprcr %0, cpcr30" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<30, 15>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set MSA0
+  \details Writes the given value to the MSA0 Register.
+  \param [in]    msa0  MSA0 Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_MSA0(uint32_t msa0)
+{
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cpwcr %0, cpcr30" : : "r"(msa0));
+#else
+    __ASM volatile("mtcr %0, cr<30, 15>" : : "r"(msa0));
+#endif
+}
+
+
+/**
+  \brief   Get MSA1
+  \details Returns the content of the MSA1 Register.
+  \return               MSA1 Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_MSA1(void)
+{
+    uint32_t result;
+
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cprcr %0, cpcr31" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<31, 15>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set MSA1
+  \details Writes the given value to the MSA1 Register.
+  \param [in]    msa1  MSA1 Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_MSA1(uint32_t msa1)
+{
+#ifdef __CK610
+    __ASM volatile("cpseti 15");
+    __ASM volatile("cpwcr %0, cpcr31" : : "r"(msa1));
+#else
+    __ASM volatile("mtcr %0, cr<31, 15>" : : "r"(msa1));
+#endif
+}
+
+
+/**
+  \brief   Enable interrupts and exceptions
+  \details Enables interrupts and exceptions by setting the IE-bit and EE-bit in the PSR.
+           Can only be executed in Privileged modes.
+ */
+__ALWAYS_STATIC_INLINE void __enable_excp_irq(void)
+{
+    __ASM volatile("psrset ee, ie");
+}
+
+
+/**
+  \brief   Disable interrupts and exceptions
+  \details Disables interrupts and exceptions by clearing the IE-bit and EE-bit in the PSR.
+           Can only be executed in Privileged modes.
+ */
+__ALWAYS_STATIC_INLINE void __disable_excp_irq(void)
+{
+    __ASM volatile("psrclr ee, ie");
+}
+
+/**
+  \brief   Get GSR
+  \details Returns the content of the GSR Register.
+  \return               GSR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_GSR(void)
+{
+    uint32_t result;
+
+#ifdef __CK610
+    __ASM volatile("mfcr %0, cr12" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<12, 0>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Get GCR
+  \details Returns the content of the GCR Register.
+  \return               GCR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_GCR(void)
+{
+    uint32_t result;
+
+#ifdef __CK610
+    __ASM volatile("mfcr %0, cr11" : "=r"(result));
+#else
+    __ASM volatile("mfcr %0, cr<11, 0>" : "=r"(result));
+#endif
+    return (result);
+}
+
+/**
+  \brief   Set GCR
+  \details Writes the given value to the GCR Register.
+  \param [in]    gcr  GCR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_GCR(uint32_t gcr)
+{
+#ifdef __CK610
+    __ASM volatile("mtcr %0, cr11" : : "r"(gcr));
+#else
+    __ASM volatile("mtcr %0, cr<11, 0>" : : "r"(gcr));
+#endif
+}
+
+/**
+  \brief   Get WSSR
+  \details Returns the content of the WSSR Register, must be accessed in TEE
+  \return               WSSR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_WSSR(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mfcr %0, cr<0, 3>" : "=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Get WRCR
+  \details Returns the content of the WRCR Register, must be accessed in TEE
+  \return               WRCR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_WRCR(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mfcr %0, cr<1, 3>" : "=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Set WRCR
+  \details Writes the given value to the WRCR Register, must be accessed in TEE
+  \param [in]    wrcr  WRCR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_WRCR(uint32_t wrcr)
+{
+    __ASM volatile("mtcr %0, cr<1, 3>" : : "r"(wrcr));
+}
+
+/**
+  \brief   Get DCR
+  \details Returns the content of the DCR Register, must be accessed in TEE
+  \return               DCR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_DCR(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mfcr %0, cr<8, 3>" : "=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Set DCR
+  \details Writes the given value to the DCR Register, must be accessed in TEE
+  \param [in]    dcr  DCR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_DCR(uint32_t dcr)
+{
+    __ASM volatile("mtcr %0, cr<8, 3>" : : "r"(dcr));
+}
+
+/**
+  \brief   Get PCR
+  \details Returns the content of the PCR Register, must be accessed in TEE
+  \return               PCR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_PCR(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mfcr %0, cr<9, 3>" : "=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Set PCR
+  \details Writes the given value to the PCR Register, must be accessed in TEE
+  \param [in]    pcr  PCR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_PCR(uint32_t pcr)
+{
+    __ASM volatile("mtcr %0, cr<9, 3>" : : "r"(pcr));
+}
+
+/**
+  \brief   Get EBR
+  \details Returns the content of the EBR Register.
+  \return               EBR Register value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_EBR(void)
+{
+    uint32_t result;
+
+    __ASM volatile("mfcr %0, cr<1, 1>" : "=r"(result));
+    return (result);
+}
+
+/**
+  \brief   Set EBR
+  \details Writes the given value to the EBR Register.
+  \param [in]    ebr  EBR Register value to set
+ */
+__ALWAYS_STATIC_INLINE void __set_EBR(uint32_t ebr)
+{
+    __ASM volatile("mtcr %0, cr<1, 1>" : : "r"(ebr));
+}
+
+/*@} end of CSI_Core_RegAccFunctions */
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CSI_Core_InstructionInterface CSI Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+#define __CSI_GCC_OUT_REG(r) "=r" (r)
+#define __CSI_GCC_USE_REG(r) "r" (r)
+
+/**
+  \brief   No Operation
+  \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__ALWAYS_STATIC_INLINE void __NOP(void)
+{
+    __ASM volatile("nop");
+}
+
+
+/**
+  \brief   Wait For Interrupt
+  \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+__ALWAYS_STATIC_INLINE void __WFI(void)
+{
+    __ASM volatile("wait");
+}
+
+/**
+  \brief   Wait For Interrupt
+  \details Wait For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
+ */
+__ALWAYS_STATIC_INLINE void __WAIT(void)
+{
+    __ASM volatile("wait");
+}
+
+/**
+  \brief   Doze For Interrupt
+  \details Doze For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
+ */
+__ALWAYS_STATIC_INLINE void __DOZE(void)
+{
+    __ASM volatile("doze");
+}
+
+/**
+  \brief   Stop For Interrupt
+  \details Stop For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
+ */
+__ALWAYS_STATIC_INLINE void __STOP(void)
+{
+    __ASM volatile("stop");
+}
+
+/**
+  \brief   Instruction Synchronization Barrier
+  \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+           so that all instructions following the ISB are fetched from cache or memory,
+           after the instruction has been completed.
+ */
+__ALWAYS_STATIC_INLINE void __ISB(void)
+{
+    __ASM volatile("sync"::: "memory");
+}
+
+
+/**
+  \brief   Data Synchronization Barrier
+  \details Acts as a special kind of Data Memory Barrier.
+           It completes when all explicit memory accesses before this instruction complete.
+ */
+__ALWAYS_STATIC_INLINE void __DSB(void)
+{
+    __ASM volatile("sync"::: "memory");
+}
+
+
+/**
+  \brief   Data Memory Barrier
+  \details Ensures the apparent order of the explicit memory operations before
+           and after the instruction, without ensuring their completion.
+ */
+__ALWAYS_STATIC_INLINE void __DMB(void)
+{
+    __ASM volatile("sync"::: "memory");
+}
+
+/**
+  \brief   Search from the highest bit that the very first bit which's value is 1.
+  \param [in]    value  Value to  bit search.
+  \return               if the highest bit' value is 1,  return 0, and if lowest bit's value is 1, return 31, otherwise return 32.
+ */
+#if !defined(__CK610) || !(__CK80X == 1)
+__ALWAYS_STATIC_INLINE uint32_t __FF0(uint32_t value)
+{
+    uint32_t ret;
+
+    __ASM volatile("ff0 %0, %1" : "=r"(ret) : "r"(value));
+    return ret;
+}
+#endif
+
+/**
+  \brief   Search from the highest bit that the very first bit which's value is 0.
+  \param [in]    value  Value to  bit search.
+  \return               if the highest bit' value is 0,  return 0, and if lowest bit's value is 0, return 31, otherwise return 32.
+ */
+#if !(__CK80X == 1)
+__ALWAYS_STATIC_INLINE uint32_t __FF1(uint32_t value)
+{
+    uint32_t ret;
+#if !defined (__CK610)
+    __ASM volatile("ff1 %0, %1" : "=r"(ret) : "r"(value));
+#else
+    ret = value;
+    __ASM volatile("ff1 %0" : "=r"(ret):);
+#endif
+    return ret;
+}
+#endif
+
+/**
+  \brief   Reverse byte order (32 bit)
+  \details Reverses the byte order in integer value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __REV(uint32_t value)
+{
+    return __builtin_bswap32(value);
+}
+
+
+/**
+  \brief   Reverse byte order (16 bit)
+  \details Reverses the byte order in two unsigned short values.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+    uint32_t result;
+#if (__CK80X >= 2)
+    __ASM volatile("revh %0, %1" : __CSI_GCC_OUT_REG(result) : __CSI_GCC_USE_REG(value));
+#else
+    result = ((value & 0xFF000000) >> 8) | ((value & 0x00FF0000) << 8) |
+             ((value & 0x0000FF00) >> 8) | ((value & 0x000000FF) << 8);
+#endif
+    return (result);
+}
+
+
+/**
+  \brief   Reverse byte order in signed short value
+  \details Reverses the byte order in a signed short value with sign extension to integer.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__ALWAYS_STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+    return (short)(((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8));
+}
+
+
+/**
+  \brief   Rotate Right in unsigned value (32 bit)
+  \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+  \param [in]    op1  Value to rotate
+  \param [in]    op2  Number of Bits to rotate
+  \return               Rotated value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+    return (op1 >> op2) | (op1 << (32U - op2));
+}
+
+
+/**
+  \brief   Breakpoint
+  \details Causes the processor to enter Debug state
+           Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+ */
+__ALWAYS_STATIC_INLINE void __BKPT(void)
+{
+    __ASM volatile("bkpt");
+}
+
+/**
+  \brief   Reverse bit order of value
+  \details Reverses the bit order of the given value.
+  \param [in]    value  Value to reverse
+  \return               Reversed value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+    uint32_t result;
+
+#if (__CK80X >= 0x03U)
+    __ASM volatile("brev %0, %1" : "=r"(result) : "r"(value));
+#else
+    int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+    result = value;                      /* r will be reversed bits of v; first get LSB of v */
+
+    for (value >>= 1U; value; value >>= 1U) {
+        result <<= 1U;
+        result |= value & 1U;
+        s--;
+    }
+
+    result <<= s;                        /* shift when v's highest bits are zero */
+#endif
+    return (result);
+}
+
+
+/**
+  \brief   Count leading zeros
+  \details Counts the number of leading zeros of a data value.
+  \param [in]  value  Value to count the leading zeros
+  \return             number of leading zeros in value
+ */
+#define __CLZ             __builtin_clz
+/**
+  \details This function saturates a signed value.
+  \param [in]    x   Value to be saturated
+  \param [in]    y   Bit position to saturate to [1..32]
+  \return            Saturated value.
+ */
+__ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, uint32_t y)
+{
+    int32_t posMax, negMin;
+    uint32_t i;
+
+    posMax = 1;
+
+    for (i = 0; i < (y - 1); i++) {
+        posMax = posMax * 2;
+    }
+
+    if (x > 0) {
+        posMax = (posMax - 1);
+
+        if (x > posMax) {
+            x = posMax;
+        }
+
+//    x &= (posMax * 2 + 1);
+    } else {
+        negMin = -posMax;
+
+        if (x < negMin) {
+            x = negMin;
+        }
+
+//    x &= (posMax * 2 - 1);
+    }
+
+    return (x);
+}
+
+/**
+  \brief   Unsigned Saturate
+  \details Saturates an unsigned value.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (0..31)
+  \return             Saturated value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __USAT(uint32_t value, uint32_t sat)
+{
+    uint32_t result;
+
+    if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
+        result = 0xFFFFFFFF >> (32 - sat);
+    } else {
+        result = value;
+    }
+
+    return (result);
+}
+
+/**
+  \brief   Unsigned Saturate for internal use
+  \details Saturates an unsigned value, should not call directly.
+  \param [in]  value  Value to be saturated
+  \param [in]    sat  Bit position to saturate to (0..31)
+  \return             Saturated value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat)
+{
+    uint32_t result;
+
+    if (value & 0x80000000) { /* only overflow set bit-31 */
+        result = 0;
+    } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) {
+        result = 0xFFFFFFFF >> (32 - sat);
+    } else {
+        result = value;
+    }
+
+    return (result);
+}
+
+/**
+  \brief   Rotate Right with Extend
+  \details This function moves each bit of a bitstring right by one bit.
+           The carry input is shifted in at the left end of the bitstring.
+  \note    carry input will always 0.
+  \param [in]    op1  Value to rotate
+  \return               Rotated value
+ */
+__ALWAYS_STATIC_INLINE uint32_t __RRX(uint32_t op1)
+{
+#if (__CK80X >= 2)
+    uint32_t res = 0;
+    __ASM volatile("bgeni    t0, 31\n\t"
+                   "lsri     %0, 1\n\t"
+                   "movt     %1, t0\n\t"
+                   "or       %1, %1, %0\n\t"
+               : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "t0");
+    return res;
+#else
+    uint32_t res = 0;
+    __ASM volatile("movi     r7, 0\n\t"
+                   "bseti    r7, 31\n\t"
+                   "lsri     %0, 1\n\t"
+                   "bf       1f\n\t"
+                   "mov     %1, r7\n\t"
+                   "1:\n\t"
+                   "or       %1, %1, %0\n\t"
+               : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "r7");
+    return res;
+#endif
+}
+
+/**
+  \brief   LDRT Unprivileged (8 bit)
+  \details Executes a Unprivileged LDRT instruction for 8 bit value.
+  \param [in]    addr  Pointer to location
+  \return             value of type uint8_t at (*ptr)
+ */
+__ALWAYS_STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
+{
+    uint32_t result;
+//#warning "__LDRBT"
+    __ASM volatile("ldb %0, (%1, 0)" : "=r"(result) : "r"(addr));
+    return ((uint8_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDRT Unprivileged (16 bit)
+  \details Executes a Unprivileged LDRT instruction for 16 bit values.
+  \param [in]    addr  Pointer to location
+  \return        value of type uint16_t at (*ptr)
+ */
+__ALWAYS_STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
+{
+    uint32_t result;
+
+//#warning "__LDRHT"
+    __ASM volatile("ldh %0, (%1, 0)" : "=r"(result) : "r"(addr));
+    return ((uint16_t) result);    /* Add explicit type cast here */
+}
+
+
+/**
+  \brief   LDRT Unprivileged (32 bit)
+  \details Executes a Unprivileged LDRT instruction for 32 bit values.
+  \param [in]    addr  Pointer to location
+  \return        value of type uint32_t at (*ptr)
+ */
+__ALWAYS_STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
+{
+    uint32_t result;
+
+//#warning "__LDRT"
+    __ASM volatile("ldw %0, (%1, 0)" : "=r"(result) : "r"(addr));
+    return (result);
+}
+
+
+/**
+  \brief   STRT Unprivileged (8 bit)
+  \details Executes a Unprivileged STRT instruction for 8 bit values.
+  \param [in]  value  Value to store
+  \param [in]    addr  Pointer to location
+ */
+__ALWAYS_STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
+{
+//#warning "__STRBT"
+    __ASM volatile("stb %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
+}
+
+
+/**
+  \brief   STRT Unprivileged (16 bit)
+  \details Executes a Unprivileged STRT instruction for 16 bit values.
+  \param [in]  value  Value to store
+  \param [in]    addr  Pointer to location
+ */
+__ALWAYS_STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
+{
+//#warning "__STRHT"
+    __ASM volatile("sth %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
+}
+
+
+/**
+  \brief   STRT Unprivileged (32 bit)
+  \details Executes a Unprivileged STRT instruction for 32 bit values.
+  \param [in]  value  Value to store
+  \param [in]    addr  Pointer to location
+ */
+__ALWAYS_STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
+{
+//#warning "__STRT"
+    __ASM volatile("stw %1, (%0, 0)" :: "r"(addr), "r"(value) : "memory");
+}
+
+/*@}*/ /* end of group CSI_Core_InstructionInterface */
+
+
+/* ##########################  FPU functions  #################################### */
+/**
+  \ingroup  CSI_Core_FunctionInterface
+  \defgroup CSI_Core_FpuFunctions FPU Functions
+  \brief    Function that provides FPU type.
+  @{
+ */
+
+/**
+  \brief   get FPU type
+  \details returns the FPU type, always 0.
+  \returns
+   - \b  0: No FPU
+   - \b  1: Single precision FPU
+   - \b  2: Double + Single precision FPU
+ */
+__ALWAYS_STATIC_INLINE uint32_t __get_FPUType(void)
+{
+//FIXME:
+    return 0;
+}
+
+/*@} end of CSI_Core_FpuFunctions */
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CSI_SIMD_intrinsics CSI SIMD Intrinsics
+  Access to dedicated SIMD instructions \n
+  Single Instruction Multiple Data (SIMD) extensions are provided to simplify development of application software. SIMD extensions increase the processing capability without materially increasing the power consumption. The SIMD extensions are completely transparent to the operating system (OS), allowing existing OS ports to be used.
+
+  @{
+*/
+
+/**
+  \brief   Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16]
+           of val2 levitated with the val3.
+  \details Combine a halfword from one register with a halfword from another register.
+           The second argument can be left-shifted before extraction of the halfword.
+  \param [in]    val1   first 16-bit operands
+  \param [in]    val2   second 16-bit operands
+  \param [in]    val3   value for left-shifting val2. Value range [0..31].
+  \return               the combination of halfwords.
+  \remark
+                 res[15:0]  = val1[15:0]              \n
+                 res[31:16] = val2[31:16] << val3
+ */
+__ALWAYS_STATIC_INLINE uint32_t __PKHBT(uint32_t val1, uint32_t val2, uint32_t val3)
+{
+    return ((((int32_t)(val1) << 0) & (int32_t)0x0000FFFF) | (((int32_t)(val2) << val3) & (int32_t)0xFFFF0000));
+}
+
+/**
+  \brief   Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0]
+           of val2 right-shifted with the val3.
+  \details Combine a halfword from one register with a halfword from another register.
+           The second argument can be right-shifted before extraction of the halfword.
+  \param [in]    val1   first 16-bit operands
+  \param [in]    val2   second 16-bit operands
+  \param [in]    val3   value for right-shifting val2. Value range [1..32].
+  \return               the combination of halfwords.
+  \remark
+                 res[15:0]  = val2[15:0] >> val3        \n
+                 res[31:16] = val1[31:16]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __PKHTB(uint32_t val1, uint32_t val2, uint32_t val3)
+{
+    return ((((int32_t)(val1) << 0) & (int32_t)0xFFFF0000) | (((int32_t)(val2) >> val3) & (int32_t)0x0000FFFF));
+}
+
+/**
+  \brief   Dual 16-bit signed saturate.
+  \details This function saturates a signed value.
+  \param [in]    x   two signed 16-bit values to be saturated.
+  \param [in]    y   bit position for saturation, an integral constant expression in the range 1 to 16.
+  \return        the sum of the absolute differences of the following bytes, added to the accumulation value:\n
+                 the signed saturation of the low halfword in val1, saturated to the bit position specified in
+                 val2 and returned in the low halfword of the return value.\n
+                 the signed saturation of the high halfword in val1, saturated to the bit position specified in
+                 val2 and returned in the high halfword of the return value.
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SSAT16(int32_t x, const uint32_t y)
+{
+    int32_t r = 0, s = 0;
+
+    r = __SSAT((((int32_t)x << 16) >> 16), y) & (int32_t)0x0000FFFF;
+    s = __SSAT((((int32_t)x) >> 16), y) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned saturate.
+  \details This function enables you to saturate two signed 16-bit values to a selected unsigned range.
+  \param [in]    x   two signed 16-bit values to be saturated.
+  \param [in]    y   bit position for saturation, an integral constant expression in the range 1 to 16.
+  \return        the saturation of the two signed 16-bit values, as non-negative values:
+                 the saturation of the low halfword in val1, saturated to the bit position specified in
+                 val2 and returned in the low halfword of the return value.\n
+                 the saturation of the high halfword in val1, saturated to the bit position specified in
+                 val2 and returned in the high halfword of the return value.
+ */
+__ALWAYS_STATIC_INLINE uint32_t __USAT16(uint32_t x, const uint32_t y)
+{
+    int32_t r = 0, s = 0;
+
+    r = __IUSAT(((x << 16) >> 16), y) & 0x0000FFFF;
+    s = __IUSAT(((x) >> 16), y) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Quad 8-bit saturating addition.
+  \details This function enables you to perform four 8-bit integer additions,
+           saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
+  \param [in]    x   first four 8-bit summands.
+  \param [in]    y   second four 8-bit summands.
+  \return        the saturated addition of the first byte of each operand in the first byte of the return value.\n
+                 the saturated addition of the second byte of each operand in the second byte of the return value.\n
+                 the saturated addition of the third byte of each operand in the third byte of the return value.\n
+                 the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n
+                 The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
+  \remark
+                 res[7:0]   = val1[7:0]   + val2[7:0]        \n
+                 res[15:8]  = val1[15:8]  + val2[15:8]       \n
+                 res[23:16] = val1[23:16] + val2[23:16]      \n
+                 res[31:24] = val1[31:24] + val2[31:24]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __QADD8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = __SSAT(((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+    s = __SSAT(((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+    t = __SSAT(((((int32_t)x <<  8) >> 24) + (((int32_t)y <<  8) >> 24)), 8) & (int32_t)0x000000FF;
+    u = __SSAT(((((int32_t)x) >> 24) + (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF;
+
+    return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
+}
+
+/**
+  \brief   Quad 8-bit unsigned saturating addition.
+  \details This function enables you to perform four unsigned 8-bit integer additions,
+           saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1.
+  \param [in]    x   first four 8-bit summands.
+  \param [in]    y   second four 8-bit summands.
+  \return        the saturated addition of the first byte of each operand in the first byte of the return value.\n
+                 the saturated addition of the second byte of each operand in the second byte of the return value.\n
+                 the saturated addition of the third byte of each operand in the third byte of the return value.\n
+                 the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n
+                 The returned results are saturated to the 8-bit signed integer range 0 <= x <= 2^8 - 1.
+  \remark
+                 res[7:0]   = val1[7:0]   + val2[7:0]        \n
+                 res[15:8]  = val1[15:8]  + val2[15:8]       \n
+                 res[23:16] = val1[23:16] + val2[23:16]      \n
+                 res[31:24] = val1[31:24] + val2[31:24]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UQADD8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = __IUSAT((((x << 24) >> 24) + ((y << 24) >> 24)), 8) & 0x000000FF;
+    s = __IUSAT((((x << 16) >> 24) + ((y << 16) >> 24)), 8) & 0x000000FF;
+    t = __IUSAT((((x <<  8) >> 24) + ((y <<  8) >> 24)), 8) & 0x000000FF;
+    u = __IUSAT((((x) >> 24) + ((y) >> 24)), 8) & 0x000000FF;
+
+    return ((u << 24) | (t << 16) | (s <<  8) | (r));
+}
+
+/**
+  \brief   Quad 8-bit signed addition.
+  \details This function performs four 8-bit signed integer additions.
+  \param [in]    x  first four 8-bit summands.
+  \param [in]    y  second four 8-bit summands.
+  \return        the addition of the first bytes from each operand, in the first byte of the return value.\n
+                 the addition of the second bytes of each operand, in the second byte of the return value.\n
+                 the addition of the third bytes of each operand, in the third byte of the return value.\n
+                 the addition of the fourth bytes of each operand, in the fourth byte of the return value.
+  \remark
+                 res[7:0]   = val1[7:0]   + val2[7:0]        \n
+                 res[15:8]  = val1[15:8]  + val2[15:8]       \n
+                 res[23:16] = val1[23:16] + val2[23:16]      \n
+                 res[31:24] = val1[31:24] + val2[31:24]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SADD8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = ((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF;
+    s = ((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF;
+    t = ((((int32_t)x <<  8) >> 24) + (((int32_t)y <<  8) >> 24)) & (int32_t)0x000000FF;
+    u = ((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) & (int32_t)0x000000FF;
+
+    return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
+}
+
+/**
+  \brief   Quad 8-bit unsigned addition.
+  \details This function performs four unsigned 8-bit integer additions.
+  \param [in]    x  first four 8-bit summands.
+  \param [in]    y  second four 8-bit summands.
+  \return        the addition of the first bytes from each operand, in the first byte of the return value.\n
+                 the addition of the second bytes of each operand, in the second byte of the return value.\n
+                 the addition of the third bytes of each operand, in the third byte of the return value.\n
+                 the addition of the fourth bytes of each operand, in the fourth byte of the return value.
+  \remark
+                 res[7:0]   = val1[7:0]   + val2[7:0]        \n
+                 res[15:8]  = val1[15:8]  + val2[15:8]       \n
+                 res[23:16] = val1[23:16] + val2[23:16]      \n
+                 res[31:24] = val1[31:24] + val2[31:24]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UADD8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = (((x << 24) >> 24) + ((y << 24) >> 24)) & 0x000000FF;
+    s = (((x << 16) >> 24) + ((y << 16) >> 24)) & 0x000000FF;
+    t = (((x <<  8) >> 24) + ((y <<  8) >> 24)) & 0x000000FF;
+    u = (((x) >> 24) + ((y) >> 24)) & 0x000000FF;
+
+    return ((u << 24) | (t << 16) | (s <<  8) | (r));
+}
+
+/**
+  \brief   Quad 8-bit saturating subtract.
+  \details This function enables you to perform four 8-bit integer subtractions,
+           saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
+  \param [in]    x   first four 8-bit summands.
+  \param [in]    y   second four 8-bit summands.
+  \return        the subtraction of the first byte of each operand in the first byte of the return value.\n
+                 the subtraction of the second byte of each operand in the second byte of the return value.\n
+                 the subtraction of the third byte of each operand in the third byte of the return value.\n
+                 the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n
+                 The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
+  \remark
+                 res[7:0]   = val1[7:0]   - val2[7:0]        \n
+                 res[15:8]  = val1[15:8]  - val2[15:8]       \n
+                 res[23:16] = val1[23:16] - val2[23:16]      \n
+                 res[31:24] = val1[31:24] - val2[31:24]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __QSUB8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = __SSAT(((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+    s = __SSAT(((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+    t = __SSAT(((((int32_t)x <<  8) >> 24) - (((int32_t)y <<  8) >> 24)), 8) & (int32_t)0x000000FF;
+    u = __SSAT(((((int32_t)x) >> 24) - (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF;
+
+    return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
+}
+
+/**
+  \brief   Quad 8-bit unsigned saturating subtraction.
+  \details This function enables you to perform four unsigned 8-bit integer subtractions,
+           saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1.
+  \param [in]    x   first four 8-bit summands.
+  \param [in]    y   second four 8-bit summands.
+  \return        the subtraction of the first byte of each operand in the first byte of the return value.\n
+                 the subtraction of the second byte of each operand in the second byte of the return value.\n
+                 the subtraction of the third byte of each operand in the third byte of the return value.\n
+                 the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n
+                 The returned results are saturated to the 8-bit unsigned integer range 0 <= x <= 2^8 - 1.
+  \remark
+                 res[7:0]   = val1[7:0]   - val2[7:0]        \n
+                 res[15:8]  = val1[15:8]  - val2[15:8]       \n
+                 res[23:16] = val1[23:16] - val2[23:16]      \n
+                 res[31:24] = val1[31:24] - val2[31:24]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UQSUB8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = __IUSAT((((x << 24) >> 24) - ((y << 24) >> 24)), 8) & 0x000000FF;
+    s = __IUSAT((((x << 16) >> 24) - ((y << 16) >> 24)), 8) & 0x000000FF;
+    t = __IUSAT((((x <<  8) >> 24) - ((y <<  8) >> 24)), 8) & 0x000000FF;
+    u = __IUSAT((((x) >> 24) - ((y) >> 24)), 8) & 0x000000FF;
+
+    return ((u << 24) | (t << 16) | (s <<  8) | (r));
+}
+
+/**
+  \brief   Quad 8-bit signed subtraction.
+  \details This function enables you to perform four 8-bit signed integer subtractions.
+  \param [in]    x  first four 8-bit operands of each subtraction.
+  \param [in]    y  second four 8-bit operands of each subtraction.
+  \return        the subtraction of the first bytes from each operand, in the first byte of the return value.\n
+                 the subtraction of the second bytes of each operand, in the second byte of the return value.\n
+                 the subtraction of the third bytes of each operand, in the third byte of the return value.\n
+                 the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.
+  \remark
+                 res[7:0]   = val1[7:0]   - val2[7:0]        \n
+                 res[15:8]  = val1[15:8]  - val2[15:8]       \n
+                 res[23:16] = val1[23:16] - val2[23:16]      \n
+                 res[31:24] = val1[31:24] - val2[31:24]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SSUB8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = ((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF;
+    s = ((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF;
+    t = ((((int32_t)x <<  8) >> 24) - (((int32_t)y <<  8) >> 24)) & (int32_t)0x000000FF;
+    u = ((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) & (int32_t)0x000000FF;
+
+    return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
+}
+
+/**
+  \brief   Quad 8-bit unsigned subtract.
+  \details This function enables you to perform four 8-bit unsigned integer subtractions.
+  \param [in]    x  first four 8-bit operands of each subtraction.
+  \param [in]    y  second four 8-bit operands of each subtraction.
+  \return        the subtraction of the first bytes from each operand, in the first byte of the return value.\n
+                 the subtraction of the second bytes of each operand, in the second byte of the return value.\n
+                 the subtraction of the third bytes of each operand, in the third byte of the return value.\n
+                 the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.
+  \remark
+                 res[7:0]   = val1[7:0]   - val2[7:0]        \n
+                 res[15:8]  = val1[15:8]  - val2[15:8]       \n
+                 res[23:16] = val1[23:16] - val2[23:16]      \n
+                 res[31:24] = val1[31:24] - val2[31:24]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __USUB8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF;
+    s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF;
+    t = (((x <<  8) >> 24) - ((y <<  8) >> 24)) & 0x000000FF;
+    u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF;
+
+    return ((u << 24) | (t << 16) | (s <<  8) | (r));
+}
+
+/**
+  \brief   Unsigned sum of quad 8-bit unsigned absolute difference.
+  \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values
+           of the differences together, returning the result as a single unsigned integer.
+  \param [in]    x  first four 8-bit operands of each subtraction.
+  \param [in]    y  second four 8-bit operands of each subtraction.
+  \return        the subtraction of the first bytes from each operand, in the first byte of the return value.\n
+                 the subtraction of the second bytes of each operand, in the second byte of the return value.\n
+                 the subtraction of the third bytes of each operand, in the third byte of the return value.\n
+                 the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.\n
+                 The sum is returned as a single unsigned integer.
+  \remark
+                 absdiff1   = val1[7:0]   - val2[7:0]        \n
+                 absdiff2   = val1[15:8]  - val2[15:8]       \n
+                 absdiff3   = val1[23:16] - val2[23:16]      \n
+                 absdiff4   = val1[31:24] - val2[31:24]      \n
+                 res[31:0]  = absdiff1 + absdiff2 + absdiff3 + absdiff4
+ */
+__ALWAYS_STATIC_INLINE uint32_t __USAD8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF;
+    s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF;
+    t = (((x <<  8) >> 24) - ((y <<  8) >> 24)) & 0x000000FF;
+    u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF;
+
+    return (u + t + s + r);
+}
+
+/**
+  \brief   Unsigned sum of quad 8-bit unsigned absolute difference with 32-bit accumulate.
+  \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values
+           of the differences to a 32-bit accumulate operand.
+  \param [in]    x  first four 8-bit operands of each subtraction.
+  \param [in]    y  second four 8-bit operands of each subtraction.
+  \param [in]  sum  accumulation value.
+  \return        the sum of the absolute differences of the following bytes, added to the accumulation value:
+                 the subtraction of the first bytes from each operand, in the first byte of the return value.\n
+                 the subtraction of the second bytes of each operand, in the second byte of the return value.\n
+                 the subtraction of the third bytes of each operand, in the third byte of the return value.\n
+                 the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.
+  \remark
+                 absdiff1 = val1[7:0]   - val2[7:0]        \n
+                 absdiff2 = val1[15:8]  - val2[15:8]       \n
+                 absdiff3 = val1[23:16] - val2[23:16]      \n
+                 absdiff4 = val1[31:24] - val2[31:24]      \n
+                 sum = absdiff1 + absdiff2 + absdiff3 + absdiff4 \n
+                 res[31:0] = sum[31:0] + val3[31:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __USADA8(uint32_t x, uint32_t y, uint32_t sum)
+{
+    int32_t r, s, t, u;
+
+#ifdef __cplusplus
+    r = (abs((long long)((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF;
+    s = (abs((long long)((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF;
+    t = (abs((long long)((x <<  8) >> 24) - ((y <<  8) >> 24))) & 0x000000FF;
+    u = (abs((long long)((x) >> 24) - ((y) >> 24))) & 0x000000FF;
+#else
+    r = (abs(((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF;
+    s = (abs(((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF;
+    t = (abs(((x <<  8) >> 24) - ((y <<  8) >> 24))) & 0x000000FF;
+    u = (abs(((x) >> 24) - ((y) >> 24))) & 0x000000FF;
+#endif
+    return (u + t + s + r + sum);
+}
+
+/**
+  \brief   Dual 16-bit saturating addition.
+  \details This function enables you to perform two 16-bit integer arithmetic additions in parallel,
+           saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+  \param [in]    x   first two 16-bit summands.
+  \param [in]    y   second two 16-bit summands.
+  \return        the saturated addition of the low halfwords, in the low halfword of the return value.\n
+                 the saturated addition of the high halfwords, in the high halfword of the return value.\n
+                 The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+  \remark
+                 res[15:0]  = val1[15:0]  + val2[15:0]        \n
+                 res[31:16] = val1[31:16] + val2[31:16]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __QADD16(uint32_t x, uint32_t y)
+{
+    int32_t r = 0, s = 0;
+
+    r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned saturating addition.
+  \details This function enables you to perform two unsigned 16-bit integer additions, saturating
+           the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1.
+  \param [in]    x   first two 16-bit summands.
+  \param [in]    y   second two 16-bit summands.
+  \return        the saturated addition of the low halfwords, in the low halfword of the return value.\n
+                 the saturated addition of the high halfwords, in the high halfword of the return value.\n
+                 The results are saturated to the 16-bit unsigned integer range 0 < x < 2^16 - 1.
+  \remark
+                 res[15:0]  = val1[15:0]  + val2[15:0]        \n
+                 res[31:16] = val1[31:16] + val2[31:16]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UQADD16(uint32_t x, uint32_t y)
+{
+    int32_t r = 0, s = 0;
+
+    r = __IUSAT((((x << 16) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF;
+    s = __IUSAT((((x) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Dual 16-bit signed addition.
+  \details This function enables you to perform two 16-bit signed integer additions.
+  \param [in]    x   first two 16-bit summands.
+  \param [in]    y   second two 16-bit summands.
+  \return        the addition of the low halfwords in the low halfword of the return value.\n
+                 the addition of the high halfwords in the high halfword of the return value.
+  \remark
+                 res[15:0]  = val1[15:0]  + val2[15:0]        \n
+                 res[31:16] = val1[31:16] + val2[31:16]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SADD16(uint32_t x, uint32_t y)
+{
+    int32_t r = 0, s = 0;
+
+    r = ((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
+    s = ((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned addition
+  \details This function enables you to perform two 16-bit unsigned integer additions.
+  \param [in]    x   first two 16-bit summands for each addition.
+  \param [in]    y   second two 16-bit summands for each addition.
+  \return        the addition of the low halfwords in the low halfword of the return value.\n
+                 the addition of the high halfwords in the high halfword of the return value.
+  \remark
+                 res[15:0]  = val1[15:0]  + val2[15:0]        \n
+                 res[31:16] = val1[31:16] + val2[31:16]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UADD16(uint32_t x, uint32_t y)
+{
+    int32_t r = 0, s = 0;
+
+    r = (((x << 16) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF;
+    s = (((x) >> 16) + ((y) >> 16)) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+
+/**
+  \brief   Dual 16-bit signed addition with halved results.
+  \details This function enables you to perform two signed 16-bit integer additions, halving the results.
+  \param [in]    x   first two 16-bit summands.
+  \param [in]    y   second two 16-bit summands.
+  \return        the halved addition of the low halfwords, in the low halfword of the return value.\n
+                 the halved addition of the high halfwords, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = (val1[15:0]  + val2[15:0]) >> 1        \n
+                 res[31:16] = (val1[31:16] + val2[31:16]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SHADD16(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = (((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned addition with halved results.
+  \details This function enables you to perform two unsigned 16-bit integer additions, halving the results.
+  \param [in]    x   first two 16-bit summands.
+  \param [in]    y   second two 16-bit summands.
+  \return        the halved addition of the low halfwords, in the low halfword of the return value.\n
+                 the halved addition of the high halfwords, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = (val1[15:0]  + val2[15:0]) >> 1        \n
+                 res[31:16] = (val1[31:16] + val2[31:16]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UHADD16(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = ((((x << 16) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
+    s = ((((x) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Quad 8-bit signed addition with halved results.
+  \details This function enables you to perform four signed 8-bit integer additions, halving the results.
+  \param [in]    x   first four 8-bit summands.
+  \param [in]    y   second four 8-bit summands.
+  \return        the halved addition of the first bytes from each operand, in the first byte of the return value.\n
+                 the halved addition of the second bytes from each operand, in the second byte of the return value.\n
+                 the halved addition of the third bytes from each operand, in the third byte of the return value.\n
+                 the halved addition of the fourth bytes from each operand, in the fourth byte of the return value.
+  \remark
+                 res[7:0]   = (val1[7:0]   + val2[7:0]  ) >> 1    \n
+                 res[15:8]  = (val1[15:8]  + val2[15:8] ) >> 1    \n
+                 res[23:16] = (val1[23:16] + val2[23:16]) >> 1    \n
+                 res[31:24] = (val1[31:24] + val2[31:24]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SHADD8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = (((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF;
+    s = (((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF;
+    t = (((((int32_t)x <<  8) >> 24) + (((int32_t)y <<  8) >> 24)) >> 1) & (int32_t)0x000000FF;
+    u = (((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF;
+
+    return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
+}
+
+/**
+  \brief   Quad 8-bit unsigned addition with halved results.
+  \details This function enables you to perform four unsigned 8-bit integer additions, halving the results.
+  \param [in]    x   first four 8-bit summands.
+  \param [in]    y   second four 8-bit summands.
+  \return        the halved addition of the first bytes from each operand, in the first byte of the return value.\n
+                 the halved addition of the second bytes from each operand, in the second byte of the return value.\n
+                 the halved addition of the third bytes from each operand, in the third byte of the return value.\n
+                 the halved addition of the fourth bytes from each operand, in the fourth byte of the return value.
+  \remark
+                 res[7:0]   = (val1[7:0]   + val2[7:0]  ) >> 1    \n
+                 res[15:8]  = (val1[15:8]  + val2[15:8] ) >> 1    \n
+                 res[23:16] = (val1[23:16] + val2[23:16]) >> 1    \n
+                 res[31:24] = (val1[31:24] + val2[31:24]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UHADD8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = ((((x << 24) >> 24) + ((y << 24) >> 24)) >> 1) & 0x000000FF;
+    s = ((((x << 16) >> 24) + ((y << 16) >> 24)) >> 1) & 0x000000FF;
+    t = ((((x <<  8) >> 24) + ((y <<  8) >> 24)) >> 1) & 0x000000FF;
+    u = ((((x) >> 24) + ((y) >> 24)) >> 1) & 0x000000FF;
+
+    return ((u << 24) | (t << 16) | (s <<  8) | (r));
+}
+
+/**
+  \brief   Dual 16-bit saturating subtract.
+  \details This function enables you to perform two 16-bit integer subtractions in parallel,
+           saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+  \param [in]    x   first two 16-bit summands.
+  \param [in]    y   second two 16-bit summands.
+  \return        the saturated subtraction of the low halfwords, in the low halfword of the return value.\n
+                 the saturated subtraction of the high halfwords, in the high halfword of the return value.\n
+                 The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+  \remark
+                 res[15:0]  = val1[15:0]  - val2[15:0]        \n
+                 res[31:16] = val1[31:16] - val2[31:16]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __QSUB16(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned saturating subtraction.
+  \details This function enables you to perform two unsigned 16-bit integer subtractions,
+           saturating the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1.
+  \param [in]    x   first two 16-bit operands for each subtraction.
+  \param [in]    y   second two 16-bit operands for each subtraction.
+  \return        the saturated subtraction of the low halfwords, in the low halfword of the return value.\n
+                 the saturated subtraction of the high halfwords, in the high halfword of the return value.\n
+                 The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+  \remark
+                 res[15:0]  = val1[15:0]  - val2[15:0]        \n
+                 res[31:16] = val1[31:16] - val2[31:16]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UQSUB16(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = __IUSAT((((x << 16) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF;
+    s = __IUSAT((((x) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Dual 16-bit signed subtraction.
+  \details This function enables you to perform two 16-bit signed integer subtractions.
+  \param [in]    x   first two 16-bit operands of each subtraction.
+  \param [in]    y   second two 16-bit operands of each subtraction.
+  \return        the subtraction of the low halfword in the second operand from the low
+                 halfword in the first operand, in the low halfword of the return value. \n
+                 the subtraction of the high halfword in the second operand from the high
+                 halfword in the first operand, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = val1[15:0]  - val2[15:0]        \n
+                 res[31:16] = val1[31:16] - val2[31:16]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SSUB16(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = ((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
+    s = ((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned subtract.
+  \details This function enables you to perform two 16-bit unsigned integer subtractions.
+  \param [in]    x   first two 16-bit operands of each subtraction.
+  \param [in]    y   second two 16-bit operands of each subtraction.
+  \return        the subtraction of the low halfword in the second operand from the low
+                 halfword in the first operand, in the low halfword of the return value. \n
+                 the subtraction of the high halfword in the second operand from the high
+                 halfword in the first operand, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = val1[15:0]  - val2[15:0]        \n
+                 res[31:16] = val1[31:16] - val2[31:16]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __USUB16(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = (((x << 16) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF;
+    s = (((x) >> 16) - ((y) >> 16)) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Dual 16-bit signed subtraction with halved results.
+  \details This function enables you to perform two signed 16-bit integer subtractions, halving the results.
+  \param [in]    x   first two 16-bit summands.
+  \param [in]    y   second two 16-bit summands.
+  \return        the halved subtraction of the low halfwords, in the low halfword of the return value.\n
+                 the halved subtraction of the high halfwords, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = (val1[15:0]  - val2[15:0]) >> 1        \n
+                 res[31:16] = (val1[31:16] - val2[31:16]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SHSUB16(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = (((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned subtraction with halved results.
+  \details This function enables you to perform two unsigned 16-bit integer subtractions, halving the results.
+  \param [in]    x   first two 16-bit summands.
+  \param [in]    y   second two 16-bit summands.
+  \return        the halved subtraction of the low halfwords, in the low halfword of the return value.\n
+                 the halved subtraction of the high halfwords, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = (val1[15:0]  - val2[15:0]) >> 1        \n
+                 res[31:16] = (val1[31:16] - val2[31:16]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UHSUB16(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = ((((x << 16) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
+    s = ((((x) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Quad 8-bit signed addition with halved results.
+  \details This function enables you to perform four signed 8-bit integer subtractions, halving the results.
+  \param [in]    x   first four 8-bit summands.
+  \param [in]    y   second four 8-bit summands.
+  \return        the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n
+                 the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n
+                 the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n
+                 the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value.
+  \remark
+                 res[7:0]   = (val1[7:0]   - val2[7:0]  ) >> 1    \n
+                 res[15:8]  = (val1[15:8]  - val2[15:8] ) >> 1    \n
+                 res[23:16] = (val1[23:16] - val2[23:16]) >> 1    \n
+                 res[31:24] = (val1[31:24] - val2[31:24]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SHSUB8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = (((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF;
+    s = (((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF;
+    t = (((((int32_t)x <<  8) >> 24) - (((int32_t)y <<  8) >> 24)) >> 1) & (int32_t)0x000000FF;
+    u = (((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF;
+
+    return ((uint32_t)((u << 24) | (t << 16) | (s <<  8) | (r)));
+}
+
+/**
+  \brief   Quad 8-bit unsigned subtraction with halved results.
+  \details This function enables you to perform four unsigned 8-bit integer subtractions, halving the results.
+  \param [in]    x   first four 8-bit summands.
+  \param [in]    y   second four 8-bit summands.
+  \return        the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n
+                 the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n
+                 the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n
+                 the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value.
+  \remark
+                 res[7:0]   = (val1[7:0]   - val2[7:0]  ) >> 1    \n
+                 res[15:8]  = (val1[15:8]  - val2[15:8] ) >> 1    \n
+                 res[23:16] = (val1[23:16] - val2[23:16]) >> 1    \n
+                 res[31:24] = (val1[31:24] - val2[31:24]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UHSUB8(uint32_t x, uint32_t y)
+{
+    int32_t r, s, t, u;
+
+    r = ((((x << 24) >> 24) - ((y << 24) >> 24)) >> 1) & 0x000000FF;
+    s = ((((x << 16) >> 24) - ((y << 16) >> 24)) >> 1) & 0x000000FF;
+    t = ((((x <<  8) >> 24) - ((y <<  8) >> 24)) >> 1) & 0x000000FF;
+    u = ((((x) >> 24) - ((y) >> 24)) >> 1) & 0x000000FF;
+
+    return ((u << 24) | (t << 16) | (s <<  8) | (r));
+}
+
+/**
+  \brief   Dual 16-bit add and subtract with exchange.
+  \details This function enables you to exchange the halfwords of the one operand,
+           then add the high halfwords and subtract the low halfwords,
+           saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+  \param [in]    x   first operand for the subtraction in the low halfword,
+                     and the first operand for the addition in the high halfword.
+  \param [in]    y   second operand for the subtraction in the high halfword,
+                     and the second operand for the addition in the low halfword.
+  \return        the saturated subtraction of the high halfword in the second operand from the
+                 low halfword in the first operand, in the low halfword of the return value.\n
+                 the saturated addition of the high halfword in the first operand and the
+                 low halfword in the second operand, in the high halfword of the return value.\n
+                 The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+  \remark
+                 res[15:0]  = val1[15:0]  - val2[31:16]        \n
+                 res[31:16] = val1[31:16] + val2[15:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __QASX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned saturating addition and subtraction with exchange.
+  \details This function enables you to exchange the halfwords of the second operand and
+           perform one unsigned 16-bit integer addition and one unsigned 16-bit subtraction,
+           saturating the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
+  \param [in]    x   first operand for the subtraction in the low halfword,
+                     and the first operand for the addition in the high halfword.
+  \param [in]    y   second operand for the subtraction in the high halfword,
+                     and the second operand for the addition in the low halfword.
+  \return        the saturated subtraction of the high halfword in the second operand from the
+                 low halfword in the first operand, in the low halfword of the return value.\n
+                 the saturated addition of the high halfword in the first operand and the
+                 low halfword in the second operand, in the high halfword of the return value.\n
+                 The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
+  \remark
+                 res[15:0]  = val1[15:0]  - val2[31:16]        \n
+                 res[31:16] = val1[31:16] + val2[15:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UQASX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = __IUSAT((((x << 16) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF;
+    s = __IUSAT((((x) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Dual 16-bit addition and subtraction with exchange.
+  \details It enables you to exchange the halfwords of the second operand, add the high halfwords
+           and subtract the low halfwords.
+  \param [in]    x   first operand for the subtraction in the low halfword,
+                     and the first operand for the addition in the high halfword.
+  \param [in]    y   second operand for the subtraction in the high halfword,
+                     and the second operand for the addition in the low halfword.
+  \return        the subtraction of the high halfword in the second operand from the
+                 low halfword in the first operand, in the low halfword of the return value.\n
+                 the addition of the high halfword in the first operand and the
+                 low halfword in the second operand, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = val1[15:0]  - val2[31:16]        \n
+                 res[31:16] = val1[31:16] + val2[15:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SASX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = ((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
+    s = ((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned addition and subtraction with exchange.
+  \details This function enables you to exchange the two halfwords of the second operand,
+           add the high halfwords and subtract the low halfwords.
+  \param [in]    x   first operand for the subtraction in the low halfword,
+                     and the first operand for the addition in the high halfword.
+  \param [in]    y   second operand for the subtraction in the high halfword,
+                     and the second operand for the addition in the low halfword.
+  \return        the subtraction of the high halfword in the second operand from the
+                 low halfword in the first operand, in the low halfword of the return value.\n
+                 the addition of the high halfword in the first operand and the
+                 low halfword in the second operand, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = val1[15:0]  - val2[31:16]        \n
+                 res[31:16] = val1[31:16] + val2[15:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UASX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = (((x << 16) >> 16) - ((y) >> 16)) & 0x0000FFFF;
+    s = (((x) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Dual 16-bit signed addition and subtraction with halved results.
+  \details This function enables you to exchange the two halfwords of one operand, perform one
+           signed 16-bit integer addition and one signed 16-bit subtraction, and halve the results.
+  \param [in]    x   first 16-bit operands.
+  \param [in]    y   second 16-bit operands.
+  \return        the halved subtraction of the high halfword in the second operand from the
+                 low halfword in the first operand, in the low halfword of the return value.\n
+                 the halved addition of the low halfword in the second operand from the high
+                 halfword in the first operand, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = (val1[15:0]  - val2[31:16]) >> 1        \n
+                 res[31:16] = (val1[31:16] + val2[15:0]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SHASX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = (((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned addition and subtraction with halved results and exchange.
+  \details This function enables you to exchange the halfwords of the second operand,
+           add the high halfwords and subtract the low halfwords, halving the results.
+  \param [in]    x   first operand for the subtraction in the low halfword, and
+                     the first operand for the addition in the high halfword.
+  \param [in]    y   second operand for the subtraction in the high halfword, and
+                     the second operand for the addition in the low halfword.
+  \return        the halved subtraction of the high halfword in the second operand from the
+                 low halfword in the first operand, in the low halfword of the return value.\n
+                 the halved addition of the low halfword in the second operand from the high
+                 halfword in the first operand, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = (val1[15:0]  - val2[31:16]) >> 1        \n
+                 res[31:16] = (val1[31:16] + val2[15:0]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UHASX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = ((((x << 16) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF;
+    s = ((((x) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Dual 16-bit subtract and add with exchange.
+  \details This function enables you to exchange the halfwords of one operand,
+           then subtract the high halfwords and add the low halfwords,
+           saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+  \param [in]    x   first operand for the addition in the low halfword,
+                     and the first operand for the subtraction in the high halfword.
+  \param [in]    y   second operand for the addition in the high halfword,
+                     and the second operand for the subtraction in the low halfword.
+  \return        the saturated addition of the low halfword of the first operand and the high
+                 halfword of the second operand, in the low halfword of the return value.\n
+                 the saturated subtraction of the low halfword of the second operand from the
+                 high halfword of the first operand, in the high halfword of the return value.\n
+                 The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+  \remark
+                 res[15:0]  = val1[15:0]  + val2[31:16]        \n
+                 res[31:16] = val1[31:16] - val2[15:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __QSAX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
+    s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned saturating subtraction and addition with exchange.
+  \details This function enables you to exchange the halfwords of the second operand and perform
+           one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, saturating
+           the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
+  \param [in]    x   first operand for the addition in the low halfword,
+                     and the first operand for the subtraction in the high halfword.
+  \param [in]    y   second operand for the addition in the high halfword,
+                     and the second operand for the subtraction in the low halfword.
+  \return        the saturated addition of the low halfword of the first operand and the high
+                 halfword of the second operand, in the low halfword of the return value.\n
+                 the saturated subtraction of the low halfword of the second operand from the
+                 high halfword of the first operand, in the high halfword of the return value.\n
+                 The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
+  \remark
+                 res[15:0]  = val1[15:0]  + val2[31:16]        \n
+                 res[31:16] = val1[31:16] - val2[15:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UQSAX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = __IUSAT((((x << 16) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF;
+    s = __IUSAT((((x) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Dual 16-bit unsigned subtract and add with exchange.
+  \details This function enables you to exchange the halfwords of the second operand,
+           subtract the high halfwords and add the low halfwords.
+  \param [in]    x   first operand for the addition in the low halfword,
+                     and the first operand for the subtraction in the high halfword.
+  \param [in]    y   second operand for the addition in the high halfword,
+                     and the second operand for the subtraction in the low halfword.
+  \return        the addition of the low halfword of the first operand and the high
+                 halfword of the second operand, in the low halfword of the return value.\n
+                 the subtraction of the low halfword of the second operand from the
+                 high halfword of the first operand, in the high halfword of the return value.\n
+  \remark
+                 res[15:0]  = val1[15:0]  + val2[31:16]        \n
+                 res[31:16] = val1[31:16] - val2[15:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __USAX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = (((x << 16) >> 16) + ((y) >> 16)) & 0x0000FFFF;
+    s = (((x) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Dual 16-bit signed subtraction and addition with exchange.
+  \details This function enables you to exchange the two halfwords of one operand and perform one
+           16-bit integer subtraction and one 16-bit addition.
+  \param [in]    x   first operand for the addition in the low halfword, and the first operand
+                     for the subtraction in the high halfword.
+  \param [in]    y   second operand for the addition in the high halfword, and the second
+                     operand for the subtraction in the low halfword.
+  \return        the addition of the low halfword of the first operand and the high
+                 halfword of the second operand, in the low halfword of the return value.\n
+                 the subtraction of the low halfword of the second operand from the
+                 high halfword of the first operand, in the high halfword of the return value.\n
+  \remark
+                 res[15:0]  = val1[15:0]  + val2[31:16]        \n
+                 res[31:16] = val1[31:16] - val2[15:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SSAX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = ((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
+    s = ((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+
+/**
+  \brief   Dual 16-bit signed subtraction and addition with halved results.
+  \details This function enables you to exchange the two halfwords of one operand, perform one signed
+           16-bit integer subtraction and one signed 16-bit addition, and halve the results.
+  \param [in]    x   first 16-bit operands.
+  \param [in]    y   second 16-bit operands.
+  \return        the halved addition of the low halfword in the first operand and the
+                 high halfword in the second operand, in the low halfword of the return value.\n
+                 the halved subtraction of the low halfword in the second operand from the
+                 high halfword in the first operand, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = (val1[15:0]  + val2[31:16]) >> 1        \n
+                 res[31:16] = (val1[31:16] - val2[15:0]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SHSAX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = (((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+    s = (((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+    return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+  \brief   Dual 16-bit unsigned subtraction and addition with halved results and exchange.
+  \details This function enables you to exchange the halfwords of the second operand,
+           subtract the high halfwords and add the low halfwords, halving the results.
+  \param [in]    x   first operand for the addition in the low halfword, and
+                     the first operand for the subtraction in the high halfword.
+  \param [in]    y   second operand for the addition in the high halfword, and
+                     the second operand for the subtraction in the low halfword.
+  \return        the halved addition of the low halfword in the first operand and the
+                 high halfword in the second operand, in the low halfword of the return value.\n
+                 the halved subtraction of the low halfword in the second operand from the
+                 high halfword in the first operand, in the high halfword of the return value.
+  \remark
+                 res[15:0]  = (val1[15:0]  + val2[31:16]) >> 1        \n
+                 res[31:16] = (val1[31:16] - val2[15:0]) >> 1
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UHSAX(uint32_t x, uint32_t y)
+{
+    int32_t r, s;
+
+    r = ((((x << 16) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF;
+    s = ((((x) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
+
+    return ((s << 16) | (r));
+}
+
+/**
+  \brief   Dual 16-bit signed multiply with exchange returning difference.
+  \details This function enables you to perform two 16-bit signed multiplications, subtracting
+           one of the products from the other. The halfwords of the second operand are exchanged
+           before performing the arithmetic. This produces top * bottom and bottom * top multiplication.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \return        the difference of the products of the two 16-bit signed multiplications.
+  \remark
+                 p1 = val1[15:0]  * val2[31:16]       \n
+                 p2 = val1[31:16] * val2[15:0]        \n
+                 res[31:0] = p1 - p2
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SMUSDX(uint32_t x, uint32_t y)
+{
+    return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) -
+                       ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16))));
+}
+
+/**
+  \brief   Sum of dual 16-bit signed multiply with exchange.
+  \details This function enables you to perform two 16-bit signed multiplications with exchanged
+           halfwords of the second operand, adding the products together.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \return        the sum of the products of the two 16-bit signed multiplications with exchanged halfwords of the second operand.
+  \remark
+                 p1 = val1[15:0]  * val2[31:16]       \n
+                 p2 = val1[31:16] * val2[15:0]        \n
+                 res[31:0] = p1 + p2
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SMUADX(uint32_t x, uint32_t y)
+{
+    return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) +
+                       ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16))));
+}
+
+
+/**
+  \brief   Saturating add.
+  \details This function enables you to obtain the saturating add of two integers.
+  \param [in]    x   first summand of the saturating add operation.
+  \param [in]    y   second summand of the saturating add operation.
+  \return        the saturating addition of val1 and val2.
+  \remark
+                 res[31:0] = SAT(val1 + SAT(val2))
+ */
+__ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y)
+{
+    int32_t result;
+
+    if (y >= 0) {
+        if (x + y >= x) {
+            result = x + y;
+        } else {
+            result = 0x7FFFFFFF;
+        }
+    } else {
+        if (x + y < x) {
+            result = x + y;
+        } else {
+            result = 0x80000000;
+        }
+    }
+
+    return result;
+}
+
+/**
+  \brief   Saturating subtract.
+  \details This function enables you to obtain the saturating add of two integers.
+  \param [in]    x   first summand of the saturating add operation.
+  \param [in]    y   second summand of the saturating add operation.
+  \return        the saturating addition of val1 and val2.
+  \remark
+                 res[31:0] = SAT(val1 - SAT(val2))
+ */
+__ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y)
+{
+    int64_t tmp;
+    int32_t result;
+
+    tmp = (int64_t)x - (int64_t)y;
+
+    if (tmp > 0x7fffffff) {
+        tmp = 0x7fffffff;
+    } else if (tmp < (-2147483647 - 1)) {
+        tmp = -2147483647 - 1;
+    }
+
+    result = tmp;
+    return result;
+}
+
+/**
+  \brief   Dual 16-bit signed multiply with single 32-bit accumulator.
+  \details This function enables you to perform two signed 16-bit multiplications,
+           adding both results to a 32-bit accumulate operand.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \param [in]  sum   accumulate value.
+  \return        the product of each multiplication added to the accumulate value, as a 32-bit integer.
+  \remark
+                 p1 = val1[15:0]  * val2[15:0]      \n
+                 p2 = val1[31:16] * val2[31:16]     \n
+                 res[31:0] = p1 + p2 + val3[31:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SMLAD(uint32_t x, uint32_t y, uint32_t sum)
+{
+    return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) +
+                       ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
+                       (((int32_t)sum))));
+}
+
+/**
+  \brief   Pre-exchanged dual 16-bit signed multiply with single 32-bit accumulator.
+  \details This function enables you to perform two signed 16-bit multiplications with exchanged
+           halfwords of the second operand, adding both results to a 32-bit accumulate operand.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \param [in]  sum   accumulate value.
+  \return        the product of each multiplication with exchanged halfwords of the second
+                 operand added to the accumulate value, as a 32-bit integer.
+  \remark
+                 p1 = val1[15:0]  * val2[31:16]     \n
+                 p2 = val1[31:16] * val2[15:0]      \n
+                 res[31:0] = p1 + p2 + val3[31:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SMLADX(uint32_t x, uint32_t y, uint32_t sum)
+{
+    return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) +
+                       ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
+                       (((int32_t)sum))));
+}
+
+/**
+  \brief   Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate.
+  \details This function enables you to perform two 16-bit signed multiplications, take the
+           difference of the products, subtracting the high halfword product from the low
+           halfword product, and add the difference to a 32-bit accumulate operand.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \param [in]  sum   accumulate value.
+  \return        the difference of the product of each multiplication, added to the accumulate value.
+  \remark
+                 p1 = val1[15:0]  * val2[15:0]       \n
+                 p2 = val1[31:16] * val2[31:16]      \n
+                 res[31:0] = p1 - p2 + val3[31:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SMLSD(uint32_t x, uint32_t y, uint32_t sum)
+{
+    return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) -
+                       ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
+                       (((int32_t)sum))));
+}
+
+/**
+  \brief   Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate.
+  \details This function enables you to exchange the halfwords in the second operand, then perform two 16-bit
+           signed multiplications. The difference of the products is added to a 32-bit accumulate operand.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \param [in]  sum   accumulate value.
+  \return        the difference of the product of each multiplication, added to the accumulate value.
+  \remark
+                 p1 = val1[15:0]  * val2[31:16]     \n
+                 p2 = val1[31:16] * val2[15:0]      \n
+                 res[31:0] = p1 - p2 + val3[31:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SMLSDX(uint32_t x, uint32_t y, uint32_t sum)
+{
+    return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) -
+                       ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
+                       (((int32_t)sum))));
+}
+
+/**
+  \brief   Dual 16-bit signed multiply with single 64-bit accumulator.
+  \details This function enables you to perform two signed 16-bit multiplications, adding both results
+           to a 64-bit accumulate operand. Overflow is only possible as a result of the 64-bit addition.
+           This overflow is not detected if it occurs. Instead, the result wraps around modulo2^64.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \param [in]  sum   accumulate value.
+  \return        the product of each multiplication added to the accumulate value.
+  \remark
+                 p1 = val1[15:0]  * val2[15:0]      \n
+                 p2 = val1[31:16] * val2[31:16]     \n
+                 sum = p1 + p2 + val3[63:32][31:0]  \n
+                 res[63:32] = sum[63:32]            \n
+                 res[31:0]  = sum[31:0]
+ */
+__ALWAYS_STATIC_INLINE uint64_t __SMLALD(uint32_t x, uint32_t y, uint64_t sum)
+{
+    return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) +
+                       ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
+                       (((uint64_t)sum))));
+}
+
+/**
+  \brief   Dual 16-bit signed multiply with exchange with single 64-bit accumulator.
+  \details This function enables you to exchange the halfwords of the second operand, and perform two
+           signed 16-bit multiplications, adding both results to a 64-bit accumulate operand. Overflow
+           is only possible as a result of the 64-bit addition. This overflow is not detected if it occurs.
+           Instead, the result wraps around modulo2^64.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \param [in]  sum   accumulate value.
+  \return        the product of each multiplication added to the accumulate value.
+  \remark
+                 p1 = val1[15:0]  * val2[31:16]     \n
+                 p2 = val1[31:16] * val2[15:0]      \n
+                 sum = p1 + p2 + val3[63:32][31:0]  \n
+                 res[63:32] = sum[63:32]            \n
+                 res[31:0]  = sum[31:0]
+ */
+__ALWAYS_STATIC_INLINE uint64_t __SMLALDX(uint32_t x, uint32_t y, uint64_t sum)
+{
+    return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) +
+                       ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
+                       (((uint64_t)sum))));
+}
+
+/**
+  \brief   dual 16-bit signed multiply subtract with 64-bit accumulate.
+  \details This function It enables you to perform two 16-bit signed multiplications, take the difference
+           of the products, subtracting the high halfword product from the low halfword product, and add the
+           difference to a 64-bit accumulate operand. Overflow cannot occur during the multiplications or the
+           subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow is not
+           detected. Instead, the result wraps round to modulo2^64.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \param [in]  sum   accumulate value.
+  \return        the difference of the product of each multiplication, added to the accumulate value.
+  \remark
+                 p1 = val1[15:0]  * val2[15:0]      \n
+                 p2 = val1[31:16] * val2[31:16]     \n
+                 res[63:32][31:0] = p1 - p2 + val3[63:32][31:0]
+ */
+__ALWAYS_STATIC_INLINE uint64_t __SMLSLD(uint32_t x, uint32_t y, uint64_t sum)
+{
+    return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) -
+                       ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
+                       (((uint64_t)sum))));
+}
+
+/**
+  \brief   Dual 16-bit signed multiply with exchange subtract with 64-bit accumulate.
+  \details This function enables you to exchange the halfwords of the second operand, perform two 16-bit multiplications,
+           adding the difference of the products to a 64-bit accumulate operand. Overflow cannot occur during the
+           multiplications or the subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow
+           is not detected. Instead, the result wraps round to modulo2^64.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \param [in]  sum   accumulate value.
+  \return        the difference of the product of each multiplication, added to the accumulate value.
+  \remark
+                 p1 = val1[15:0]  * val2[31:16]      \n
+                 p2 = val1[31:16] * val2[15:0]       \n
+                 res[63:32][31:0] = p1 - p2 + val3[63:32][31:0]
+ */
+__ALWAYS_STATIC_INLINE uint64_t __SMLSLDX(uint32_t x, uint32_t y, uint64_t sum)
+{
+    return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) -
+                       ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
+                       (((uint64_t)sum))));
+}
+
+/**
+  \brief   32-bit signed multiply with 32-bit truncated accumulator.
+  \details This function enables you to perform a signed 32-bit multiplications, adding the most
+           significant 32 bits of the 64-bit result to a 32-bit accumulate operand.
+  \param [in]    x   first operand for multiplication.
+  \param [in]    y   second operand for multiplication.
+  \param [in]  sum   accumulate value.
+  \return        the product of multiplication (most significant 32 bits) is added to the accumulate value, as a 32-bit integer.
+  \remark
+                 p = val1 * val2      \n
+                 res[31:0] = p[63:32] + val3[31:0]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SMMLA(int32_t x, int32_t y, int32_t sum)
+{
+    return (uint32_t)((int32_t)((int64_t)((int64_t)x * (int64_t)y) >> 32) + sum);
+}
+
+/**
+  \brief   Sum of dual 16-bit signed multiply.
+  \details This function enables you to perform two 16-bit signed multiplications, adding the products together.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \return        the sum of the products of the two 16-bit signed multiplications.
+  \remark
+                 p1 = val1[15:0]  * val2[15:0]      \n
+                 p2 = val1[31:16] * val2[31:16]     \n
+                 res[31:0] = p1 + p2
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SMUAD(uint32_t x, uint32_t y)
+{
+    return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) +
+                       ((((int32_t)x) >> 16) * (((int32_t)y) >> 16))));
+}
+
+/**
+  \brief   Dual 16-bit signed multiply returning difference.
+  \details This function enables you to perform two 16-bit signed multiplications, taking the difference
+           of the products by subtracting the high halfword product from the low halfword product.
+  \param [in]    x   first 16-bit operands for each multiplication.
+  \param [in]    y   second 16-bit operands for each multiplication.
+  \return        the difference of the products of the two 16-bit signed multiplications.
+  \remark
+                 p1 = val1[15:0]  * val2[15:0]      \n
+                 p2 = val1[31:16] * val2[31:16]     \n
+                 res[31:0] = p1 - p2
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SMUSD(uint32_t x, uint32_t y)
+{
+    return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) -
+                       ((((int32_t)x) >> 16) * (((int32_t)y) >> 16))));
+}
+
+/**
+  \brief   Dual extracted 8-bit to 16-bit signed addition.
+  \details This function enables you to extract two 8-bit values from the second operand (at bit positions
+           [7:0] and [23:16]), sign-extend them to 16-bits each, and add the results to the first operand.
+  \param [in]    x   values added to the sign-extended to 16-bit values.
+  \param [in]    y   two 8-bit values to be extracted and sign-extended.
+  \return        the addition of val1 and val2, where the 8-bit values in val2[7:0] and
+                 val2[23:16] have been extracted and sign-extended prior to the addition.
+  \remark
+                 res[15:0]  = val1[15:0] + SignExtended(val2[7:0])      \n
+                 res[31:16] = val1[31:16] + SignExtended(val2[23:16])
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SXTAB16(uint32_t x, uint32_t y)
+{
+    return ((uint32_t)((((((int32_t)y << 24) >> 24) + (((int32_t)x << 16) >> 16)) & (int32_t)0x0000FFFF) |
+                       (((((int32_t)y <<  8) >>  8)  + (((int32_t)x >> 16) << 16)) & (int32_t)0xFFFF0000)));
+}
+
+/**
+  \brief   Extracted 16-bit to 32-bit unsigned addition.
+  \details This function enables you to extract two 8-bit values from one operand, zero-extend
+           them to 16 bits each, and add the results to two 16-bit values from another operand.
+  \param [in]    x   values added to the zero-extended to 16-bit values.
+  \param [in]    y   two 8-bit values to be extracted and zero-extended.
+  \return        the addition of val1 and val2, where the 8-bit values in val2[7:0] and
+                 val2[23:16] have been extracted and zero-extended prior to the addition.
+  \remark
+                 res[15:0]  = ZeroExt(val2[7:0]   to 16 bits) + val1[15:0]      \n
+                 res[31:16] = ZeroExt(val2[31:16] to 16 bits) + val1[31:16]
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UXTAB16(uint32_t x, uint32_t y)
+{
+    return ((uint32_t)(((((y << 24) >> 24) + ((x << 16) >> 16)) & 0x0000FFFF) |
+                       ((((y <<  8) >>  8) + ((x >> 16) << 16)) & 0xFFFF0000)));
+}
+
+/**
+  \brief   Dual extract 8-bits and sign extend each to 16-bits.
+  \details This function enables you to extract two 8-bit values from an operand and sign-extend them to 16 bits each.
+  \param [in]    x   two 8-bit values in val[7:0] and val[23:16] to be sign-extended.
+  \return        the 8-bit values sign-extended to 16-bit values.\n
+                 sign-extended value of val[7:0] in the low halfword of the return value.\n
+                 sign-extended value of val[23:16] in the high halfword of the return value.
+  \remark
+                 res[15:0]  = SignExtended(val[7:0])       \n
+                 res[31:16] = SignExtended(val[23:16])
+ */
+__ALWAYS_STATIC_INLINE uint32_t __SXTB16(uint32_t x)
+{
+    return ((uint32_t)(((((int32_t)x << 24) >> 24) & (int32_t)0x0000FFFF) |
+                       ((((int32_t)x <<  8) >>  8) & (int32_t)0xFFFF0000)));
+}
+
+/**
+  \brief   Dual extract 8-bits and zero-extend to 16-bits.
+  \details This function enables you to extract two 8-bit values from an operand and zero-extend them to 16 bits each.
+  \param [in]    x   two 8-bit values in val[7:0] and val[23:16] to be zero-extended.
+  \return        the 8-bit values sign-extended to 16-bit values.\n
+                 sign-extended value of val[7:0] in the low halfword of the return value.\n
+                 sign-extended value of val[23:16] in the high halfword of the return value.
+  \remark
+                 res[15:0]  = SignExtended(val[7:0])       \n
+                 res[31:16] = SignExtended(val[23:16])
+ */
+__ALWAYS_STATIC_INLINE uint32_t __UXTB16(uint32_t x)
+{
+    return ((uint32_t)((((x << 24) >> 24) & 0x0000FFFF) |
+                       (((x <<  8) >>  8) & 0xFFFF0000)));
+}
+
+#endif /* _CSI_GCC_H_ */

+ 351 - 0
include/arch/xt804/csi_dsp/csky_common_tables.h

@@ -0,0 +1,351 @@
+/******************************************************************************
+ * @file     csky_common_tables.h
+ * @brief    This file has extern declaration for common tables like
+ *           Bitreverse, reciprocal etc which are used across different functions.
+ * @version  V1.0
+ * @date     20. Dec 2016
+ ******************************************************************************/
+/* ---------------------------------------------------------------------------
+ * Copyright (C) 2016 CSKY Limited. All rights reserved.
+ *
+ * Redistribution and use of this software 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 CSKY Ltd. nor the names of CSKY's contributors may
+ *     be used to endorse or promote products derived from this software without
+ *     specific prior written permission of CSKY Ltd.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ * -------------------------------------------------------------------------- */
+
+#ifndef _CSKY_COMMON_TABLES_H
+#define _CSKY_COMMON_TABLES_H
+
+#include "csky_math.h"
+
+extern const uint16_t cskyBitRevTable[1024];
+extern const q15_t cskyRecipTableQ15[64];
+extern const q31_t cskyRecipTableQ31[64];
+extern const float32_t twiddleCoef_16[32];
+extern const float32_t twiddleCoef_32[64];
+extern const float32_t twiddleCoef_64[128];
+extern const float32_t twiddleCoef_128[256];
+extern const float32_t twiddleCoef_256[512];
+extern const float32_t twiddleCoef_512[1024];
+extern const float32_t twiddleCoef_1024[2048];
+extern const float32_t twiddleCoef_2048[4096];
+extern const float32_t twiddleCoef_4096[8192];
+extern const q31_t twiddleCoef_16_q31[24];
+extern const q31_t twiddleCoef_32_q31[48];
+extern const q31_t twiddleCoef_64_q31[96];
+extern const q31_t twiddleCoef_128_q31[192];
+extern const q31_t twiddleCoef_256_q31[384];
+extern const q31_t twiddleCoef_512_q31[768];
+extern const q31_t twiddleCoef_1024_q31[1536];
+extern const q31_t twiddleCoef_2048_q31[3072];
+extern const q31_t twiddleCoef_4096_q31[6144];
+extern const q15_t twiddleCoef_16_q15[24];
+extern const q15_t twiddleCoef_32_q15[48];
+extern const q15_t twiddleCoef_64_q15[96];
+extern const q15_t twiddleCoef_128_q15[192];
+extern const q15_t twiddleCoef_256_q15[384];
+extern const q15_t twiddleCoef_512_q15[768];
+extern const q15_t twiddleCoef_1024_q15[1536];
+extern const q15_t twiddleCoef_2048_q15[3072];
+extern const q15_t twiddleCoef_4096_q15[6144];
+extern const float32_t twiddleCoef_rfft_32[32];
+extern const float32_t twiddleCoef_rfft_64[64];
+extern const float32_t twiddleCoef_rfft_128[128];
+extern const float32_t twiddleCoef_rfft_256[256];
+extern const float32_t twiddleCoef_rfft_512[512];
+extern const float32_t twiddleCoef_rfft_1024[1024];
+extern const float32_t twiddleCoef_rfft_2048[2048];
+extern const float32_t twiddleCoef_rfft_4096[4096];
+extern const float32_t twiddleCoef_rfft_8192[8192];
+
+
+extern const q15_t realCoefAQ15_8192[8192];
+extern const q31_t realCoefAQ31_8192[8192];
+
+/*Tables for RFFT.*/
+extern const q15_t ALIGN4 realCoefAQ15_32[32];
+extern const q15_t ALIGN4 realCoefAQ15_64[64];
+extern const q15_t ALIGN4 realCoefAQ15_128[128];
+extern const q15_t ALIGN4 realCoefAQ15_256[256];
+extern const q15_t ALIGN4 realCoefAQ15_512[512];
+extern const q15_t ALIGN4 realCoefAQ15_1024[1024];
+extern const q15_t ALIGN4 realCoefAQ15_2048[2048];
+extern const q15_t ALIGN4 realCoefAQ15_4096[4096];
+
+extern const q31_t realCoefAQ31_32[32];
+extern const q31_t realCoefAQ31_64[64];
+extern const q31_t realCoefAQ31_128[128];
+extern const q31_t realCoefAQ31_256[256];
+extern const q31_t realCoefAQ31_512[512];
+extern const q31_t realCoefAQ31_1024[1024];
+extern const q31_t realCoefAQ31_2048[2048];
+extern const q31_t realCoefAQ31_4096[4096];
+
+
+extern const float32_t realCoefA[8192];
+extern const float32_t realCoefB[8192];
+
+
+/*Tables for DCT4*/
+extern const q15_t ALIGN4 WeightsQ15_128[128+2];
+extern const q15_t ALIGN4 WeightsQ15_512[512+2];
+extern const q15_t ALIGN4 WeightsQ15_2048[2048+2];
+extern const q15_t ALIGN4 WeightsQ15_8192[8192+2];
+
+extern const q15_t ALIGN4 cos_factorsQ15_128[128];
+extern const q15_t ALIGN4 cos_factorsQ15_512[512];
+extern const q15_t ALIGN4 cos_factorsQ15_2048[2048];
+extern const q15_t ALIGN4 cos_factorsQ15_8192[8192];
+
+
+extern const q31_t WeightsQ31_128[128+2];
+extern const q31_t WeightsQ31_512[512+2];
+extern const q31_t WeightsQ31_2048[2048+2];
+extern const q31_t WeightsQ31_8192[8192+2];
+
+extern const q31_t cos_factorsQ31_128[128];
+extern const q31_t cos_factorsQ31_512[512];
+extern const q31_t cos_factorsQ31_2048[2048];
+extern const q31_t cos_factorsQ31_8192[8192];
+
+
+extern const float32_t Weights_128[128+2];
+extern const float32_t Weights_512[512+2];
+extern const float32_t Weights_2048[2048+2];
+extern const float32_t Weights_8192[8192+2];
+
+extern const float32_t cos_factors_128[128];
+extern const float32_t cos_factors_512[512];
+extern const float32_t cos_factors_2048[2048];
+extern const float32_t cos_factors_8192[8192];
+
+/* floating-point bit reversal tables */
+#define CSKYBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20  )
+#define CSKYBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48  )
+#define CSKYBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56  )
+#define CSKYBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 )
+#define CSKYBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 )
+#define CSKYBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 )
+#define CSKYBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800)
+#define CSKYBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808)
+#define CSKYBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032)
+
+extern const uint16_t cskyBitRevIndexTable16[CSKYBITREVINDEXTABLE__16_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable32[CSKYBITREVINDEXTABLE__32_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable64[CSKYBITREVINDEXTABLE__64_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable128[CSKYBITREVINDEXTABLE_128_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable256[CSKYBITREVINDEXTABLE_256_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable512[CSKYBITREVINDEXTABLE_512_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable1024[CSKYBITREVINDEXTABLE1024_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable2048[CSKYBITREVINDEXTABLE2048_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable4096[CSKYBITREVINDEXTABLE4096_TABLE_LENGTH];
+
+/* fixed-point bit reversal tables */
+#define CSKYBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12  )
+#define CSKYBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24  )
+#define CSKYBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56  )
+#define CSKYBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 )
+#define CSKYBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 )
+#define CSKYBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 )
+#define CSKYBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 )
+#define CSKYBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
+#define CSKYBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
+
+extern const uint16_t cskyBitRevIndexTable_fixed_16[CSKYBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable_fixed_32[CSKYBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable_fixed_64[CSKYBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable_fixed_128[CSKYBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable_fixed_256[CSKYBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable_fixed_512[CSKYBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable_fixed_1024[CSKYBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable_fixed_2048[CSKYBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
+extern const uint16_t cskyBitRevIndexTable_fixed_4096[CSKYBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
+
+/* Tables for Fast Math Sine and Cosine */
+extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
+extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
+extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
+
+/*Table for Fast math pow*/
+extern  const log2_cof1  ui;
+extern  const log2_cof2  vj;
+extern  const exp_cof1 coar;
+extern  const exp_cof2 fine;
+
+/*Table for Fast math pow2*/
+extern  const float64_t exp2_accuratetable[512];
+extern  const float32_t exp2_deltatable[512];
+
+/*Table for Fast math pow2*/
+extern  const mynumber Iu[182];
+extern  const mynumber Iv[362];
+extern  const mynumber Lu[182][2];
+extern  const mynumber Lv[362][2];
+
+/*constant for Fast math*/
+  const static mynumber
+  nZERO	  = {{0, 0x80000000}},	        /* -0.0          */
+  INF     = {{0x00000000, 0x7ff00000}}, /* INF           */
+  nINF    = {{0x00000000, 0xfff00000}}, /* -INF          */
+  sqrt_2  = {{0x667f3bcc, 0x3ff6a09e}}, /* sqrt(2)       */
+  ln2a    = {{0xfefa3800, 0x3fe62e42}}, /* ln(2) 43 bits */
+  ln2b    = {{0x93c76730, 0x3d2ef357}}, /* ln(2)-ln2a    */
+  bigu    = {{0xfffffd2c, 0x4297ffff}}, /* 1.5*2**42 -724*2**-10  */
+  bigv    = {{0xfff8016a, 0x4207ffff}}, /* 1.5*2**33-1+362*2**-19 */
+  t52     = {{0x00000000, 0x43300000}}, /* 2**52         */
+  two52e  = {{0x000003ff, 0x43300000}}, /* 2**52'        */
+  //nan     = {{0x00000000, 0x7ff80000}}, /* NAN           */
+  t256    = {{0, 0x4ff00000}},          /* 2^256         */
+  ln_two1 = {{0xFEFA3800, 0x3FE62E42}}, /* 0.69314718055989033 */
+  ln_two2 = {{0x93C76730, 0x3D2EF357}}, /* 5.4979230187083712e-14*/
+  log2e   = {{0x652B82FE, 0x3FF71547}}, /* 1.4426950408889634  */
+  ep2     = {{0x000004DC, 0x3FE00000}}, /* 0.50000000000013811 */
+  ep3     = {{0x55555A0F, 0x3FC55555}}, /* 0.16666666666670024 */
+  three33 = {{0, 0x42180000}},          /* 25769803776      */
+  three51 = {{0, 0x43380000}};          /* 6755399441055744 */
+
+  const static float64_t
+  p2 = -0.5, p3 =  3.3333333333333333333e-1, p4 = -0.25,
+  q2 = -0.5, q3 = 3.3333333333331404e-01, q4 =  -2.4999999999996436e-01,
+  q5 =  2.0000010500004459e-01, q6 =  -1.6666678916688004e-01,
+  r3 =  3.33333333333333333372884096563030E-01,
+  r4 = -2.50000000000000000213574153875908E-01,
+  r5 =  1.99999999999683593814072199830603E-01,
+  r6 = -1.66666666666065494878165510225378E-01,
+  r7 =  1.42857517857114380606360005067609E-01,
+  r8 = -1.25000449999974370683775964001702E-01,
+  s3 =  0.333251953125000000e0,
+ ss3 =  8.138020833333333333e-05,
+  s4 = -2.500000000000000000e-01,
+  s5 =  1.999999999999960937e-01,
+  s6 = -1.666666666666592447e-01,
+  s7 =  1.428571845238194705e-01;
+//  s8 = -1.250000500000149097e-01;
+
+  const static float64_t huge = 1.0e300, tiny = 1.0e-300;
+  const static float64_t err_0 = 1.000014, err_1 = 0.000016, zero = 0.0;
+  const static q31_t bigint = 0x40862002,
+               badint = 0x40876000, smallint = 0x3C8fffff;
+  const static q31_t hugeint = 0x7fffffff, infint = 0x7ff00000;
+
+static const mynumber
+  /* polynomial I */
+  a2  = {{0x0001aa8f, 0xbfe00000} }, /* -0.500... */
+  a3             = {{0x55588d2e, 0x3fd55555} }, /*  0.333... */
+  /*polynomial II */
+  b0    = {{0x55555555, 0x3fd55555} }, /*  0.333... */
+  b1    = {{0xffffffbb, 0xbfcfffff} }, /* -0.249... */
+  b2    = {{0x9999992f, 0x3fc99999} }, /*  0.199... */
+  b3    = {{0x556503fd, 0xbfc55555} }, /* -0.166... */
+  b4    = {{0x925b3d62, 0x3fc24924} }, /*  0.142... */
+  b5    = {{0x160472fc, 0xbfbffffe} }, /* -0.124... */
+  b6    = {{0x25db58ac, 0x3fbc71c5} }, /*  0.111... */
+  b7    = {{0x11a2a61c, 0xbfb9a4ac} }, /* -0.100... */
+  b8    = {{0x0df2b591, 0x3fb75077} }, /*  0.091... */
+  /*polynomial III */
+  c2    = {{0x00000000, 0xbfe00000} }, /* -1/2      */
+  c3    = {{0x55555555, 0x3fd55555} }, /*  1/3      */
+  c4    = {{0x00000000, 0xbfd00000} }, /* -1/4      */
+  c5    = {{0x9999999a, 0x3fc99999} }, /*  1/5      */
+  /*polynomial IV */
+  d2    = {{0x00000000, 0xbfe00000} }, /* -1/2      */
+  dd2   = {{0x00000000, 0x00000000} }, /* -1/2-d2   */
+  d3    = {{0x55555555, 0x3fd55555} }, /*  1/3      */
+  dd3   = {{0x55555555, 0x3c755555} }, /*  1/3-d3   */
+  d4    = {{0x00000000, 0xbfd00000} }, /* -1/4      */
+  dd4   = {{0x00000000, 0x00000000} }, /* -1/4-d4   */
+  d5    = {{0x9999999a, 0x3fc99999} }, /*  1/5      */
+  dd5   = {{0x9999999a, 0xbc699999} }, /*  1/5-d5   */
+  d6    = {{0x55555555, 0xbfc55555} }, /* -1/6      */
+  dd6   = {{0x55555555, 0xbc655555} }, /* -1/6-d6   */
+  d7    = {{0x92492492, 0x3fc24924} }, /*  1/7      */
+  dd7   = {{0x92492492, 0x3c624924} }, /*  1/7-d7   */
+  d8    = {{0x00000000, 0xbfc00000} }, /* -1/8      */
+  dd8   = {{0x00000000, 0x00000000} }, /* -1/8-d8   */
+  d9    = {{0x1c71c71c, 0x3fbc71c7} }, /*  1/9      */
+  dd9   = {{0x1c71c71c, 0x3c5c71c7} }, /*  1/9-d9   */
+  d10   = {{0x9999999a, 0xbfb99999} }, /* -1/10     */
+  dd10  = {{0x9999999a, 0x3c599999} }, /* -1/10-d10 */
+  d11   = {{0x745d1746, 0x3fb745d1} }, /*  1/11     */
+  d12   = {{0x55555555, 0xbfb55555} }, /* -1/12     */
+  d13   = {{0x13b13b14, 0x3fb3b13b} }, /*  1/13     */
+  d14   = {{0x92492492, 0xbfb24924} }, /* -1/14     */
+  d15   = {{0x11111111, 0x3fb11111} }, /*  1/15     */
+  d16   = {{0x00000000, 0xbfb00000} }, /* -1/16     */
+  d17   = {{0x1e1e1e1e, 0x3fae1e1e} }, /*  1/17     */
+  d18   = {{0x1c71c71c, 0xbfac71c7} }, /* -1/18     */
+  d19   = {{0xbca1af28, 0x3faaf286} }, /*  1/19     */
+  d20   = {{0x9999999a, 0xbfa99999} }, /* -1/20     */
+  /*constants    */
+  h1    = {{0x00000000, 0x3fd2e000} }, /* 151/2**9  */
+  h2    = {{0x00000000, 0x3f669000} }, /* 361/2**17 */
+  delu  = {{0x00000000, 0x3f700000} }, /* 1/2**8    */
+  delv  = {{0x00000000, 0x3ef00000} }, /* 1/2**16   */
+  e1    = {{0x00000000, 0x3bbcc868} }, /* 6.095e-21 */
+  e2    = {{0x00000000, 0x3c1138ce} }, /* 2.334e-19 */
+  e3    = {{0x00000000, 0x3aa1565d} }, /* 2.801e-26 */
+  e4    = {{0x00000000, 0x39809d88} }, /* 1.024e-31 */
+  e[4]  = {{{0x00000000, 0x37da223a} },/* 1.2e-39   */
+          {{0x00000000, 0x35c851c4} }, /* 1.3e-49   */
+          {{0x00000000, 0x2ab85e51} }, /* 6.8e-103  */
+          {{0x00000000, 0x17383827} }},/* 8.1e-197  */
+  two54 = {{0x00000000, 0x43500000} }, /* 2**54     */
+  u03   = {{0xeb851eb8, 0x3f9eb851} }; /* 0.03      */
+
+#define  SQRT_2    sqrt_2.x
+#define  DEL_U     delu.x
+#define  DEL_V     delv.x
+#define  LN2A      ln2a.x
+#define  LN2B      ln2b.x
+#define  E1        e1.x
+#define  E2        e2.x
+#define  E3        e3.x
+#define  E4        e4.x
+#define  U03       u03.x
+#define  HALF      0x1.0p-1     /* 1/2 */
+#define  MHALF     -0x1.0p-1    /* -1/2 */
+
+/*coeffient for log2 funtion*/
+static const float64_t
+  ln2     = 0.69314718055994530942,
+  two54_d = 1.80143985094819840000e+16,   /* 43500000 00000000 */
+  Lg1     = 6.666666666666735130e-01,     /* 3FE55555 55555593 */
+  Lg2     = 3.999999999940941908e-01,     /* 3FD99999 9997FA04 */
+  Lg3     = 2.857142874366239149e-01,     /* 3FD24924 94229359 */
+  Lg4     = 2.222219843214978396e-01,     /* 3FCC71C5 1D8E78AF */
+  Lg5     = 1.818357216161805012e-01,     /* 3FC74664 96CB03DE */
+  Lg6     = 1.531383769920937332e-01,     /* 3FC39A09 D078C69F */
+  Lg7     = 1.479819860511658591e-01;     /* 3FC2F112 DF3E5244 */
+
+/*coeffient for log10 function*/
+static const float64_t
+  ivln10    = 4.34294481903251816668e-01,	/* 0x3FDBCB7B, 0x1526E50E */
+  log10_2hi = 3.01029995663611771306e-01,	/* 0x3FD34413, 0x509F6000 */
+  log10_2lo = 3.69423907715893078616e-13;	/* 0x3D59FEF3, 0x11F12B36 */
+
+/*constant for log10 function*/
+static const float64_t
+  TWO1023  = 8.988465674311579539e+307,
+  TWOM1000 = 9.3326361850321887899e-302;
+
+#endif /*  CSKY_COMMON_TABLES_H */

+ 140 - 0
include/arch/xt804/csi_dsp/csky_const_structs.h

@@ -0,0 +1,140 @@
+/******************************************************************************
+ * @file     csky_const_structs.h
+ * @brief    This file has constant structs that are initialized for
+ *           user convenience.  For example, some can be given as
+ *           arguments to the csky_cfft_f32() function.
+ * @version  V1.0
+ * @date     20. Dec 2016
+ ******************************************************************************/
+/* ---------------------------------------------------------------------------
+ * Copyright (C) 2016 CSKY Limited. All rights reserved.
+ *
+ * Redistribution and use of this software 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 CSKY Ltd. nor the names of CSKY's contributors may
+ *     be used to endorse or promote products derived from this software without
+ *     specific prior written permission of CSKY Ltd.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ * -------------------------------------------------------------------------- */
+
+#ifndef _CSKY_CONST_STRUCTS_H
+#define _CSKY_CONST_STRUCTS_H
+
+#include "csky_math.h"
+#include "csky_common_tables.h"
+
+   extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len16;
+   extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len32;
+   extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len64;
+   extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len128;
+   extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len256;
+   extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len512;
+   extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len1024;
+   extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len2048;
+   extern const csky_cfft_instance_f32 csky_cfft_sR_f32_len4096;
+
+   extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len16;
+   extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len32;
+   extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len64;
+   extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len128;
+   extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len256;
+   extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len512;
+   extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len1024;
+   extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len2048;
+   extern const csky_cfft_instance_q31 csky_cfft_sR_q31_len4096;
+
+   extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len16;
+   extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len32;
+   extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len64;
+   extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len128;
+   extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len256;
+   extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len512;
+   extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len1024;
+   extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len2048;
+   extern const csky_cfft_instance_q15 csky_cfft_sR_q15_len4096;
+
+   extern csky_rfft_instance_q15 csky_rfft_sR_q15_len32;
+   extern csky_rfft_instance_q15 csky_rfft_sR_q15_len64;
+   extern csky_rfft_instance_q15 csky_rfft_sR_q15_len128;
+   extern csky_rfft_instance_q15 csky_rfft_sR_q15_len256;
+   extern csky_rfft_instance_q15 csky_rfft_sR_q15_len512;
+   extern csky_rfft_instance_q15 csky_rfft_sR_q15_len1024;
+   extern csky_rfft_instance_q15 csky_rfft_sR_q15_len2048;
+   extern csky_rfft_instance_q15 csky_rfft_sR_q15_len4096;
+   extern csky_rfft_instance_q15 csky_rfft_sR_q15_len8192;
+
+
+   extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len32;
+   extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len64;
+   extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len128;
+   extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len256;
+   extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len512;
+   extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len1024;
+   extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len2048;
+   extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len4096;
+   extern csky_rfft_instance_q15 csky_inv_rfft_sR_q15_len8192;
+
+
+   extern csky_rfft_instance_q31 csky_rfft_sR_q31_len32;
+   extern csky_rfft_instance_q31 csky_rfft_sR_q31_len64;
+   extern csky_rfft_instance_q31 csky_rfft_sR_q31_len128;
+   extern csky_rfft_instance_q31 csky_rfft_sR_q31_len256;
+   extern csky_rfft_instance_q31 csky_rfft_sR_q31_len512;
+   extern csky_rfft_instance_q31 csky_rfft_sR_q31_len1024;
+   extern csky_rfft_instance_q31 csky_rfft_sR_q31_len2048;
+   extern csky_rfft_instance_q31 csky_rfft_sR_q31_len4096;
+   extern csky_rfft_instance_q31 csky_rfft_sR_q31_len8192;
+
+   extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len32;
+   extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len64;
+   extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len128;
+   extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len256;
+   extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len512;
+   extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len1024;
+   extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len2048;
+   extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len4096;
+   extern csky_rfft_instance_q31 csky_inv_rfft_sR_q31_len8192;
+
+
+   extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len32;
+   extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len64;
+   extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len128;
+   extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len256;
+   extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len512;
+   extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len1024;
+   extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len2048;
+   extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len4096;
+   extern csky_rfft_fast_instance_f32 csky_rfft_sR_f32_len8192;
+
+   extern csky_dct4_instance_q15 csky_dct4_sR_q15_len128;
+   extern csky_dct4_instance_q15 csky_dct4_sR_q15_len512;
+   extern csky_dct4_instance_q15 csky_dct4_sR_q15_len2048;
+   extern csky_dct4_instance_q15 csky_dct4_sR_q15_len8192;
+
+   extern csky_dct4_instance_q31 csky_dct4_sR_q31_len128;
+   extern csky_dct4_instance_q31 csky_dct4_sR_q31_len512;
+   extern csky_dct4_instance_q31 csky_dct4_sR_q31_len2048;
+   extern csky_dct4_instance_q31 csky_dct4_sR_q31_len8192;
+
+   extern csky_dct4_instance_f32 csky_dct4_sR_f32_len128;
+   extern csky_dct4_instance_f32 csky_dct4_sR_f32_len512;
+   extern csky_dct4_instance_f32 csky_dct4_sR_f32_len2048;
+   extern csky_dct4_instance_f32 csky_dct4_sR_f32_len8192;
+#endif

+ 4783 - 0
include/arch/xt804/csi_dsp/csky_math.h

@@ -0,0 +1,4783 @@
+/******************************************************************************
+ * @file     csky_math.h
+ * @brief    Public header file for CSI DSP Library.
+ * @version  V1.0
+ * @date     20. Dec 2016
+ ******************************************************************************/
+/* ---------------------------------------------------------------------------
+ * Copyright (C) 2016 CSKY Limited. All rights reserved.
+ *
+ * Redistribution and use of this software 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 CSKY Ltd. nor the names of CSKY's contributors may
+ *     be used to endorse or promote products derived from this software without
+ *     specific prior written permission of CSKY Ltd.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ * -------------------------------------------------------------------------- */
+
+
+/**
+ * @defgroup groupMath Basic Math Functions
+ */
+
+/**
+ * @defgroup groupFastMath Fast Math Functions
+ * This set of functions provides a fast approximation to sine, cosine, and square root.
+ * As compared to most of the other functions in the CSI math library, the fast math functions
+ * operate on individual values and not arrays.
+ * There are separate functions for Q15, Q31, and floating-point data.
+ *
+ */
+
+/**
+ * @defgroup groupCmplxMath Complex Math Functions
+ * This set of functions operates on complex data vectors.
+ * The data in the complex arrays is stored in an interleaved fashion
+ * (real, imag, real, imag, ...).
+ * In the API functions, the number of samples in a complex array refers
+ * to the number of complex values; the array contains twice this number of
+ * real values.
+ */
+
+/**
+ * @defgroup groupFilters Filtering Functions
+ */
+
+/**
+ * @defgroup groupMatrix Matrix Functions
+ *
+ * This set of functions provides basic matrix math operations.
+ * The functions operate on matrix data structures.  For example,
+ * the type
+ * definition for the floating-point matrix structure is shown
+ * below:
+ * <pre>
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } csky_matrix_instance_f32;
+ * </pre>
+ * There are similar definitions for Q15 and Q31 data types.
+ *
+ * The structure specifies the size of the matrix and then points to
+ * an array of data.  The array is of size <code>numRows X numCols</code>
+ * and the values are arranged in row order.  That is, the
+ * matrix element (i, j) is stored at:
+ * <pre>
+ *     pData[i*numCols + j]
+ * </pre>
+ *
+ * \par Init Functions
+ * There is an associated initialization function for each type of matrix
+ * data structure.
+ * The initialization function sets the values of the internal structure fields.
+ * Refer to the function <code>csky_mat_init_f32()</code>, <code>csky_mat_init_q31()</code>
+ * and <code>csky_mat_init_q15()</code> for floating-point, Q31 and Q15 types,  respectively.
+ *
+ * \par
+ * Use of the initialization function is optional. However, if initialization function is used
+ * then the instance structure cannot be placed into a const data section.
+ * To place the instance structure in a const data
+ * section, manually initialize the data structure.  For example:
+ * <pre>
+ * <code>csky_matrix_instance_f32 S = {nRows, nColumns, pData};</code>
+ * <code>csky_matrix_instance_q31 S = {nRows, nColumns, pData};</code>
+ * <code>csky_matrix_instance_q15 S = {nRows, nColumns, pData};</code>
+ * </pre>
+ * where <code>nRows</code> specifies the number of rows, <code>nColumns</code>
+ * specifies the number of columns, and <code>pData</code> points to the
+ * data array.
+ *
+ * \par Size Checking
+ * By default all of the matrix functions perform size checking on the input and
+ * output matrices.  For example, the matrix addition function verifies that the
+ * two input matrices and the output matrix all have the same number of rows and
+ * columns.  If the size check fails the functions return:
+ * <pre>
+ *     CSKY_MATH_SIZE_MISMATCH
+ * </pre>
+ * Otherwise the functions return
+ * <pre>
+ *     CSKY_MATH_SUCCESS
+ * </pre>
+ * There is some overhead associated with this matrix size checking.
+ * The matrix size checking is enabled via the \#define
+ * <pre>
+ *     CSKY_MATH_MATRIX_CHECK
+ * </pre>
+ * within the library project settings.  By default this macro is defined
+ * and size checking is enabled.  By changing the project settings and
+ * undefining this macro size checking is eliminated and the functions
+ * run a bit faster.  With size checking disabled the functions always
+ * return <code>CSKY_MATH_SUCCESS</code>.
+ */
+
+/**
+ * @defgroup groupTransforms Transform Functions
+ */
+
+/**
+ * @defgroup groupController Controller Functions
+ */
+
+/**
+ * @defgroup groupStats Statistics Functions
+ */
+/**
+ * @defgroup groupSupport Support Functions
+ */
+
+/**
+ * @defgroup groupInterpolation Interpolation Functions
+ * These functions perform 1- and 2-dimensional interpolation of data.
+ * Linear interpolation is used for 1-dimensional data and
+ * bilinear interpolation is used for 2-dimensional data.
+ */
+
+
+/**
+ * @defgroup groupYunvoice Yunvoice Functions
+ * These functions are designed for Yunvoice project, which are modified
+ * according to the CEVA DSP functions. So, one can porting the software
+ * from CEVA to CSKY straightforwardly.
+ */
+
+/**
+ * @defgroup groupExamples Examples
+ */
+
+
+#ifndef _CSKY_MATH_H
+#define _CSKY_MATH_H
+
+#define __CSI_GENERIC         /* disable NVIC and Systick functions */
+
+#include "csi_core.h"
+
+#include <float.h>
+#undef  __CSI_GENERIC         /* enable NVIC and Systick functions */
+#include "string.h"
+#include "math.h"
+#ifdef   __cplusplus
+extern "C"
+{
+#endif
+
+
+  /**
+   * @brief Macros required for reciprocal calculation in Normalized LMS
+   */
+
+#define DELTA_Q31          (0x100)
+#define DELTA_Q15          0x5
+#define INDEX_MASK         0x0000003F
+#ifndef PI
+#define PI                 3.14159265358979f
+#endif
+
+  /**
+   * @brief Macros required for SINE and COSINE Fast math approximations
+   */
+
+#define FAST_MATH_TABLE_SIZE  512
+#define FAST_MATH_Q31_SHIFT   (32 - 10)
+#define FAST_MATH_Q15_SHIFT   (16 - 10)
+#define CONTROLLER_Q31_SHIFT  (32 - 9)
+#define TABLE_SIZE  256
+#define TABLE_SPACING_Q31     0x400000
+#define TABLE_SPACING_Q15     0x80
+
+  /**
+   * @brief Macros required for SINE and COSINE Controller functions
+   */
+  /* 1.31(q31) Fixed value of 2/360 */
+  /* -1 to +1 is divided into 360 values so total spacing is (2/360) */
+#define INPUT_SPACING         0xB60B61
+
+  /**
+   * @brief Macro for Unaligned Support
+   */
+#ifndef UNALIGNED_SUPPORT_DISABLE
+    #define ALIGN4
+#else
+    #define ALIGN4 __attribute__((aligned(4)))
+#endif   /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+
+  /**
+   * @brief Macro for log , pow and related fast functions.
+   */
+#define ABS(x) (((x) > 0)   ? (x) : (-x))
+#define max(x) (((y) > (x)) ? (y) : (x))
+#define min(x) (((y) < (x)) ? (y) : (x))
+#define CN                     124217729.0
+#define HIGH_HALF              1
+#define LOW_HALF               0
+
+/* Exact addition of two single-length floating point numbers.         */
+/* The macro produces a double-length number (z,zz) that satisfies     */
+/* z+zz = x+y exactly.                                                 */
+
+#define  EADD(x,y,z,zz)                            \
+        z=(x)+(y);  zz=(ABS(x)>ABS(y)) ? (((x)-(z))+(y)) : (((y)-(z))+(x));
+
+/* Exact multiplication of two single-length floating point numbers,   */
+/*The macro produces a double-length number (z,zz) that                */
+/* satisfies z+zz = x*y exactly. p,hx,tx,hy,ty are temporary           */
+/* storage variables of type double.                                   */
+
+# define  EMULV(x,y,z,zz,p,hx,tx,hy,ty)            \
+        p=CN*(x);  hx=((x)-p)+p;  tx=(x)-hx;       \
+        p=CN*(y);  hy=((y)-p)+p;  ty=(y)-hy;       \
+        z=(x)*(y); zz=(((hx*hy-z)+hx*ty)+tx*hy)+tx*ty;
+/* Exact multiplication of two single-length floating point numbers.         */
+/* The macro produces a nearly double-length number (z,zz) (see Dekker)      */
+/* that satisfies z+zz = x*y exactly. p,hx,tx,hy,ty,q are temporary          */
+/* storage variables of type double.                                         */
+
+# define  MUL12(x,y,z,zz,p,hx,tx,hy,ty,q)          \
+        p=CN*(x);  hx=((x)-p)+p;  tx=(x)-hx;       \
+        p=CN*(y);  hy=((y)-p)+p;  ty=(y)-hy;       \
+        p=hx*hy;  q=hx*ty+tx*hy; z=p+q;  zz=((p-z)+q)+tx*ty;
+
+/* Double-length addition, Dekker. The macro produces a double-length   */
+/* number (z,zz) which satisfies approximately   z+zz = x+xx + y+yy.    */
+/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy)       */
+/* are assumed to be double-length numbers. r,s are temporary           */
+/* storage variables of type double.                                    */
+
+#define  ADD2(x,xx,y,yy,z,zz,r,s)                  \
+        r=(x)+(y);  s=(ABS(x)>ABS(y)) ?            \
+                (((((x)-r)+(y))+(yy))+(xx)) :      \
+                (((((y)-r)+(x))+(xx))+(yy));       \
+        z=r+s;  zz=(r-z)+s;
+
+
+/* Double-length subtraction, Dekker. The macro produces a double-length  */
+/* number (z,zz) which satisfies approximately   z+zz = x+xx - (y+yy).    */
+/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy)         */
+/* are assumed to be double-length numbers. r,s are temporary             */
+/* storage variables of type double.                                      */
+
+#define  SUB2(x,xx,y,yy,z,zz,r,s)                  \
+        r=(x)-(y);  s=(ABS(x)>ABS(y)) ?            \
+                (((((x)-r)-(y))-(yy))+(xx)) :      \
+                ((((x)-((y)+r))+(xx))-(yy));       \
+        z=r+s;  zz=(r-z)+s;
+
+
+/* Double-length multiplication, Dekker. The macro produces a double-length  */
+/* number (z,zz) which satisfies approximately   z+zz = (x+xx)*(y+yy).       */
+/* An error bound: abs((x+xx)*(y+yy))*1.24e-31. (x,xx), (y,yy)               */
+/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc are         */
+/* temporary storage variables of type double.                               */
+
+#define  MUL2(x,xx,y,yy,z,zz,p,hx,tx,hy,ty,q,c,cc) \
+        MUL12(x,y,c,cc,p,hx,tx,hy,ty,q)            \
+        cc=((x)*(yy)+(xx)*(y))+cc;   z=c+cc;   zz=(c-z)+cc;
+
+__STATIC_INLINE int32_t __SSAT_31(int32_t x)
+{
+    int32_t res = x;
+    if (x > 0x3fffffff) {
+       res = 0x3fffffff;
+    } else if (x < -1073741824) {
+       res = -1073741824;
+    }
+
+    return res;
+}
+
+__STATIC_INLINE int32_t __SSAT_16(int32_t x)
+{
+    int32_t res = x;
+    if (x > 0x7fff) {
+       res = 0x7fff;
+    } else if (x < -32768) {
+       res = -32768;
+    }
+
+    return res;
+}
+
+__STATIC_INLINE int32_t __SSAT_8(int32_t x)
+{
+    int32_t res = x;
+    if (x > 0x7f) {
+       res = 0x7f;
+    } else if (x < -128) {
+       res = -128;
+    }
+
+    return res;
+}
+
+#ifdef CSKY_SIMD
+/* SMMLAR */
+__STATIC_INLINE int32_t multAcc_32x32_keep32_R(int32_t a, int32_t x, int32_t y)
+{
+    __ASM volatile("mula.s32.rhs %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y) : "0" (a), "1" (x), "2" (y));
+    return a;
+}
+
+/* SMMLSR */
+__STATIC_INLINE int32_t multSub_32x32_keep32_R(int32_t a, int32_t x, int32_t y)
+{
+    __ASM volatile("muls.s32.rhs %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y));
+    return a;
+}
+
+/* SMMULR */
+__STATIC_INLINE int32_t mult_32x32_keep32_R(int32_t x, int32_t y)
+{
+    int32_t a;
+    __ASM volatile("mul.s32.rh %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y));
+    return a;
+}
+
+/* SMMLA */
+__STATIC_INLINE int32_t multAcc_32x32_keep32(int32_t a, int32_t x, int32_t y)
+{
+    __ASM volatile("mula.s32.hs %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y));
+    return a;
+}
+
+/* SMMLS */
+__STATIC_INLINE int32_t multSub_32x32_keep32(int32_t a, int32_t x, int32_t y)
+{
+    __ASM volatile("muls.s32.hs %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y));
+    return a;
+}
+
+/* SMMUL */
+__STATIC_INLINE int32_t mult_32x32_keep32(int32_t x, int32_t y)
+{
+    int32_t a;
+    __ASM volatile("mul.s32.h %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y));
+    return a;
+}
+
+__STATIC_INLINE int32_t multAcc_16x16_keep32(int32_t a, int16_t x, int16_t y)
+{
+    __ASM volatile("mulall.s16 %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y));
+    return a;
+}
+
+__STATIC_INLINE int64_t multAcc_16x16_keep64(int64_t a, int16_t x, int16_t y)
+{
+    __ASM volatile("mulall.s16.e %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y));
+    return a;
+}
+
+__STATIC_INLINE int64_t mult_32x32_keep64(int32_t x, int32_t y)
+{
+    int64_t a;
+    __ASM volatile("mul.s32 %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y));
+    return a;
+}
+
+__STATIC_INLINE int64_t multAcc_32x32_keep64(int64_t a, int32_t x, int32_t y)
+{
+    __ASM volatile("mula.s32 %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "0" (a), "1" (x), "2" (y));
+    return a;
+}
+
+__STATIC_INLINE int32_t mult_32x32_dext_31(int32_t x, int32_t y)
+{
+    int64_t tmp1;
+    int32_t tmp2;
+    __ASM volatile("mul.s32 %0, %1, %2\n\t"
+                   "dexti %3, %0, %R0, 31"
+                   :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y));
+    return tmp2;
+}
+
+__STATIC_INLINE int32_t mult_32x32_dext_30(int32_t x, int32_t y)
+{
+    int64_t tmp1;
+    int32_t tmp2;
+    __ASM volatile("mul.s32 %0, %1, %2\n\t"
+                   "dexti %3, %0, %R0, 30"
+                   :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y));
+    return tmp2;
+}
+
+__STATIC_INLINE int32_t mult_32x32_dext_4(int32_t x, int32_t y)
+{
+    int64_t tmp1;
+    int32_t tmp2;
+    __ASM volatile("mul.s32 %0, %1, %2\n\t"
+                   "dexti %3, %0, %R0, 4"
+                   :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y));
+    return tmp2;
+}
+
+__STATIC_INLINE int32_t mult_32x32_dext_33(int32_t x, int32_t y)
+{
+    int64_t tmp1;
+    int32_t tmp2;
+    __ASM volatile("mul.s32 %0, %1, %2\n\t"
+                   "asri %3, %R0, 1"
+                   :"=r" (tmp1), "=r" (x), "=r" (y), "=r" (tmp2): "1" (x), "2" (y));
+    return tmp2;
+}
+
+__STATIC_INLINE int32_t dext_31(int64_t x)
+{
+    int32_t tmp1;
+    __ASM volatile(
+                   "dexti %0, %1, %R1, 31"
+                   :"=r" (tmp1), "=r" (x) : "1" (x));
+    return tmp1;
+}
+
+__STATIC_INLINE int32_t mult_l16xl16_keep32(int32_t x, int32_t y)
+{
+    int32_t a;
+    __ASM volatile("mulll.s16 %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y));
+    return a;
+}
+
+__STATIC_INLINE int32_t mult_h16xl16_keep32(int32_t x, int32_t y)
+{
+    int32_t a;
+    __ASM volatile("mulhl.s16 %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y));
+    return a;
+}
+
+__STATIC_INLINE int32_t mult_h16xh16_keep32(int32_t x, int32_t y)
+{
+    int32_t a;
+    __ASM volatile("mulhh.s16 %0, %1, %2\n\t"
+                   :"=r" (a), "=r" (x), "=r" (y): "1" (x), "2" (y));
+    return a;
+}
+
+#endif
+
+
+  /**
+   * @brief Error status returned by some functions in the library.
+   */
+
+  typedef enum
+  {
+    CSKY_MATH_SUCCESS = 0,                /**< No error */
+    CSKY_MATH_ARGUMENT_ERROR = -1,        /**< One or more arguments are incorrect */
+    CSKY_MATH_LENGTH_ERROR = -2,          /**< Length of data buffer is incorrect */
+    CSKY_MATH_SIZE_MISMATCH = -3,         /**< Size of matrices is not compatible with the operation. */
+    CSKY_MATH_NANINF = -4,                /**< Not-a-number (NaN) or infinity is generated */
+    CSKY_MATH_SINGULAR = -5,              /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */
+    CSKY_MATH_TEST_FAILURE = -6           /**< Test Failed  */
+  } csky_status;
+
+  /**
+   * @brief 8-bit fractional data type in 1.7 format.
+   */
+  typedef int8_t q7_t;
+
+  /**
+   * @brief 16-bit fractional data type in 1.15 format.
+   */
+  typedef int16_t q15_t;
+
+  /**
+   * @brief 32-bit fractional data type in 1.31 format.
+   */
+  typedef int32_t q31_t;
+
+  /**
+   * @brief 64-bit fractional data type in 1.63 format.
+   */
+  typedef int64_t q63_t;
+
+  /**
+   * @brief 32-bit floating-point type definition.
+   */
+  typedef float float32_t;
+
+  /**
+   * @brief 64-bit floating-point type definition.
+   */
+  typedef double float64_t;
+
+   /**
+   * @brief 32-bit fractional complex data type in 1.31 format.
+   */
+  typedef struct
+  {
+    q31_t re;
+    q31_t im;
+  } cq31_t;
+  /**
+   * @brief 16-bit fractional complex data type in 1.15 format.
+   */
+  typedef struct
+  {
+    q15_t re;
+    q15_t im;
+  } cq15_t;
+   /**
+   * @brief definition to read/write two 16 bit values.
+   */
+  #define __SIMD32_TYPE int32_t
+  #define CSI_UNUSED __attribute__((unused))
+
+#define __SIMD32(addr)        (*(__SIMD32_TYPE **) & (addr))
+#define __SIMD32_CONST(addr)  ((__SIMD32_TYPE *)(addr))
+#define _SIMD32_OFFSET(addr)  (*(__SIMD32_TYPE *)  (addr))
+#define __SIMD64(addr)        (*(int64_t **) & (addr))
+
+#if defined (CSKY_MATH_NO_SIMD)
+  /**
+   * @brief definition to pack two 16 bit values.
+   */
+#define __PKHBT(ARG1, ARG2, ARG3)      ( (((int32_t)(ARG1) <<  0) & (int32_t)0x0000FFFF) | \
+                                         (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000)  )
+#define __PKHTB(ARG1, ARG2, ARG3)      ( (((int32_t)(ARG1) <<  0) & (int32_t)0xFFFF0000) | \
+                                         (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF)  )
+
+#endif
+
+
+   /**
+   * @brief definition to pack four 8 bit values.
+   */
+#ifndef CSKY_MATH_BIG_ENDIAN
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) <<  0) & (int32_t)0x000000FF) | \
+                                (((int32_t)(v1) <<  8) & (int32_t)0x0000FF00) | \
+                                (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \
+                                (((int32_t)(v3) << 24) & (int32_t)0xFF000000)  )
+#else
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) <<  0) & (int32_t)0x000000FF) | \
+                                (((int32_t)(v2) <<  8) & (int32_t)0x0000FF00) | \
+                                (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \
+                                (((int32_t)(v0) << 24) & (int32_t)0xFF000000)  )
+
+#endif
+
+  /**
+   * @brief Clips Q63 to Q31 values.
+   */
+  static __INLINE q31_t clip_q63_to_q31(
+  q63_t x)
+  {
+    return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+      ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x;
+  }
+
+  /**
+   * @brief Instance structure for the Q7 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;        /**< number of filter coefficients in the filter. */
+    q7_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q7_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+  } csky_fir_instance_q7;
+
+  /**
+   * @brief Instance structure for the Q15 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;         /**< number of filter coefficients in the filter. */
+    q15_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+  } csky_fir_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;         /**< number of filter coefficients in the filter. */
+    q31_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps. */
+  } csky_fir_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of filter coefficients in the filter. */
+    float32_t *pState;    /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;   /**< points to the coefficient array. The array is of length numTaps. */
+  } csky_fir_instance_f32;
+
+  void csky_fir_q7(
+  const csky_fir_instance_q7 * S,
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fir_init_q7(
+  csky_fir_instance_q7 * S,
+  uint16_t numTaps,
+  q7_t * pCoeffs,
+  q7_t * pState,
+  uint32_t blockSize);
+
+  void csky_fir_q15(
+  const csky_fir_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fir_fast_q15(
+  const csky_fir_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  csky_status csky_fir_init_q15(
+  csky_fir_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+  void csky_fir_q31(
+  const csky_fir_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fir_fast_q31(
+  const csky_fir_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fir_init_q31(
+  csky_fir_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+  void csky_fir_f32(
+  const csky_fir_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fir_init_f32(
+  csky_fir_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    int8_t numStages;        /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q15_t *pState;           /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    q15_t *pCoeffs;          /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+    int8_t postShift;        /**< Additional shift, in bits, applied to each output sample. */
+  } csky_biquad_casd_df1_inst_q15;
+
+  /**
+   * @brief Instance structure for the Q31 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint32_t numStages;      /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q31_t *pState;           /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    q31_t *pCoeffs;          /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+    uint8_t postShift;       /**< Additional shift, in bits, applied to each output sample. */
+  } csky_biquad_casd_df1_inst_q31;
+
+ /**
+   * @brief Instance structure for the Q31 Biquad cascade filter.
+   */
+
+  /**
+   * @brief Instance structure for the floating-point Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint32_t numStages;      /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;       /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    float32_t *pCoeffs;      /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+  } csky_biquad_casd_df1_inst_f32;
+
+  void csky_biquad_cascade_df1_q15(
+  const csky_biquad_casd_df1_inst_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_biquad_cascade_df1_init_q15(
+  csky_biquad_casd_df1_inst_q15 * S,
+  uint8_t numStages,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  int8_t postShift);
+
+  void csky_biquad_cascade_df1_fast_q15(
+  const csky_biquad_casd_df1_inst_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_biquad_cascade_df1_q31(
+  const csky_biquad_casd_df1_inst_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_biquad_cascade_df1_fast_q31(
+  const csky_biquad_casd_df1_inst_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_biquad_cascade_df1_init_q31(
+  csky_biquad_casd_df1_inst_q31 * S,
+  uint8_t numStages,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  int8_t postShift);
+
+  void csky_biquad_cascade_df1_f32(
+  const csky_biquad_casd_df1_inst_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_biquad_cascade_df1_init_f32(
+  csky_biquad_casd_df1_inst_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  /**
+   * @brief Instance structure for the floating-point matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    float32_t *pData;     /**< points to the data of the matrix. */
+  } csky_matrix_instance_f32;
+
+
+  /**
+   * @brief Instance structure for the floating-point matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    float64_t *pData;     /**< points to the data of the matrix. */
+  } csky_matrix_instance_f64;
+
+  /**
+   * @brief Instance structure for the Q15 matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    q15_t *pData;         /**< points to the data of the matrix. */
+  } csky_matrix_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    q31_t *pData;         /**< points to the data of the matrix. */
+  } csky_matrix_instance_q31;
+
+  csky_status csky_mat_add_f32(
+  const csky_matrix_instance_f32 * pSrcA,
+  const csky_matrix_instance_f32 * pSrcB,
+  csky_matrix_instance_f32 * pDst);
+
+  csky_status csky_mat_add_q15(
+  const csky_matrix_instance_q15 * pSrcA,
+  const csky_matrix_instance_q15 * pSrcB,
+  csky_matrix_instance_q15 * pDst);
+
+  csky_status csky_mat_add_q31(
+  const csky_matrix_instance_q31 * pSrcA,
+  const csky_matrix_instance_q31 * pSrcB,
+  csky_matrix_instance_q31 * pDst);
+
+  csky_status csky_mat_cmplx_mult_f32(
+  const csky_matrix_instance_f32 * pSrcA,
+  const csky_matrix_instance_f32 * pSrcB,
+  csky_matrix_instance_f32 * pDst);
+
+  csky_status csky_mat_cmplx_mult_q15(
+  const csky_matrix_instance_q15 * pSrcA,
+  const csky_matrix_instance_q15 * pSrcB,
+  csky_matrix_instance_q15 * pDst,
+  q15_t * pScratch);
+
+  csky_status csky_mat_cmplx_mult_q31(
+  const csky_matrix_instance_q31 * pSrcA,
+  const csky_matrix_instance_q31 * pSrcB,
+  csky_matrix_instance_q31 * pDst);
+
+  csky_status csky_mat_trans_f32(
+  const csky_matrix_instance_f32 * pSrc,
+  csky_matrix_instance_f32 * pDst);
+
+  csky_status csky_mat_trans_q15(
+  const csky_matrix_instance_q15 * pSrc,
+  csky_matrix_instance_q15 * pDst);
+
+  csky_status csky_mat_trans_q31(
+  const csky_matrix_instance_q31 * pSrc,
+  csky_matrix_instance_q31 * pDst);
+
+  csky_status csky_mat_mult_f32(
+  const csky_matrix_instance_f32 * pSrcA,
+  const csky_matrix_instance_f32 * pSrcB,
+  csky_matrix_instance_f32 * pDst);
+
+  csky_status csky_mat_mult_q15(
+  const csky_matrix_instance_q15 * pSrcA,
+  const csky_matrix_instance_q15 * pSrcB,
+  csky_matrix_instance_q15 * pDst,
+  q15_t * pState);
+
+  csky_status csky_mat_mult_fast_q15(
+  const csky_matrix_instance_q15 * pSrcA,
+  const csky_matrix_instance_q15 * pSrcB,
+  csky_matrix_instance_q15 * pDst,
+  q15_t * pState);
+
+  csky_status csky_mat_mult_q31(
+  const csky_matrix_instance_q31 * pSrcA,
+  const csky_matrix_instance_q31 * pSrcB,
+  csky_matrix_instance_q31 * pDst);
+
+  csky_status csky_mat_mult_fast_q31(
+  const csky_matrix_instance_q31 * pSrcA,
+  const csky_matrix_instance_q31 * pSrcB,
+  csky_matrix_instance_q31 * pDst);
+
+  csky_status csky_mat_sub_f32(
+  const csky_matrix_instance_f32 * pSrcA,
+  const csky_matrix_instance_f32 * pSrcB,
+  csky_matrix_instance_f32 * pDst);
+
+  csky_status csky_mat_sub_q15(
+  const csky_matrix_instance_q15 * pSrcA,
+  const csky_matrix_instance_q15 * pSrcB,
+  csky_matrix_instance_q15 * pDst);
+
+  csky_status csky_mat_sub_q31(
+  const csky_matrix_instance_q31 * pSrcA,
+  const csky_matrix_instance_q31 * pSrcB,
+  csky_matrix_instance_q31 * pDst);
+
+  csky_status csky_mat_scale_f32(
+  const csky_matrix_instance_f32 * pSrc,
+  float32_t scale,
+  csky_matrix_instance_f32 * pDst);
+
+  csky_status csky_mat_scale_q15(
+  const csky_matrix_instance_q15 * pSrc,
+  q15_t scaleFract,
+  int32_t shift,
+  csky_matrix_instance_q15 * pDst);
+
+  csky_status csky_mat_scale_q31(
+  const csky_matrix_instance_q31 * pSrc,
+  q31_t scaleFract,
+  int32_t shift,
+  csky_matrix_instance_q31 * pDst);
+
+  void csky_mat_init_q31(
+  csky_matrix_instance_q31 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  q31_t * pData);
+
+  void csky_mat_init_q15(
+  csky_matrix_instance_q15 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  q15_t * pData);
+
+  void csky_mat_init_f32(
+  csky_matrix_instance_f32 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  float32_t * pData);
+
+  /**
+   * @brief Instance structure for the Q15 PID Control.
+   */
+  typedef struct
+  {
+    q15_t A0;           /**< The derived gain, A0 = Kp + Ki + Kd . */
+    q15_t A1;
+    q15_t A2;
+    q15_t state[3];     /**< The state array of length 3. */
+    q15_t Kp;           /**< The proportional gain. */
+    q15_t Ki;           /**< The integral gain. */
+    q15_t Kd;           /**< The derivative gain. */
+  } csky_pid_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 PID Control.
+   */
+  typedef struct
+  {
+    q31_t A0;            /**< The derived gain, A0 = Kp + Ki + Kd . */
+    q31_t A1;            /**< The derived gain, A1 = -Kp - 2Kd. */
+    q31_t A2;            /**< The derived gain, A2 = Kd . */
+    q31_t state[3];      /**< The state array of length 3. */
+    q31_t Kp;            /**< The proportional gain. */
+    q31_t Ki;            /**< The integral gain. */
+    q31_t Kd;            /**< The derivative gain. */
+  } csky_pid_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point PID Control.
+   */
+  typedef struct
+  {
+    float32_t A0;          /**< The derived gain, A0 = Kp + Ki + Kd . */
+    float32_t A1;          /**< The derived gain, A1 = -Kp - 2Kd. */
+    float32_t A2;          /**< The derived gain, A2 = Kd . */
+    float32_t state[3];    /**< The state array of length 3. */
+    float32_t Kp;          /**< The proportional gain. */
+    float32_t Ki;          /**< The integral gain. */
+    float32_t Kd;          /**< The derivative gain. */
+  } csky_pid_instance_f32;
+
+  void csky_pid_init_f32(
+  csky_pid_instance_f32 * S,
+  int32_t resetStateFlag);
+
+  void csky_pid_reset_f32(
+  csky_pid_instance_f32 * S);
+
+  void csky_pid_init_q31(
+  csky_pid_instance_q31 * S,
+  int32_t resetStateFlag);
+
+  void csky_pid_reset_q31(
+  csky_pid_instance_q31 * S);
+
+  void csky_pid_init_q15(
+  csky_pid_instance_q15 * S,
+  int32_t resetStateFlag);
+
+  void csky_pid_reset_q15(
+  csky_pid_instance_q15 * S);
+
+
+  /**
+   * @brief Instance structure for the floating-point Linear Interpolate function.
+   */
+  typedef struct
+  {
+    uint32_t nValues;           /**< nValues */
+    float32_t x1;               /**< x1 */
+    float32_t xSpacing;         /**< xSpacing */
+    float32_t *pYData;          /**< pointer to the table of Y values */
+  } csky_linear_interp_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    float32_t *pData;   /**< points to the data table. */
+  } csky_bilinear_interp_instance_f32;
+
+   /**
+   * @brief Instance structure for the Q31 bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q31_t *pData;       /**< points to the data table. */
+  } csky_bilinear_interp_instance_q31;
+
+   /**
+   * @brief Instance structure for the Q15 bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q15_t *pData;       /**< points to the data table. */
+  } csky_bilinear_interp_instance_q15;
+
+   /**
+   * @brief Instance structure for the Q15 bilinear interpolation function.
+   */
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q7_t *pData;        /**< points to the data table. */
+  } csky_bilinear_interp_instance_q7;
+
+  void csky_mult_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_mult_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_mult_rnd_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_mult_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_mult_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q15_t *pTwiddle;                 /**< points to the Sin twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } csky_cfft_radix2_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q15 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q15_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } csky_cfft_radix4_instance_q15;
+
+  /**
+   * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q31_t *pTwiddle;                 /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } csky_cfft_radix2_instance_q31;
+
+  /**
+   * @brief Instance structure for the Q31 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q31_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } csky_cfft_radix4_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    uint8_t ifftFlag;                  /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;            /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    float32_t *pTwiddle;               /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;            /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;         /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;             /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+    float32_t onebyfftLen;             /**< value of 1/fftLen. */
+  } csky_cfft_radix2_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    uint8_t ifftFlag;                  /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;            /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    float32_t *pTwiddle;               /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;            /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;         /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;             /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+    float32_t onebyfftLen;             /**< value of 1/fftLen. */
+  } csky_cfft_radix4_instance_f32;
+
+  /**
+   * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const q15_t *pTwiddle;             /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } csky_cfft_instance_q15;
+
+void csky_cfft_q15(
+    const csky_cfft_instance_q15 * S,
+    q15_t * p1,
+    uint8_t ifftFlag,
+    uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const q31_t *pTwiddle;             /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } csky_cfft_instance_q31;
+
+void csky_cfft_q31(
+    const csky_cfft_instance_q31 * S,
+    q31_t * p1,
+    uint8_t ifftFlag,
+    uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const float32_t *pTwiddle;         /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } csky_cfft_instance_f32;
+
+  void csky_cfft_f32(
+  const csky_cfft_instance_f32 * S,
+  float32_t * p1,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the Q15 RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                      /**< length of the real FFT. */
+    uint8_t ifftFlagR;                        /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                  /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;               /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    q15_t *pTwiddleAReal;                     /**< points to the real twiddle factor table. */
+    const csky_cfft_instance_q15 *pCfft;      /**< points to the complex FFT instance. */
+  } csky_rfft_instance_q15;
+
+  csky_status csky_rfft_init_q15(
+  csky_rfft_instance_q15 * S,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void csky_rfft_q15(
+  const csky_rfft_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst);
+
+  /**
+   * @brief Instance structure for the Q31 RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                        /**< length of the real FFT. */
+    uint8_t ifftFlagR;                          /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                    /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;                 /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    q31_t *pTwiddleAReal;                       /**< points to the real twiddle factor table. */
+    const csky_cfft_instance_q31 *pCfft;        /**< points to the complex FFT instance. */
+  } csky_rfft_instance_q31;
+
+  csky_status csky_rfft_init_q31(
+  csky_rfft_instance_q31 * S,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void csky_rfft_q31(
+  const csky_rfft_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst);
+
+  /**
+   * @brief Instance structure for the floating-point RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                        /**< length of the real FFT. */
+    uint16_t fftLenBy2;                         /**< length of the complex FFT. */
+    uint8_t ifftFlagR;                          /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                    /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;                 /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    float32_t *pTwiddleAReal;                   /**< points to the real twiddle factor table. */
+    float32_t *pTwiddleBReal;                   /**< points to the imag twiddle factor table. */
+    csky_cfft_radix4_instance_f32 *pCfft;       /**< points to the complex FFT instance. */
+  } csky_rfft_instance_f32;
+
+  csky_status csky_rfft_init_f32(
+  csky_rfft_instance_f32 * S,
+  csky_cfft_radix4_instance_f32 * S_CFFT,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void csky_rfft_f32(
+  const csky_rfft_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst);
+
+  /**
+   * @brief Instance structure for the floating-point RFFT/RIFFT function.
+   */
+typedef struct
+  {
+    csky_cfft_instance_f32 Sint;     /**< Internal CFFT structure. */
+    uint16_t fftLenRFFT;             /**< length of the real sequence */
+    float32_t * pTwiddleRFFT;        /**< Twiddle factors real stage  */
+  } csky_rfft_fast_instance_f32 ;
+
+csky_status csky_rfft_fast_init_f32 (
+   csky_rfft_fast_instance_f32 * S,
+   uint16_t fftLen);
+
+void csky_rfft_fast_f32(
+  csky_rfft_fast_instance_f32 * S,
+  float32_t * p, float32_t * pOut,
+  uint8_t ifftFlag);
+
+  /**
+   * @brief Instance structure for the floating-point DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                           /**< length of the DCT4. */
+    uint16_t Nby2;                        /**< half of the length of the DCT4. */
+    float32_t normalize;                  /**< normalizing factor. */
+    float32_t *pTwiddle;                  /**< points to the twiddle factor table. */
+    float32_t *pCosFactor;                /**< points to the cosFactor table. */
+    csky_rfft_fast_instance_f32 *pRfft;   /**< points to the real FFT fast instance. */
+    csky_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+  } csky_dct4_instance_f32;
+
+  csky_status csky_dct4_init_f32(
+  csky_dct4_instance_f32 * S,
+  csky_rfft_fast_instance_f32 * S_RFFT,
+  csky_cfft_radix4_instance_f32 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  float32_t normalize);
+
+  void csky_dct4_f32(
+  const csky_dct4_instance_f32 * S,
+  float32_t * pState,
+  float32_t * pInlineBuffer);
+
+
+  /**
+   * @brief Instance structure for the Q31 DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                           /**< length of the DCT4. */
+    uint16_t Nby2;                        /**< half of the length of the DCT4. */
+    q31_t normalize;                      /**< normalizing factor. */
+    q31_t *pTwiddle;                      /**< points to the twiddle factor table. */
+    q31_t *pCosFactor;                    /**< points to the cosFactor table. */
+    csky_rfft_instance_q31 *pRfft;        /**< points to the real FFT instance. */
+    csky_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+  } csky_dct4_instance_q31;
+
+  csky_status csky_dct4_init_q31(
+  csky_dct4_instance_q31 * S,
+  csky_rfft_instance_q31 * S_RFFT,
+  csky_cfft_radix4_instance_q31 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  q31_t normalize);
+
+  void csky_dct4_q31(
+  const csky_dct4_instance_q31 * S,
+  q31_t * pState,
+  q31_t * pInlineBuffer);
+
+  /**
+   * @brief Instance structure for the Q15 DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                           /**< length of the DCT4. */
+    uint16_t Nby2;                        /**< half of the length of the DCT4. */
+    q15_t normalize;                      /**< normalizing factor. */
+    q15_t *pTwiddle;                      /**< points to the twiddle factor table. */
+    q15_t *pCosFactor;                    /**< points to the cosFactor table. */
+    csky_rfft_instance_q15 *pRfft;        /**< points to the real FFT instance. */
+    csky_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+  } csky_dct4_instance_q15;
+
+  csky_status csky_dct4_init_q15(
+  csky_dct4_instance_q15 * S,
+  csky_rfft_instance_q15 * S_RFFT,
+  csky_cfft_radix4_instance_q15 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  q15_t normalize);
+
+  void csky_dct4_q15(
+  const csky_dct4_instance_q15 * S,
+  q15_t * pState,
+  q15_t * pInlineBuffer);
+
+  void csky_add_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_add_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_add_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_add_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_sub_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_sub_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_sub_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_sub_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_scale_f32(
+  float32_t * pSrc,
+  float32_t scale,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_scale_q7(
+  q7_t * pSrc,
+  q7_t scaleFract,
+  int8_t shift,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_scale_q15(
+  q15_t * pSrc,
+  q15_t scaleFract,
+  int8_t shift,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_scale_q31(
+  q31_t * pSrc,
+  q31_t scaleFract,
+  int8_t shift,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_abs_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_abs_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_abs_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_abs_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_abs_max_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_abs_max_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  void csky_dot_prod_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  uint32_t blockSize,
+  float32_t * result);
+
+  void csky_dot_prod_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  uint32_t blockSize,
+  q31_t * result);
+
+  void csky_dot_prod_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  uint32_t blockSize,
+  q63_t * result);
+
+  void csky_dot_prod_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  uint32_t blockSize,
+  q63_t * result);
+
+  void csky_shift_q7(
+  q7_t * pSrc,
+  int8_t shiftBits,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_shift_q15(
+  q15_t * pSrc,
+  int8_t shiftBits,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_shift_q31(
+  q31_t * pSrc,
+  int8_t shiftBits,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_offset_f32(
+  float32_t * pSrc,
+  float32_t offset,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_offset_q7(
+  q7_t * pSrc,
+  q7_t offset,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_offset_q15(
+  q15_t * pSrc,
+  q15_t offset,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_offset_q31(
+  q31_t * pSrc,
+  q31_t offset,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_negate_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_negate_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_negate_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_negate_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_copy_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_copy_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_copy_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_copy_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fill_f32(
+  float32_t value,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fill_q7(
+  q7_t value,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fill_q15(
+  q15_t value,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fill_q31(
+  q31_t value,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_conv_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst);
+
+  void csky_conv_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  void csky_conv_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+  void csky_conv_fast_q15(
+          q15_t * pSrcA,
+          uint32_t srcALen,
+          q15_t * pSrcB,
+          uint32_t srcBLen,
+          q15_t * pDst);
+
+  void csky_conv_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  void csky_conv_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+  void csky_conv_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+  void csky_conv_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  void csky_conv_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst);
+
+  csky_status csky_conv_partial_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  csky_status csky_conv_partial_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  csky_status csky_conv_partial_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  csky_status csky_conv_partial_fast_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  csky_status csky_conv_partial_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  csky_status csky_conv_partial_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  csky_status csky_conv_partial_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  csky_status csky_conv_partial_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  csky_status csky_conv_partial_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  /**
+   * functions for the yunVoice functions.
+   */
+   q15_t csky_dsp_lib_vec_max_abs16(
+   q15_t  * A,
+   uint32_t N);
+
+   q31_t csky_dsp_lib_vec_max_abs32(
+   q31_t  * A,
+   uint32_t N);
+
+   void csky_dsp_lib_vec_abs16(
+   q15_t  * A,
+   uint32_t N,
+   q15_t  * C);
+
+   void csky_dsp_lib_vec_abs32(
+   q31_t * A,
+   uint32_t N,
+   q31_t * C);
+
+   void csky_dsp_lib_vec_add16(
+   q15_t * A,
+   q15_t * B,
+   uint32_t N,
+   q15_t * C);
+
+   void csky_dsp_lib_vec_add32(
+   q31_t * A,
+   q31_t * B,
+   uint32_t N,
+   q31_t * C);
+
+   void csky_dsp_lib_vec_cx_conj_q15(
+   q15_t * A,
+   uint32_t N,
+   q15_t * B);
+
+   void csky_dsp_lib_vec_cx_conj_q31(
+   q31_t * A,
+   uint32_t N,
+   q31_t * C);
+
+   q31_t csky_dsp_lib_vec_dot_q15(
+   q15_t * A,
+   q15_t * B,
+   uint32_t N);
+
+   q31_t csky_dsp_lib_vec_dot_q31(
+   q31_t * A,
+   q31_t * B,
+   uint32_t N);
+
+   void csky_dsp_lib_mat_cx_add16(
+   cq15_t * A,
+   cq15_t * B,
+   uint32_t N,
+   uint32_t M,
+   cq15_t * C);
+
+   void csky_dsp_lib_mat_cx_add32(
+   cq31_t * A,
+   cq31_t * B,
+   uint32_t N,
+   uint32_t M,
+   cq31_t * C);
+
+   void csky_dsp_lib_mat_cx_mul_q15(
+   cq15_t * A,
+   cq15_t * B,
+   uint32_t N,
+   uint32_t M,
+   uint32_t L,
+   cq15_t * C);
+
+   void csky_dsp_lib_mat_cx_mul_q31(
+   cq31_t * A,
+   cq31_t * B,
+   uint32_t N,
+   uint32_t M,
+   uint32_t L,
+   cq31_t * C);
+
+   void csky_dsp_lib_mat_cx_sub16(
+   cq15_t * A,
+   cq15_t * B,
+   uint32_t N,
+   uint32_t M,
+   cq15_t * C);
+
+   void csky_dsp_lib_mat_cx_sub32(
+   cq31_t * A,
+   cq31_t * B,
+   uint32_t N,
+   uint32_t M,
+   cq31_t * C);
+
+   void csky_dsp_lib_vec_mul_q15(
+   q15_t * A,
+   q15_t * B,
+   uint32_t N,
+   q15_t * C);
+
+   void csky_dsp_lib_vec_mul_q31(
+   q31_t * A,
+   q31_t * B,
+   uint32_t N,
+   q31_t * C);
+
+   q31_t csky_dsp_lib_pow_int32(
+   q31_t arg_in_x,
+   q15_t arg_exp_in_x,
+   q31_t arg_in_y,
+   q15_t arg_exp_in_y,
+   q31_t *arg_exp_out);
+
+   void csky_dsp_lib_vec_scale_q15(
+   q15_t * A,
+   q15_t scaleFract,
+   int8_t shift,
+   q15_t * B,
+   uint32_t N);
+
+   void csky_dsp_lib_vec_scale_q31(
+   q31_t * A,
+   q31_t scaleFract,
+   int8_t shift,
+   q31_t * B,
+   uint32_t N);
+
+   void csky_dsp_lib_vec_shf16(
+   q15_t * A,
+   int8_t shift_val,
+   uint32_t N,
+   q15_t * C);
+
+   void csky_dsp_lib_vec_shf32(
+   q31_t * A,
+   q31_t shift_val,
+   uint32_t N,
+   q31_t * C);
+
+   q15_t csky_dsp_lib_sqrt_int32(
+   q31_t x,
+   uint32_t rnd_flag);
+
+   void csky_dsp_lib_vec_sub16(
+   q15_t * A,
+   q15_t * B,
+   uint32_t N,
+   q15_t * C);
+
+   void csky_dsp_lib_vec_sub32(
+   q31_t * A,
+   q31_t * B,
+   uint32_t N,
+   q31_t * C);
+
+   q63_t csky_dsp_lib_vec_sum16(
+   q15_t * A,
+   uint32_t N);
+
+   q63_t csky_dsp_lib_vec_sum32(
+   q31_t * A,
+   uint32_t N);
+
+    void csky_fft_lib_cx16_fft(
+    q31_t log2_buf_len,
+    q15_t * in_buf,
+    q15_t * out_buf,
+    const q15_t * twi_table,
+    const uint16_t * bitrev_tbl,
+    q15_t * temp_buf,
+    q7_t  * ScaleShift,
+    q31_t br);
+
+    void csky_fft_lib_cx32_fft(
+    q31_t log2_buf_len,
+    q31_t * in_buf,
+    q31_t * out_buf,
+    const q31_t * twi_table,
+    const uint16_t * bitrev_tbl,
+    q31_t * temp_buf,
+    q31_t br);
+
+    void csky_fft_lib_cx16_ifft(
+    q31_t log2_buf_len,
+    q15_t * in_buf,
+    q15_t * out_buf,
+    const q15_t * twi_table,
+    const uint16_t * bitrev_tbl,
+    q15_t * temp_buf,
+    q7_t  * ScaleShift,
+    q31_t br);
+
+    void csky_fft_lib_cx32_ifft(
+    q31_t log2_buf_len,
+    q31_t * in_buf,
+    q31_t * out_buf,
+    const q31_t * twi_table,
+    const uint16_t * bitrev_tbl,
+    q31_t * temp_buf,
+    q31_t br);
+
+    void csky_fft_lib_int16_fft(
+    q31_t log2_buf_len,
+    q15_t * in_buf,
+    q15_t * out_buf,
+    const q15_t * twi_table,
+    const q15_t * last_stage_twi_table,
+    const uint16_t * bitrev_tbl,
+    q15_t * temp_buf,
+    q7_t  * ScaleShift,
+    q31_t br);
+
+    void csky_fft_lib_int32_fft(
+    q31_t log2_buf_len,
+    q31_t * in_buf,
+    q31_t * out_buf,
+    const q31_t * twi_table,
+    const q31_t * last_stage_twi_table,
+    const uint16_t * bitrev_tbl,
+    q31_t * temp_buf,
+    q31_t br);
+
+    void csky_fft_lib_int16_ifft(
+    q31_t log2_buf_len,
+    q15_t * in_buf,
+    q15_t * out_buf,
+    const q15_t * twi_table,
+    const q15_t * last_stage_twi_table,
+    const uint16_t * bitrev_tbl,
+    q15_t * temp_buf,
+    q7_t  * ScaleShift,
+    q31_t br);
+
+    void csky_fft_lib_int32_ifft(
+    q31_t log2_buf_len,
+    q31_t * in_buf,
+    q31_t * out_buf,
+    const q31_t * twi_table,
+    const q31_t * last_stage_twi_table,
+    const uint16_t * bitrev_tbl,
+    q31_t * temp_buf,
+    q31_t br);
+
+  /**
+   * @brief Instance structure for the Q15 FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    q15_t *pCoeffs;             /**< points to the coefficient array. The array is of length numTaps.*/
+    q15_t *pState;              /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } csky_fir_decimate_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    q31_t *pCoeffs;             /**< points to the coefficient array. The array is of length numTaps.*/
+    q31_t *pState;              /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } csky_fir_decimate_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    float32_t *pCoeffs;         /**< points to the coefficient array. The array is of length numTaps.*/
+    float32_t *pState;          /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } csky_fir_decimate_instance_f32;
+
+  void csky_fir_decimate_f32(
+  const csky_fir_decimate_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  csky_status csky_fir_decimate_init_f32(
+  csky_fir_decimate_instance_f32 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+  void csky_fir_decimate_q15(
+  const csky_fir_decimate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fir_decimate_fast_q15(
+  const csky_fir_decimate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  csky_status csky_fir_decimate_init_q15(
+  csky_fir_decimate_instance_q15 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+  void csky_fir_decimate_q31(
+  const csky_fir_decimate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fir_decimate_fast_q31(
+  csky_fir_decimate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  csky_status csky_fir_decimate_init_q31(
+  csky_fir_decimate_instance_q31 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                      /**< upsample factor. */
+    uint16_t phaseLength;           /**< length of each polyphase filter component. */
+    q15_t *pCoeffs;                 /**< points to the coefficient array. The array is of length L*phaseLength. */
+    q15_t *pState;                  /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+  } csky_fir_interpolate_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                      /**< upsample factor. */
+    uint16_t phaseLength;           /**< length of each polyphase filter component. */
+    q31_t *pCoeffs;                 /**< points to the coefficient array. The array is of length L*phaseLength. */
+    q31_t *pState;                  /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+  } csky_fir_interpolate_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                     /**< upsample factor. */
+    uint16_t phaseLength;          /**< length of each polyphase filter component. */
+    float32_t *pCoeffs;            /**< points to the coefficient array. The array is of length L*phaseLength. */
+    float32_t *pState;             /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */
+  } csky_fir_interpolate_instance_f32;
+
+  void csky_fir_interpolate_q15(
+  const csky_fir_interpolate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  csky_status csky_fir_interpolate_init_q15(
+  csky_fir_interpolate_instance_q15 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+  void csky_fir_interpolate_q31(
+  const csky_fir_interpolate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  csky_status csky_fir_interpolate_init_q31(
+  csky_fir_interpolate_instance_q31 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+  void csky_fir_interpolate_f32(
+  const csky_fir_interpolate_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  csky_status csky_fir_interpolate_init_f32(
+  csky_fir_interpolate_instance_f32 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the high precision Q31 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;       /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q63_t *pState;           /**< points to the array of state coefficients.  The array is of length 4*numStages. */
+    q31_t *pCoeffs;          /**< points to the array of coefficients.  The array is of length 5*numStages. */
+    uint8_t postShift;       /**< additional shift, in bits, applied to each output sample. */
+  } csky_biquad_cas_df1_32x64_ins_q31;
+
+  void csky_biquad_cas_df1_32x64_q31(
+  const csky_biquad_cas_df1_32x64_ins_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_biquad_cas_df1_32x64_init_q31(
+  csky_biquad_cas_df1_32x64_ins_q31 * S,
+  uint8_t numStages,
+  q31_t * pCoeffs,
+  q63_t * pState,
+  uint8_t postShift);
+
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;         /**< points to the array of state coefficients.  The array is of length 2*numStages. */
+    float32_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } csky_biquad_cascade_df2T_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;         /**< points to the array of state coefficients.  The array is of length 4*numStages. */
+    float32_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } csky_biquad_cascade_stereo_df2T_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float64_t *pState;         /**< points to the array of state coefficients.  The array is of length 2*numStages. */
+    float64_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } csky_biquad_cascade_df2T_instance_f64;
+
+  void csky_biquad_cascade_df2T_f32(
+  const csky_biquad_cascade_df2T_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_biquad_cascade_stereo_df2T_f32(
+  const csky_biquad_cascade_stereo_df2T_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_biquad_cascade_df2T_f64(
+  const csky_biquad_cascade_df2T_instance_f64 * S,
+  float64_t * pSrc,
+  float64_t * pDst,
+  uint32_t blockSize);
+
+  void csky_biquad_cascade_df2T_init_f32(
+  csky_biquad_cascade_df2T_instance_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+  void csky_biquad_cascade_stereo_df2T_init_f32(
+  csky_biquad_cascade_stereo_df2T_instance_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  void csky_biquad_cascade_df2T_init_f64(
+  csky_biquad_cascade_df2T_instance_f64 * S,
+  uint8_t numStages,
+  float64_t * pCoeffs,
+  float64_t * pState);
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    q15_t *pState;                       /**< points to the state variable array. The array is of length numStages. */
+    q15_t *pCoeffs;                      /**< points to the coefficient array. The array is of length numStages. */
+  } csky_fir_lattice_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    q31_t *pState;                       /**< points to the state variable array. The array is of length numStages. */
+    q31_t *pCoeffs;                      /**< points to the coefficient array. The array is of length numStages. */
+  } csky_fir_lattice_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    float32_t *pState;                   /**< points to the state variable array. The array is of length numStages. */
+    float32_t *pCoeffs;                  /**< points to the coefficient array. The array is of length numStages. */
+  } csky_fir_lattice_instance_f32;
+
+  void csky_fir_lattice_init_q15(
+  csky_fir_lattice_instance_q15 * S,
+  uint16_t numStages,
+  q15_t * pCoeffs,
+  q15_t * pState);
+
+  void csky_fir_lattice_q15(
+  const csky_fir_lattice_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fir_lattice_init_q31(
+  csky_fir_lattice_instance_q31 * S,
+  uint16_t numStages,
+  q31_t * pCoeffs,
+  q31_t * pState);
+
+  void csky_fir_lattice_q31(
+  const csky_fir_lattice_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_fir_lattice_init_f32(
+  csky_fir_lattice_instance_f32 * S,
+  uint16_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+  void csky_fir_lattice_f32(
+  const csky_fir_lattice_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    q15_t *pState;                       /**< points to the state variable array. The array is of length numStages+blockSize. */
+    q15_t *pkCoeffs;                     /**< points to the reflection coefficient array. The array is of length numStages. */
+    q15_t *pvCoeffs;                     /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } csky_iir_lattice_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    q31_t *pState;                       /**< points to the state variable array. The array is of length numStages+blockSize. */
+    q31_t *pkCoeffs;                     /**< points to the reflection coefficient array. The array is of length numStages. */
+    q31_t *pvCoeffs;                     /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } csky_iir_lattice_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    float32_t *pState;                   /**< points to the state variable array. The array is of length numStages+blockSize. */
+    float32_t *pkCoeffs;                 /**< points to the reflection coefficient array. The array is of length numStages. */
+    float32_t *pvCoeffs;                 /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } csky_iir_lattice_instance_f32;
+
+  void csky_iir_lattice_f32(
+  const csky_iir_lattice_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_iir_lattice_init_f32(
+  csky_iir_lattice_instance_f32 * S,
+  uint16_t numStages,
+  float32_t * pkCoeffs,
+  float32_t * pvCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+  void csky_iir_lattice_q31(
+  const csky_iir_lattice_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_iir_lattice_init_q31(
+  csky_iir_lattice_instance_q31 * S,
+  uint16_t numStages,
+  q31_t * pkCoeffs,
+  q31_t * pvCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+  void csky_iir_lattice_q15(
+  const csky_iir_lattice_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_iir_lattice_init_q15(
+  csky_iir_lattice_instance_q15 * S,
+  uint16_t numStages,
+  q15_t * pkCoeffs,
+  q15_t * pvCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the floating-point LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    float32_t *pState;   /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;  /**< points to the coefficient array. The array is of length numTaps. */
+    float32_t mu;        /**< step size that controls filter coefficient updates. */
+  } csky_lms_instance_f32;
+
+  void csky_lms_f32(
+  const csky_lms_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pRef,
+  float32_t * pOut,
+  float32_t * pErr,
+  uint32_t blockSize);
+
+  void csky_lms_init_f32(
+  csky_lms_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  float32_t mu,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    q15_t *pState;       /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;      /**< points to the coefficient array. The array is of length numTaps. */
+    q15_t mu;            /**< step size that controls filter coefficient updates. */
+    uint32_t postShift;  /**< bit shift applied to coefficients. */
+  } csky_lms_instance_q15;
+
+  void csky_lms_init_q15(
+  csky_lms_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  q15_t mu,
+  uint32_t blockSize,
+  uint32_t postShift);
+
+  void csky_lms_q15(
+  const csky_lms_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pRef,
+  q15_t * pOut,
+  q15_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q31 LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    q31_t *pState;       /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;      /**< points to the coefficient array. The array is of length numTaps. */
+    q31_t mu;            /**< step size that controls filter coefficient updates. */
+    uint32_t postShift;  /**< bit shift applied to coefficients. */
+  } csky_lms_instance_q31;
+
+  void csky_lms_q31(
+  const csky_lms_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pRef,
+  q31_t * pOut,
+  q31_t * pErr,
+  uint32_t blockSize);
+
+  void csky_lms_init_q31(
+  csky_lms_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  q31_t mu,
+  uint32_t blockSize,
+  uint32_t postShift);
+
+
+  /**
+   * @brief Instance structure for the floating-point normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of coefficients in the filter. */
+    float32_t *pState;    /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;   /**< points to the coefficient array. The array is of length numTaps. */
+    float32_t mu;         /**< step size that control filter coefficient updates. */
+    float32_t energy;     /**< saves previous frame energy. */
+    float32_t x0;         /**< saves previous input sample. */
+  } csky_lms_norm_instance_f32;
+
+  void csky_lms_norm_f32(
+  csky_lms_norm_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pRef,
+  float32_t * pOut,
+  float32_t * pErr,
+  uint32_t blockSize);
+
+  void csky_lms_norm_init_f32(
+  csky_lms_norm_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  float32_t mu,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q31 normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of coefficients in the filter. */
+    q31_t *pState;        /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;       /**< points to the coefficient array. The array is of length numTaps. */
+    q31_t mu;             /**< step size that controls filter coefficient updates. */
+    uint8_t postShift;    /**< bit shift applied to coefficients. */
+    q31_t *recipTable;    /**< points to the reciprocal initial value table. */
+    q31_t energy;         /**< saves previous frame energy. */
+    q31_t x0;             /**< saves previous input sample. */
+  } csky_lms_norm_instance_q31;
+
+  void csky_lms_norm_q31(
+  csky_lms_norm_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pRef,
+  q31_t * pOut,
+  q31_t * pErr,
+  uint32_t blockSize);
+
+  void csky_lms_norm_init_q31(
+  csky_lms_norm_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  q31_t mu,
+  uint32_t blockSize,
+  uint8_t postShift);
+
+
+  /**
+   * @brief Instance structure for the Q15 normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< Number of coefficients in the filter. */
+    q15_t *pState;        /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;       /**< points to the coefficient array. The array is of length numTaps. */
+    q15_t mu;             /**< step size that controls filter coefficient updates. */
+    uint8_t postShift;    /**< bit shift applied to coefficients. */
+    q15_t *recipTable;    /**< Points to the reciprocal initial value table. */
+    q15_t energy;         /**< saves previous frame energy. */
+    q15_t x0;             /**< saves previous input sample. */
+  } csky_lms_norm_instance_q15;
+
+  void csky_lms_norm_q15(
+  csky_lms_norm_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pRef,
+  q15_t * pOut,
+  q15_t * pErr,
+  uint32_t blockSize);
+
+  void csky_lms_norm_init_q15(
+  csky_lms_norm_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  q15_t mu,
+  uint32_t blockSize,
+  uint8_t postShift);
+
+  void csky_correlate_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst);
+
+  void csky_correlate_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch);
+
+  void csky_correlate_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+  void csky_correlate_fast_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+  void csky_correlate_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch);
+
+  void csky_correlate_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+  void csky_correlate_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+  void csky_correlate_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  void csky_correlate_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst);
+
+
+  /**
+   * @brief Instance structure for the floating-point sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    float32_t *pState;            /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    float32_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } csky_fir_sparse_instance_f32;
+
+  /**
+   * @brief Instance structure for the Q31 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q31_t *pState;                /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q31_t *pCoeffs;               /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } csky_fir_sparse_instance_q31;
+
+  /**
+   * @brief Instance structure for the Q15 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q15_t *pState;                /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q15_t *pCoeffs;               /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } csky_fir_sparse_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q7 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q7_t *pState;                 /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q7_t *pCoeffs;                /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } csky_fir_sparse_instance_q7;
+
+  void csky_fir_sparse_f32(
+  csky_fir_sparse_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  float32_t * pScratchIn,
+  uint32_t blockSize);
+
+  void csky_fir_sparse_init_f32(
+  csky_fir_sparse_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+  void csky_fir_sparse_q31(
+  csky_fir_sparse_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  q31_t * pScratchIn,
+  uint32_t blockSize);
+
+  void csky_fir_sparse_init_q31(
+  csky_fir_sparse_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+  void csky_fir_sparse_q15(
+  csky_fir_sparse_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  q15_t * pScratchIn,
+  q31_t * pScratchOut,
+  uint32_t blockSize);
+
+  void csky_fir_sparse_init_q15(
+  csky_fir_sparse_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+  void csky_fir_sparse_q7(
+  csky_fir_sparse_instance_q7 * S,
+  q7_t * pSrc,
+  q7_t * pDst,
+  q7_t * pScratchIn,
+  q31_t * pScratchOut,
+  uint32_t blockSize);
+
+  void csky_fir_sparse_init_q7(
+  csky_fir_sparse_instance_q7 * S,
+  uint16_t numTaps,
+  q7_t * pCoeffs,
+  q7_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+  void csky_sin_cos_f32(
+  float32_t theta,
+  float32_t * pSinVal,
+  float32_t * pCosVal);
+
+  void csky_sin_cos_q31(
+  q31_t theta,
+  q31_t * pSinVal,
+  q31_t * pCosVal);
+
+  void csky_cmplx_conj_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_conj_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_conj_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mag_squared_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mag_squared_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mag_squared_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+/**
+  * @ingroup groupController
+  */
+
+/**
+ * @defgroup PID PID Motor Control
+ *
+ * A Proportional Integral Derivative (PID) controller is a generic feedback control
+ * loop mechanism widely used in industrial control systems.
+ * A PID controller is the most commonly used type of feedback controller.
+ *
+ * This set of functions implements (PID) controllers
+ * for Q15, Q31, and floating-point data types.  The functions operate on a single sample
+ * of data and each call to the function returns a single processed value.
+ * <code>S</code> points to an instance of the PID control data structure.  <code>in</code>
+ * is the input sample value. The functions return the output value.
+ *
+ * \par Algorithm:
+ * <pre>
+ *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+ *    A0 = Kp + Ki + Kd
+ *    A1 = (-Kp ) - (2 * Kd )
+ *    A2 = Kd  </pre>
+ *
+ * \par
+ * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant
+ *
+ * \par
+ * \image html PID.gif "Proportional Integral Derivative Controller"
+ *
+ * \par
+ * The PID controller calculates an "error" value as the difference between
+ * the measured output and the reference input.
+ * The controller attempts to minimize the error by adjusting the process control inputs.
+ * The proportional value determines the reaction to the current error,
+ * the integral value determines the reaction based on the sum of recent errors,
+ * and the derivative value determines the reaction based on the rate at which the error has been changing.
+ *
+ * \par Instance Structure
+ * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure.
+ * A separate instance structure must be defined for each PID Controller.
+ * There are separate instance structure declarations for each of the 3 supported data types.
+ *
+ * \par Reset Functions
+ * There is also an associated reset function for each data type which clears the state array.
+ *
+ * \par Initialization Functions
+ * There is also an associated initialization function for each data type.
+ * The initialization function performs the following operations:
+ * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains.
+ * - Zeros out the values in the state buffer.
+ *
+ * \par
+ * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function.
+ *
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the fixed-point versions of the PID Controller functions.
+ * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+/**
+ * @addtogroup PID
+ * @{
+ */
+
+/**
+ * @brief  Process function for the floating-point PID Control.
+ * @param[in,out] S   is an instance of the floating-point PID Control structure
+ * @param[in]     in  input sample to process
+ * @return out processed output sample.
+ */
+  __STATIC_INLINE float32_t csky_pid_f32(
+  csky_pid_instance_f32 * S,
+  float32_t in)
+  {
+    float32_t out;
+
+    /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]  */
+    out = (S->A0 * in) +
+      (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+  }
+
+/**
+ * @}
+*/ // end of PID group
+
+
+/**
+ * @addtogroup PID
+ * @{
+ */
+
+/**
+ * @brief  Process function for the Q31 PID Control.
+ * @param[in,out] S  points to an instance of the Q31 PID Control structure
+ * @param[in]     in  input sample to process
+ * @return out processed output sample.
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using an internal 64-bit accumulator.
+ * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit.
+ * Thus, if the accumulator result overflows it wraps around rather than clip.
+ * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions.
+ * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format.
+ */
+  __STATIC_INLINE q31_t csky_pid_q31(
+  csky_pid_instance_q31 * S,
+  q31_t in)
+  {
+    q63_t acc;
+    q31_t out;
+
+  #ifdef CSKY_SIMD
+    /* acc = A0 * x[n]  */
+    acc = mult_32x32_keep64(S->A0, in);
+
+    /* acc += A1 * x[n-1] */
+    acc = multAcc_32x32_keep64(acc, S->A1, S->state[0]);
+
+    /* acc += A2 * x[n-2]  */
+    acc = multAcc_32x32_keep64(acc, S->A2, S->state[1]);
+
+    /* convert output to 1.31 format to add y[n-1] */
+    out = dext_31(acc);
+  #else
+    /* acc = A0 * x[n]  */
+    acc = (q63_t) S->A0 * in;
+
+    /* acc += A1 * x[n-1] */
+    acc += (q63_t) S->A1 * S->state[0];
+
+    /* acc += A2 * x[n-2]  */
+    acc += (q63_t) S->A2 * S->state[1];
+
+    /* convert output to 1.31 format to add y[n-1] */
+    out = (q31_t) (acc >> 31u);
+  #endif
+
+    /* out += y[n-1] */
+    out += S->state[2];
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+  }
+
+/**
+ * @}
+ */  // end of PID group
+
+/**
+ * @addtogroup PID
+ * @{
+ */
+/**
+ * @brief  Process function for the Q15 PID Control.
+ * @param[in,out] S   points to an instance of the Q15 PID Control structure
+ * @param[in]     in  input sample to process
+ * @return out processed output sample.
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using a 64-bit internal accumulator.
+ * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
+ * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
+ * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
+ * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits.
+ * Lastly, the accumulator is saturated to yield a result in 1.15 format.
+ */
+  __STATIC_INLINE q15_t csky_pid_q15(
+  csky_pid_instance_q15 * S,
+  q15_t in)
+  {
+    q63_t acc;
+    q15_t out;
+
+    /* acc = A0 * x[n]  */
+    acc = ((q31_t) S->A0) * in;
+
+    /* acc += A1 * x[n-1] + A2 * x[n-2]  */
+    acc += (q31_t) S->A1 * S->state[0];
+    acc += (q31_t) S->A2 * S->state[1];
+
+    /* acc += y[n-1] */
+    acc += (q31_t) S->state[2] << 15;
+
+    /* saturate the output */
+    out = (q15_t) (__SSAT_16((acc >> 15)));
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+  }
+/**
+ * @}
+ */ // end of PID group
+
+  csky_status csky_mat_inverse_f32(
+  const csky_matrix_instance_f32 * src,
+  csky_matrix_instance_f32 * dst);
+
+  csky_status csky_mat_inverse_f64(
+  const csky_matrix_instance_f64 * src,
+  csky_matrix_instance_f64 * dst);
+
+/**
+ * @ingroup groupController
+ */
+
+/**
+ * @defgroup clarke Vector Clarke Transform
+ * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector.
+ * Generally the Clarke transform uses three-phase currents <code>Ia, Ib and Ic</code> to calculate currents
+ * in the two-phase orthogonal stator axis <code>Ialpha</code> and <code>Ibeta</code>.
+ * When <code>Ialpha</code> is superposed with <code>Ia</code> as shown in the figure below
+ * \image html clarke.gif Stator current space vector and its components in (a,b).
+ * and <code>Ia + Ib + Ic = 0</code>, in this condition <code>Ialpha</code> and <code>Ibeta</code>
+ * can be calculated using only <code>Ia</code> and <code>Ib</code>.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html clarkeFormula.gif
+ * where <code>Ia</code> and <code>Ib</code> are the instantaneous stator phases and
+ * <code>pIalpha</code> and <code>pIbeta</code> are the two coordinates of time invariant vector.
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Clarke transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+/**
+ * @addtogroup clarke
+ * @{
+ */
+
+/**
+ *
+ * @brief  Floating-point Clarke transform
+ * @param[in]  Ia       input three-phase coordinate a
+ * @param[in]  Ib       input three-phase coordinate b
+ * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+ */
+  __STATIC_INLINE void csky_clarke_f32(
+  float32_t Ia,
+  float32_t Ib,
+  float32_t * pIalpha,
+  float32_t * pIbeta)
+  {
+    /* Calculate pIalpha using the equation, pIalpha = Ia */
+    *pIalpha = Ia;
+
+    /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */
+    *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib);
+  }
+
+/**
+ * @}
+ */ // end of clarke group
+
+
+/**
+ * @addtogroup clarke
+ * @{
+ */
+
+/**
+ * @brief  Clarke transform for Q31 version
+ * @param[in]  Ia       input three-phase coordinate a
+ * @param[in]  Ib       input three-phase coordinate b
+ * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition, hence there is no risk of overflow.
+ */
+  __STATIC_INLINE void csky_clarke_q31(
+  q31_t Ia,
+  q31_t Ib,
+  q31_t * pIalpha,
+  q31_t * pIbeta)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+
+    /* Calculating pIalpha from Ia by equation pIalpha = Ia */
+    *pIalpha = Ia;
+
+  #ifdef CSKY_SIMD
+    /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */
+    product1 = mult_32x32_dext_30(Ia, 0x24F34E8B);
+
+    /* Intermediate product is calculated by (2/sqrt(3) * Ib) */
+    product2 = mult_32x32_dext_30(Ib, 0x49E69D16);
+  #else
+    /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */
+    product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30);
+
+    /* Intermediate product is calculated by (2/sqrt(3) * Ib) */
+    product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30);
+  #endif
+
+    /* pIbeta is calculated by adding the intermediate products */
+    *pIbeta = __QADD(product1, product2);
+  }
+
+
+/**
+ * @}
+ */ // end of clarke group
+
+  void csky_q7_to_q31(
+  q7_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+/**
+ * @ingroup groupController
+ */
+/**
+ * @defgroup inv_clarke Vector Inverse Clarke Transform
+ * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html clarkeInvFormula.gif
+ * where <code>pIa</code> and <code>pIb</code> are the instantaneous stator phases and
+ * <code>Ialpha</code> and <code>Ibeta</code> are the two coordinates of time invariant vector.
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Clarke transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+/**
+ * @addtogroup inv_clarke
+ * @{
+ */
+
+ /**
+ * @brief  Floating-point Inverse Clarke transform
+ * @param[in]  Ialpha  input two-phase orthogonal vector axis alpha
+ * @param[in]  Ibeta   input two-phase orthogonal vector axis beta
+ * @param[out] pIa     points to output three-phase coordinate <code>a</code>
+ * @param[out] pIb     points to output three-phase coordinate <code>b</code>
+ */
+  __STATIC_INLINE void csky_inv_clarke_f32(
+  float32_t Ialpha,
+  float32_t Ibeta,
+  float32_t * pIa,
+  float32_t * pIb)
+  {
+    /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+    *pIa = Ialpha;
+
+    /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */
+    *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta;
+  }
+
+
+/**
+ * @}
+ */ // end of inv_clarke group
+
+/**
+ * @addtogroup inv_clarke
+ * @{
+ */
+
+/**
+ * @brief  Inverse Clarke transform for Q31 version
+ * @param[in]  Ialpha  input two-phase orthogonal vector axis alpha
+ * @param[in]  Ibeta   input two-phase orthogonal vector axis beta
+ * @param[out] pIa     points to output three-phase coordinate <code>a</code>
+ * @param[out] pIb     points to output three-phase coordinate <code>b</code>
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the subtraction, hence there is no risk of overflow.
+ */
+  __STATIC_INLINE void csky_inv_clarke_q31(
+  q31_t Ialpha,
+  q31_t Ibeta,
+  q31_t * pIa,
+  q31_t * pIb)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+
+    /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+    *pIa = Ialpha;
+
+  #ifdef CSKY_SIMD
+    /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */
+    product1 = mult_32x32_dext_31(Ialpha, 0x40000000);
+
+    /* Intermediate product is calculated by (1/sqrt(3) * pIb) */
+    product2 = mult_32x32_dext_31(Ibeta, 0x6ED9EBA1);
+  #else
+    /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */
+    product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31);
+
+    /* Intermediate product is calculated by (1/sqrt(3) * pIb) */
+    product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31);
+  #endif
+
+    /* pIb is calculated by subtracting the products */
+    *pIb = __QSUB(product2, product1);
+  }
+
+/**
+ * @}
+ */ // end of inv_clarke group
+
+  void csky_q7_to_q15(
+  q7_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+/**
+ * @ingroup groupController
+ */
+/**
+ * @defgroup park Vector Park Transform
+ *
+ * Forward Park transform converts the input two-coordinate vector to flux and torque components.
+ * The Park transform can be used to realize the transformation of the <code>Ialpha</code> and the <code>Ibeta</code> currents
+ * from the stationary to the moving reference frame and control the spatial relationship between
+ * the stator vector current and rotor flux vector.
+ * If we consider the d axis aligned with the rotor flux, the diagram below shows the
+ * current vector and the relationship from the two reference frames:
+ * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame"
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html parkFormula.gif
+ * where <code>Ialpha</code> and <code>Ibeta</code> are the stator vector components,
+ * <code>pId</code> and <code>pIq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
+ * cosine and sine values of theta (rotor flux position).
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Park transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+/**
+ * @addtogroup park
+ * @{
+ */
+/**
+ * @brief Floating-point Park transform
+ * @param[in]  Ialpha  input two-phase vector coordinate alpha
+ * @param[in]  Ibeta   input two-phase vector coordinate beta
+ * @param[out] pId     points to output   rotor reference frame d
+ * @param[out] pIq     points to output   rotor reference frame q
+ * @param[in]  sinVal  sine value of rotation angle theta
+ * @param[in]  cosVal  cosine value of rotation angle theta
+ *
+ * The function implements the forward Park transform.
+ *
+ */
+  __STATIC_INLINE void csky_park_f32(
+  float32_t Ialpha,
+  float32_t Ibeta,
+  float32_t * pId,
+  float32_t * pIq,
+  float32_t sinVal,
+  float32_t cosVal)
+{
+  /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */
+  *pId = Ialpha * cosVal + Ibeta * sinVal;
+  /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */
+  *pIq = -Ialpha * sinVal + Ibeta * cosVal;
+}
+/**
+ * @}
+ */ // end of park group
+
+/**
+ * @addtogroup park
+ * @{
+ */
+/**
+ * @brief  Park transform for Q31 version
+ * @param[in]  Ialpha  input two-phase vector coordinate alpha
+ * @param[in]  Ibeta   input two-phase vector coordinate beta
+ * @param[out] pId     points to output rotor reference frame d
+ * @param[out] pIq     points to output rotor reference frame q
+ * @param[in]  sinVal  sine value of rotation angle theta
+ * @param[in]  cosVal  cosine value of rotation angle theta
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition and subtraction, hence there is no risk of overflow.
+ */
+  __STATIC_INLINE void csky_park_q31(
+  q31_t Ialpha,
+  q31_t Ibeta,
+  q31_t * pId,
+  q31_t * pIq,
+  q31_t sinVal,
+  q31_t cosVal)
+{
+#ifdef CSKY_SIMD
+  __ASM volatile(
+                "rmul.s32.h t0, %0, %3\n\t"
+                "rmul.s32.h t1, %1, %2\n\t"
+                "add.s32.s  t0, t0, t1\n\t"
+                "st.w       t0, (%4, 0x0)\n\t"
+                "rmul.s32.h t0, %0, %2\n\t"
+                "rmul.s32.h t1, %1, %3\n\t"
+                "sub.s32.s  t1, t1, t0\n\t"
+                "st.w       t1, (%5, 0x0)\n\t"
+                ::"r"(Ialpha),"r"(Ibeta),"r"(sinVal),"r"(cosVal),"r"(pId),"r"(pIq)
+                :"t0","t1", "memory");
+#else
+  q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+  q31_t product3, product4;                    /* Temporary variables used to store intermediate results */
+  /* Intermediate product is calculated by (Ialpha * cosVal) */
+  product1 = clip_q63_to_q31 (((q63_t) (Ialpha) * (cosVal)) >> 31);
+  /* Intermediate product is calculated by (Ibeta * sinVal) */
+  product2 = clip_q63_to_q31 (((q63_t) (Ibeta) * (sinVal)) >> 31);
+  /* Intermediate product is calculated by (Ialpha * sinVal) */
+  product3 = clip_q63_to_q31 (((q63_t) (Ialpha) * (sinVal)) >> 31);
+  /* Intermediate product is calculated by (Ibeta * cosVal) */
+  product4 = clip_q63_to_q31 (((q63_t) (Ibeta) * (cosVal)) >> 31);
+  /* Calculate pId by adding the two intermediate products 1 and 2 */
+  *pId = __QADD(product1, product2);
+  /* Calculate pIq by subtracting the two intermediate products 3 from 4 */
+  *pIq = __QSUB(product4, product3);
+#endif
+}
+/**
+ * @}
+ */ // end of park group
+
+  void csky_q7_to_float(
+  q7_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+/**
+ * @ingroup groupController
+ */
+/**
+ * @defgroup inv_park Vector Inverse Park transform
+ * Inverse Park transform converts the input flux and torque components to two-coordinate vector.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html parkInvFormula.gif
+ * where <code>pIalpha</code> and <code>pIbeta</code> are the stator vector components,
+ * <code>Id</code> and <code>Iq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
+ * cosine and sine values of theta (rotor flux position).
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Park transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+/**
+ * @addtogroup inv_park
+ * @{
+ */
+ /**
+ * @brief  Floating-point Inverse Park transform
+ * @param[in]  Id       input coordinate of rotor reference frame d
+ * @param[in]  Iq       input coordinate of rotor reference frame q
+ * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+ * @param[in]  sinVal   sine value of rotation angle theta
+ * @param[in]  cosVal   cosine value of rotation angle theta
+ */
+  __STATIC_INLINE void csky_inv_park_f32(
+  float32_t Id,
+  float32_t Iq,
+  float32_t * pIalpha,
+  float32_t * pIbeta,
+  float32_t sinVal,
+  float32_t cosVal)
+{
+  /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */
+  *pIalpha = Id * cosVal - Iq * sinVal;
+  /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */
+  *pIbeta = Id * sinVal + Iq * cosVal;
+}
+/**
+ * @}
+ */ // end of inv_park group
+
+/**
+ * @addtogroup inv_park
+ * @{
+ */
+/**
+ * @brief  Inverse Park transform for   Q31 version
+ * @param[in]  Id       input coordinate of rotor reference frame d
+ * @param[in]  Iq       input coordinate of rotor reference frame q
+ * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
+ * @param[in]  sinVal   sine value of rotation angle theta
+ * @param[in]  cosVal   cosine value of rotation angle theta
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition, hence there is no risk of overflow.
+ */
+  __STATIC_INLINE void csky_inv_park_q31(
+  q31_t Id,
+  q31_t Iq,
+  q31_t * pIalpha,
+  q31_t * pIbeta,
+  q31_t sinVal,
+  q31_t cosVal)
+{
+#ifdef CSKY_SIMD
+  __ASM volatile(
+                "rmul.s32.h t0, %0, %3\n\t"
+                "rmul.s32.h t1, %1, %2\n\t"
+                "sub.s32.s  t0, t0, t1\n\t"
+                "st.w       t0, (%4, 0x0)\n\t"
+                "rmul.s32.h t0, %0, %2\n\t"
+                "rmul.s32.h t1, %1, %3\n\t"
+                "add.s32.s  t0, t0, t1\n\t"
+                "st.w       t0, (%5, 0x0)\n\t"
+                ::"r"(Id),"r"(Iq),"r"(sinVal),"r"(cosVal),"r"(pIalpha),"r"(pIbeta)
+                :"t0","t1", "memory");
+
+#else
+  q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+  q31_t product3, product4;                    /* Temporary variables used to store intermediate results */
+  /* Intermediate product is calculated by (Id * cosVal) */
+  product1 = clip_q63_to_q31 (((q63_t) (Id) * (cosVal)) >> 31);
+  /* Intermediate product is calculated by (Iq * sinVal) */
+  product2 = clip_q63_to_q31 (((q63_t) (Iq) * (sinVal)) >> 31);
+  /* Intermediate product is calculated by (Id * sinVal) */
+  product3 = clip_q63_to_q31 (((q63_t) (Id) * (sinVal)) >> 31);
+  /* Intermediate product is calculated by (Iq * cosVal) */
+  product4 = clip_q63_to_q31 (((q63_t) (Iq) * (cosVal)) >> 31);
+  /* Calculate pIalpha by using the two intermediate products 1 and 2 */
+  *pIalpha = __QSUB(product1, product2);
+  /* Calculate pIbeta by using the two intermediate products 3 and 4 */
+  *pIbeta = __QADD(product4, product3);
+#endif
+}
+
+/**
+ * @}
+ */ // end of inv_park group
+
+  void csky_q31_to_float(
+  q31_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+/**
+ * @ingroup groupInterpolation
+ */
+/**
+ * @defgroup LinearInterpolate Linear Interpolation
+ *
+ * Linear interpolation is a method of curve fitting using linear polynomials.
+ * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line
+ *
+ * \par
+ * \image html LinearInterp.gif "Linear interpolation"
+ *
+ * \par
+ * A  Linear Interpolate function calculates an output value(y), for the input(x)
+ * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values)
+ *
+ * \par Algorithm:
+ * <pre>
+ *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+ *       where x0, x1 are nearest values of input x
+ *             y0, y1 are nearest values to output y
+ * </pre>
+ *
+ * \par
+ * This set of functions implements Linear interpolation process
+ * for Q7, Q15, Q31, and floating-point data types.  The functions operate on a single
+ * sample of data and each call to the function returns a single processed value.
+ * <code>S</code> points to an instance of the Linear Interpolate function data structure.
+ * <code>x</code> is the input sample value. The functions returns the output value.
+ *
+ * \par
+ * if x is outside of the table boundary, Linear interpolation returns first value of the table
+ * if x is below input range and returns last value of table if x is above range.
+ */
+/**
+ * @addtogroup LinearInterpolate
+ * @{
+ */
+/**
+ * @brief  Process function for the floating-point Linear Interpolation Function.
+ * @param[in,out] S  is an instance of the floating-point Linear Interpolation structure
+ * @param[in]     x  input sample to process
+ * @return y processed output sample.
+ *
+ */
+__STATIC_INLINE float32_t csky_linear_interp_f32(
+csky_linear_interp_instance_f32 * S,
+float32_t x)
+{
+  float32_t y;
+  float32_t x0, x1;                            /* Nearest input values */
+  float32_t y0, y1;                            /* Nearest output values */
+  float32_t xSpacing = S->xSpacing;            /* spacing between input values */
+  int32_t i;                                   /* Index variable */
+  float32_t *pYData = S->pYData;               /* pointer to output table */
+  /* Calculation of index */
+  i = (int32_t) ((x - S->x1) / xSpacing);
+  if(i < 0)
+  {
+    /* Iniatilize output for below specified range as least output value of table */
+    y = pYData[0];
+  }
+  else if((uint32_t)i >= S->nValues)
+  {
+    /* Iniatilize output for above specified range as last output value of table */
+    y = pYData[S->nValues - 1];
+  }
+  else
+  {
+    /* Calculation of nearest input values */
+    x0 = S->x1 +  i      * xSpacing;
+    x1 = S->x1 + (i + 1) * xSpacing;
+    /* Read of nearest output values */
+    y0 = pYData[i];
+    y1 = pYData[i + 1];
+    /* Calculation of output */
+    y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0));
+  }
+  /* returns output value */
+  return (y);
+}
+/**
+ * @}
+ */ // end of LinearInterpolate group
+
+/**
+ * @addtogroup LinearInterpolate
+ * @{
+ */
+
+/**
+ * @brief  Process function for the Q31 Linear Interpolation Function.
+ * @param[in] pYData   pointer to Q31 Linear Interpolation table
+ * @param[in] x        input sample to process
+ * @param[in] nValues  number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ *
+ */
+__STATIC_INLINE q31_t csky_linear_interp_q31(
+q31_t * pYData,
+q31_t x,
+uint32_t nValues)
+{
+  q31_t y;                                     /* output */
+  q31_t y0, y1;                                /* Nearest output values */
+  q31_t fract;                                 /* fractional part */
+  int32_t index;                               /* Index to read nearest output values */
+  /* Input is in 12.20 format */
+  /* 12 bits for the table index */
+  /* Index value calculation */
+  index = ((x & (q31_t)0xFFF00000) >> 20);
+  if(index >= (int32_t)(nValues - 1))
+  {
+    return (pYData[nValues - 1]);
+  }
+  else if(index < 0)
+  {
+    return (pYData[0]);
+  }
+  else
+  {
+    /* 20 bits for the fractional part */
+    /* shift left by 11 to keep fract in 1.31 format */
+    fract = (x & 0x000FFFFF) << 11;
+    /* Read two nearest output values from the index in 1.31(q31) format */
+    y0 = pYData[index];
+    y1 = pYData[index + 1];
+#ifdef CSKY_SIMD
+    /* Calculation of y0 * (1-fract) and y is in 2.30 format */
+    y = mult_32x32_keep32(y0, (0x7FFFFFFF - fract));
+    /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */
+    y = multAcc_32x32_keep32(y, y1, fract);
+#else
+    /* Calculation of y0 * (1-fract) and y is in 2.30 format */
+    y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32));
+    /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */
+    y += ((q31_t) (((q63_t) y1 * fract) >> 32));
+#endif
+    /* Convert y to 1.31 format */
+    return (y << 1u);
+  }
+}
+/**
+ * @}
+ */ // end of LinearInterpolate group
+
+/**
+ * @addtogroup LinearInterpolate
+ * @{
+ */
+/**
+ *
+ * @brief  Process function for the Q15 Linear Interpolation Function.
+ * @param[in] pYData   pointer to Q15 Linear Interpolation table
+ * @param[in] x        input sample to process
+ * @param[in] nValues  number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ *
+ */
+__STATIC_INLINE q15_t csky_linear_interp_q15(
+q15_t * pYData,
+q31_t x,
+uint32_t nValues)
+{
+  q63_t y;                                     /* output */
+  q15_t y0, y1;                                /* Nearest output values */
+  q31_t fract;                                 /* fractional part */
+  int32_t index;                               /* Index to read nearest output values */
+  /* Input is in 12.20 format */
+  /* 12 bits for the table index */
+  /* Index value calculation */
+  index = ((x & (int32_t)0xFFF00000) >> 20);
+  if(index >= (int32_t)(nValues - 1))
+  {
+    return (pYData[nValues - 1]);
+  }
+  else if(index < 0)
+  {
+    return (pYData[0]);
+  }
+  else
+  {
+    /* 20 bits for the fractional part */
+    /* fract is in 12.20 format */
+    fract = (x & 0x000FFFFF);
+    /* Read two nearest output values from the index */
+    y0 = pYData[index];
+    y1 = pYData[index + 1];
+#ifdef CSKY_SIMD
+    /* Calculation of y0 * (1-fract) and y is in 13.35 format */
+    y = mult_32x32_keep64(y0, (0xFFFFF - fract));
+    /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */
+    y = multAcc_32x32_keep64(y, y1, (fract));
+#else
+    /* Calculation of y0 * (1-fract) and y is in 13.35 format */
+    y = ((q63_t) y0 * (0xFFFFF - fract));
+    /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */
+    y += ((q63_t) y1 * (fract));
+#endif
+    /* convert y to 1.15 format */
+    return (q15_t) (y >> 20);
+  }
+}
+/**
+ * @}
+ */ // end of LinearInterpolate group
+
+/**
+ * @addtogroup LinearInterpolate
+ * @{
+ */
+/**
+ *
+ * @brief  Process function for the Q7 Linear Interpolation Function.
+ * @param[in] pYData   pointer to Q7 Linear Interpolation table
+ * @param[in] x        input sample to process
+ * @param[in] nValues  number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ */
+__STATIC_INLINE q7_t csky_linear_interp_q7(
+q7_t * pYData,
+q31_t x,
+uint32_t nValues)
+{
+  q31_t y;                                     /* output */
+  q7_t y0, y1;                                 /* Nearest output values */
+  q31_t fract;                                 /* fractional part */
+  uint32_t index;                              /* Index to read nearest output values */
+  /* Input is in 12.20 format */
+  /* 12 bits for the table index */
+  /* Index value calculation */
+  if (x < 0)
+  {
+    return (pYData[0]);
+  }
+  index = (x >> 20) & 0xfff;
+  if(index >= (nValues - 1))
+  {
+    return (pYData[nValues - 1]);
+  }
+  else
+  {
+    /* 20 bits for the fractional part */
+    /* fract is in 12.20 format */
+    fract = (x & 0x000FFFFF);
+    /* Read two nearest output values from the index and are in 1.7(q7) format */
+    y0 = pYData[index];
+    y1 = pYData[index + 1];
+    /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */
+    y = ((y0 * (0xFFFFF - fract)));
+    /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */
+    y += (y1 * fract);
+    /* convert y to 1.7(q7) format */
+    return (q7_t) (y >> 20);
+   }
+}
+/**
+ * @}
+ */ // end of LinearInterpolate group
+
+  float32_t csky_sin_f32(
+  float32_t x);
+
+  q31_t csky_sin_q31(
+  q31_t x);
+
+  q15_t csky_sin_q15(
+  q15_t x);
+
+  float32_t csky_cos_f32(
+  float32_t x);
+
+  q31_t csky_cos_q31(
+  q31_t x);
+
+  q15_t csky_cos_q15(
+  q15_t x);
+
+  csky_status csky_sqrt_f32(
+  float32_t in,
+  float32_t * pOut);
+
+  csky_status csky_sqrt_q31(
+  q31_t in,
+  q31_t * pOut);
+
+  csky_status csky_sqrt_q15(
+  q15_t in,
+  q15_t * pOut);
+
+  /*double format*/
+  typedef union _myNumber
+  {
+    q31_t  i[2];
+    float64_t x;
+  }mynumber;
+
+  /* the coefficient for log2 table looh up*/
+  typedef union
+  {
+    q31_t i[5800];
+    float64_t x[2900];
+  }log2_cof1;
+
+  typedef union
+  {
+    q31_t i[4350];
+    float64_t x[2175];
+  }log2_cof2;
+
+  /* the coefficient for exp table looh up*/
+ typedef union
+  {
+    q31_t i[1424];
+    float64_t x[712];
+  }exp_cof1;
+
+  typedef union
+  {
+    q31_t i[2048];
+    float64_t x[1024];
+  }exp_cof2;
+
+  union ieee754_double
+  {
+    float64_t d;
+
+    struct
+      {
+        unsigned int mantissa1:32;
+        unsigned int mantissa0:20;
+        unsigned int exponent:11;
+        unsigned int negative:1;
+      } ieee;
+    struct
+      {
+        unsigned int mantissa1:32;
+        unsigned int mantissa0:19;
+        unsigned int quiet_nan:1;
+        unsigned int exponent:11;
+        unsigned int negative:1;
+      } ieee_nan;
+  };
+
+  typedef struct
+  {
+    q31_t e;
+    long  d[40];
+  }mp_no;
+
+  float64_t csky_pow_f64(
+  float64_t x,
+  float64_t y);
+
+  float64_t csky_log_f64(
+  float64_t x);
+
+  float64_t csky_exp_f64(
+  float64_t x);
+
+  float64_t csky_pow2_f64(
+  float64_t x);
+
+  float64_t csky_log2_f64(
+  float64_t x);
+
+  float64_t csky_log10_f64(
+  float64_t x);
+
+  void csky_power_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+  void csky_power_int32(
+  int32_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+  void csky_power_int32(
+  int32_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+  void csky_power_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  void csky_power_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+  void csky_power_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  void csky_mean_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * pResult);
+
+  void csky_mean_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+  void csky_mean_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  void csky_mean_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  void csky_var_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  void csky_var_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  void csky_var_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+  void csky_rms_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  void csky_rms_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  void csky_rms_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+  void csky_std_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  void csky_std_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  void csky_std_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+  void csky_cmplx_mag_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mag_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mag_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_dot_prod_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  uint32_t numSamples,
+  q31_t * realResult,
+  q31_t * imagResult);
+
+  void csky_cmplx_dot_prod_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  uint32_t numSamples,
+  q63_t * realResult,
+  q63_t * imagResult);
+
+  void csky_cmplx_dot_prod_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  uint32_t numSamples,
+  float32_t * realResult,
+  float32_t * imagResult);
+
+  void csky_cmplx_mult_real_q15(
+  q15_t * pSrcCmplx,
+  q15_t * pSrcReal,
+  q15_t * pCmplxDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mult_real_q31(
+  q31_t * pSrcCmplx,
+  q31_t * pSrcReal,
+  q31_t * pCmplxDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mult_real_f32(
+  float32_t * pSrcCmplx,
+  float32_t * pSrcReal,
+  float32_t * pCmplxDst,
+  uint32_t numSamples);
+
+  void csky_min_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * result,
+  uint32_t * index);
+
+  void csky_min_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_min_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_min_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_max_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_max_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_max_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_max_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_cmplx_mult_cmplx_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mult_cmplx_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mult_cmplx_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mult_cmplx_re_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mult_cmplx_re_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  void csky_cmplx_mult_cmplx_re_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+
+  void csky_float_to_q31(
+  float32_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_float_to_q15(
+  float32_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_float_to_q7(
+  float32_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_q31_to_q15(
+  q31_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_q31_to_q7(
+  q31_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_q15_to_float(
+  q15_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_q15_to_q31(
+  q15_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_q15_to_q7(
+  q15_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+/**
+ * @ingroup groupInterpolation
+ */
+/**
+ * @defgroup BilinearInterpolate Bilinear Interpolation
+ *
+ * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid.
+ * The underlying function <code>f(x, y)</code> is sampled on a regular grid and the interpolation process
+ * determines values between the grid points.
+ * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension.
+ * Bilinear interpolation is often used in image processing to rescale images.
+ * The CSI DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types.
+ *
+ * <b>Algorithm</b>
+ * \par
+ * The instance structure used by the bilinear interpolation functions describes a two dimensional data table.
+ * For floating-point, the instance structure is defined as:
+ * <pre>
+ *   typedef struct
+ *   {
+ *     uint16_t numRows;
+ *     uint16_t numCols;
+ *     float32_t *pData;
+ * } csky_bilinear_interp_instance_f32;
+ * </pre>
+ *
+ * \par
+ * where <code>numRows</code> specifies the number of rows in the table;
+ * <code>numCols</code> specifies the number of columns in the table;
+ * and <code>pData</code> points to an array of size <code>numRows*numCols</code> values.
+ * The data table <code>pTable</code> is organized in row order and the supplied data values fall on integer indexes.
+ * That is, table element (x,y) is located at <code>pTable[x + y*numCols]</code> where x and y are integers.
+ *
+ * \par
+ * Let <code>(x, y)</code> specify the desired interpolation point.  Then define:
+ * <pre>
+ *     XF = floor(x)
+ *     YF = floor(y)
+ * </pre>
+ * \par
+ * The interpolated output point is computed as:
+ * <pre>
+ *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+ *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+ *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+ *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+ * </pre>
+ * Note that the coordinates (x, y) contain integer and fractional components.
+ * The integer components specify which portion of the table to use while the
+ * fractional components control the interpolation processor.
+ *
+ * \par
+ * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output.
+ */
+/**
+ * @addtogroup BilinearInterpolate
+ * @{
+ */
+/**
+*
+* @brief  Floating-point bilinear interpolation.
+* @param[in,out] S  points to an instance of the interpolation structure.
+* @param[in]     X  interpolation coordinate.
+* @param[in]     Y  interpolation coordinate.
+* @return out interpolated value.
+*/
+__STATIC_INLINE float32_t csky_bilinear_interp_f32(
+const csky_bilinear_interp_instance_f32 * S,
+float32_t X,
+float32_t Y)
+{
+  float32_t out;
+  float32_t f00, f01, f10, f11;
+  float32_t *pData = S->pData;
+  int32_t xIndex, yIndex, index;
+  float32_t xdiff, ydiff;
+  float32_t b1, b2, b3, b4;
+  xIndex = (int32_t) X;
+  yIndex = (int32_t) Y;
+  /* Care taken for table outside boundary */
+  /* Returns zero output when values are outside table boundary */
+  if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1))
+  {
+    return (0);
+  }
+  /* Calculation of index for two nearest points in X-direction */
+  index = (xIndex - 1) + (yIndex - 1) * S->numCols;
+  /* Read two nearest points in X-direction */
+  f00 = pData[index];
+  f01 = pData[index + 1];
+  /* Calculation of index for two nearest points in Y-direction */
+  index = (xIndex - 1) + (yIndex) * S->numCols;
+  /* Read two nearest points in Y-direction */
+  f10 = pData[index];
+  f11 = pData[index + 1];
+  /* Calculation of intermediate values */
+  b1 = f00;
+  b2 = f01 - f00;
+  b3 = f10 - f00;
+  b4 = f00 - f01 - f10 + f11;
+  /* Calculation of fractional part in X */
+  xdiff = X - xIndex;
+  /* Calculation of fractional part in Y */
+  ydiff = Y - yIndex;
+  /* Calculation of bi-linear interpolated output */
+  out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff;
+  /* return to application */
+  return (out);
+}
+/**
+ * @}
+ */ // end of BilinearInterpolate group
+
+/**
+ * @addtogroup BilinearInterpolate
+ * @{
+ */
+/**
+*
+* @brief  Q31 bilinear interpolation.
+* @param[in,out] S  points to an instance of the interpolation structure.
+* @param[in]     X  interpolation coordinate in 12.20 format.
+* @param[in]     Y  interpolation coordinate in 12.20 format.
+* @return out interpolated value.
+*/
+__STATIC_INLINE q31_t csky_bilinear_interp_q31(
+csky_bilinear_interp_instance_q31 * S,
+q31_t X,
+q31_t Y)
+{
+  q31_t out;                                   /* Temporary output */
+  q31_t acc = 0;                               /* output */
+  q31_t xfract, yfract;                        /* X, Y fractional parts */
+  q31_t x1, x2, y1, y2;                        /* Nearest output values */
+  int32_t rI, cI;                              /* Row and column indices */
+  q31_t *pYData = S->pData;                    /* pointer to output table values */
+  uint32_t nCols = S->numCols;                 /* num of rows */
+  /* Input is in 12.20 format */
+  /* 12 bits for the table index */
+  /* Index value calculation */
+  rI = ((X & (q31_t)0xFFF00000) >> 20);
+  /* Input is in 12.20 format */
+  /* 12 bits for the table index */
+  /* Index value calculation */
+  cI = ((Y & (q31_t)0xFFF00000) >> 20);
+  /* Care taken for table outside boundary */
+  /* Returns zero output when values are outside table boundary */
+  if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+  {
+    return (0);
+  }
+  /* 20 bits for the fractional part */
+  /* shift left xfract by 11 to keep 1.31 format */
+  xfract = (X & 0x000FFFFF) << 11u;
+  /* Read two nearest output values from the index */
+  x1 = pYData[(rI) + (int32_t)nCols * (cI)    ];
+  x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1];
+  /* 20 bits for the fractional part */
+  /* shift left yfract by 11 to keep 1.31 format */
+  yfract = (Y & 0x000FFFFF) << 11u;
+  /* Read two nearest output values from the index */
+  y1 = pYData[(rI) + (int32_t)nCols * (cI + 1)    ];
+  y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1];
+#ifdef CSKY_SIMD
+  /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */
+  out = mult_32x32_keep32(x1, (0x7FFFFFFF - xfract));
+  acc = mult_32x32_keep32(out, (0x7FFFFFFF - yfract));
+  /* x2 * (xfract) * (1-yfract)  in 3.29(q29) and adding to acc */
+  out = mult_32x32_keep32(x2, (0x7FFFFFFF - yfract));
+  acc = multAcc_32x32_keep32(acc, out, xfract);
+  /* y1 * (1 - xfract) * (yfract)  in 3.29(q29) and adding to acc */
+  out = mult_32x32_keep32(y1,  (0x7FFFFFFF - xfract));
+  acc = multAcc_32x32_keep32(acc, out, yfract);
+  /* y2 * (xfract) * (yfract)  in 3.29(q29) and adding to acc */
+  out = mult_32x32_keep32(y2, xfract);
+  acc = multAcc_32x32_keep32(acc, out, yfract);
+#else
+  /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */
+  out = ((q31_t) (((q63_t) x1  * (0x7FFFFFFF - xfract)) >> 32));
+  acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32));
+  /* x2 * (xfract) * (1-yfract)  in 3.29(q29) and adding to acc */
+  out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32));
+  acc += ((q31_t) ((q63_t) out * (xfract) >> 32));
+  /* y1 * (1 - xfract) * (yfract)  in 3.29(q29) and adding to acc */
+  out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32));
+  acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+  /* y2 * (xfract) * (yfract)  in 3.29(q29) and adding to acc */
+  out = ((q31_t) ((q63_t) y2 * (xfract) >> 32));
+  acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+#endif
+  /* Convert acc to 1.31(q31) format */
+  return ((q31_t)(acc << 2));
+}
+/**
+ * @}
+ */ // end of BilinearInterpolate group
+
+/**
+ * @addtogroup BilinearInterpolate
+ * @{
+ */
+/**
+* @brief  Q15 bilinear interpolation.
+* @param[in,out] S  points to an instance of the interpolation structure.
+* @param[in]     X  interpolation coordinate in 12.20 format.
+* @param[in]     Y  interpolation coordinate in 12.20 format.
+* @return out interpolated value.
+*/
+__STATIC_INLINE q15_t csky_bilinear_interp_q15(
+csky_bilinear_interp_instance_q15 * S,
+q31_t X,
+q31_t Y)
+{
+  q63_t acc = 0;                               /* output */
+  q31_t out;                                   /* Temporary output */
+  q15_t x1, x2, y1, y2;                        /* Nearest output values */
+  q31_t xfract, yfract;                        /* X, Y fractional parts */
+  int32_t rI, cI;                              /* Row and column indices */
+  q15_t *pYData = S->pData;                    /* pointer to output table values */
+  uint32_t nCols = S->numCols;                 /* num of rows */
+  /* Input is in 12.20 format */
+  /* 12 bits for the table index */
+  /* Index value calculation */
+  rI = ((X & (q31_t)0xFFF00000) >> 20);
+  /* Input is in 12.20 format */
+  /* 12 bits for the table index */
+  /* Index value calculation */
+  cI = ((Y & (q31_t)0xFFF00000) >> 20);
+  /* Care taken for table outside boundary */
+  /* Returns zero output when values are outside table boundary */
+  if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+  {
+    return (0);
+  }
+  /* 20 bits for the fractional part */
+  /* xfract should be in 12.20 format */
+  xfract = (X & 0x000FFFFF);
+  /* Read two nearest output values from the index */
+  x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI)    ];
+  x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1];
+  /* 20 bits for the fractional part */
+  /* yfract should be in 12.20 format */
+  yfract = (Y & 0x000FFFFF);
+  /* Read two nearest output values from the index */
+  y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1)    ];
+  y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1];
+  /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */
+  /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */
+  /* convert 13.35 to 13.31 by right shifting  and out is in 1.31 */
+#ifdef CSKY_SIMD
+  out = mult_32x32_dext_4(x1, (0xFFFFF - xfract));
+  acc = mult_32x32_keep64(out, (0xFFFFF - yfract));
+  /* x2 * (xfract) * (1-yfract)  in 1.51 and adding to acc */
+  out = mult_32x32_dext_4(x2, (0xFFFFF - yfract));
+  acc = multAcc_32x32_keep64(acc, out, (xfract));
+  /* y1 * (1 - xfract) * (yfract)  in 1.51 and adding to acc */
+  out = mult_32x32_dext_4(y1, (0xFFFFF - xfract));
+  acc = multAcc_32x32_keep64(acc, out, (yfract));
+  /* y2 * (xfract) * (yfract)  in 1.51 and adding to acc */
+  out = mult_32x32_dext_4(y2, (xfract));
+  acc = multAcc_32x32_keep64(acc, out, (yfract));
+#else
+  out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u);
+  acc = ((q63_t) out * (0xFFFFF - yfract));
+  /* x2 * (xfract) * (1-yfract)  in 1.51 and adding to acc */
+  out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u);
+  acc += ((q63_t) out * (xfract));
+  /* y1 * (1 - xfract) * (yfract)  in 1.51 and adding to acc */
+  out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u);
+  acc += ((q63_t) out * (yfract));
+  /* y2 * (xfract) * (yfract)  in 1.51 and adding to acc */
+  out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u);
+  acc += ((q63_t) out * (yfract));
+#endif
+  /* acc is in 13.51 format and down shift acc by 36 times */
+  /* Convert out to 1.15 format */
+  return ((q15_t)(acc >> 36));
+}
+/**
+ * @}
+ */ // end of BilinearInterpolate group
+
+void test(q7_t *pSrc, q7_t *pDst);
+
+/**
+ * @addtogroup BilinearInterpolate
+ * @{
+ */
+/**
+* @brief  Q7 bilinear interpolation.
+* @param[in,out] S  points to an instance of the interpolation structure.
+* @param[in]     X  interpolation coordinate in 12.20 format.
+* @param[in]     Y  interpolation coordinate in 12.20 format.
+* @return out interpolated value.
+*/
+__STATIC_INLINE q7_t csky_bilinear_interp_q7(
+csky_bilinear_interp_instance_q7 * S,
+q31_t X,
+q31_t Y)
+{
+  q63_t acc = 0;                               /* output */
+  q31_t out;                                   /* Temporary output */
+  q31_t xfract, yfract;                        /* X, Y fractional parts */
+  q7_t x1, x2, y1, y2;                         /* Nearest output values */
+  int32_t rI, cI;                              /* Row and column indices */
+  q7_t *pYData = S->pData;                     /* pointer to output table values */
+  uint32_t nCols = S->numCols;                 /* num of rows */
+  /* Input is in 12.20 format */
+  /* 12 bits for the table index */
+  /* Index value calculation */
+  rI = ((X & (q31_t)0xFFF00000) >> 20);
+  /* Input is in 12.20 format */
+  /* 12 bits for the table index */
+  /* Index value calculation */
+  cI = ((Y & (q31_t)0xFFF00000) >> 20);
+  /* Care taken for table outside boundary */
+  /* Returns zero output when values are outside table boundary */
+  if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+  {
+    return (0);
+  }
+  /* 20 bits for the fractional part */
+  /* xfract should be in 12.20 format */
+  xfract = (X & (q31_t)0x000FFFFF);
+  /* Read two nearest output values from the index */
+  x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI)    ];
+  x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1];
+  /* 20 bits for the fractional part */
+  /* yfract should be in 12.20 format */
+  yfract = (Y & (q31_t)0x000FFFFF);
+  /* Read two nearest output values from the index */
+  y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1)    ];
+  y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1];
+  /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */
+  out = ((x1 * (0xFFFFF - xfract)));
+#ifdef CSKY_SIMD
+  acc = multAcc_32x32_keep64(acc, out, (0xFFFFF - yfract));
+  /* x2 * (xfract) * (1-yfract)  in 2.22 and adding to acc */
+  out = ((x2 * (0xFFFFF - yfract)));
+  acc = multAcc_32x32_keep64(acc, out, xfract);
+  /* y1 * (1 - xfract) * (yfract)  in 2.22 and adding to acc */
+  out = ((y1 * (0xFFFFF - xfract)));
+  acc = multAcc_32x32_keep64(acc, out, yfract);
+  /* y2 * (xfract) * (yfract)  in 2.22 and adding to acc */
+  out = ((y2 * (yfract)));
+  acc = multAcc_32x32_keep64(acc, out, xfract);
+#else
+  acc = (((q63_t) out * (0xFFFFF - yfract)));
+  /* x2 * (xfract) * (1-yfract)  in 2.22 and adding to acc */
+  out = ((x2 * (0xFFFFF - yfract)));
+  acc += (((q63_t) out * (xfract)));
+  /* y1 * (1 - xfract) * (yfract)  in 2.22 and adding to acc */
+  out = ((y1 * (0xFFFFF - xfract)));
+  acc += (((q63_t) out * (yfract)));
+  /* y2 * (xfract) * (yfract)  in 2.22 and adding to acc */
+  out = ((y2 * (yfract)));
+  acc += (((q63_t) out * (xfract)));
+#endif
+  /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */
+  return ((q7_t)(acc >> 40));
+}
+/**
+ * @}
+ */ // end of BilinearInterpolate group
+
+/**
+ * @ingroup groupMath
+ */
+
+/**
+ * @defgroup ShiftRight Right Shift
+ *
+ * Shift the input value to right with appointed bits, its basic format is:
+ * <pre>
+ *     a = (a) >> (shift),   1 =< shift <= bitof(a) - 1.
+ * </pre>
+ * The basic format is only designed for q31.
+ *
+ * and the extended format should be rounding to +inf:
+ * <pre>
+ *     a = (a + (1<<(shift - 1)) >> (shift),   1 =< shift <= bitof(a) - 1.
+ * </pre>
+ *
+ * which are designed for q31, q31 positive and q63.
+ */
+
+/**
+ * @addtogroup ShiftRight
+ * @{
+ */
+/**
+ * @brief  right shift Q31 version
+ * @param[in]  a        input value to be shift.
+ * @param[in]  shift    input positive value, the number of bits to be shift.
+ * @param[out] result   the shifted a.
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is only used for right shift. So, the value of shift is
+ * between[1,31].
+ */
+  __STATIC_INLINE q31_t csky_shr_q31(
+  q31_t a,
+  q31_t shift)
+{
+  q31_t res;
+#ifdef CSKY_SIMD
+  __ASM volatile(
+                "asr        %0, %1, %2\n\t"
+                :"=r"(res), "=r"(a),"=r"(shift):"0"(res), "1"(a), "2"(shift));
+#else
+  res =  ((a) >> (shift));
+#endif
+  return res;
+}
+
+#define SHR(a, shift)                 csky_shr_q31(a, shift)
+
+/**
+ * @}
+ */ // end of ShiftRight group
+
+
+/**
+ * @addtogroup ShiftRight
+ * @{
+ */
+/**
+ * @brief  right shift Q31 version
+ * @param[in]  a        input value to be shift.
+ * @param[in]  shift    input positive value, the number of bits to be shift.
+ * @param[out] result   the shifted a.
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is only used for right shift. So, the value of shift is
+ * between[1,31]. And the output value is rounding to +inf.
+ */
+  __STATIC_INLINE q31_t csky_pshr_q31(
+  q31_t a,
+  q31_t shift)
+{
+  q31_t res;
+#ifdef CSKY_SIMD
+  __ASM volatile(
+                "asr.s32.r  %0, %1, %2\n\t"
+                :"=r"(res), "=r"(a),"=r"(shift):"0"(res), "1"(a), "2"(shift));
+#else
+  res =  (a >= 0?(SHR((a) + (1<<(shift - 1)), shift))\
+               :(SHR((a) + ((1<<shift)>>1) -1, shift)));
+#endif
+  return res;
+}
+
+/**
+ * @}
+ */ // end of ShiftRight group
+
+
+/**
+ * @addtogroup ShiftRight
+ * @{
+ */
+/**
+ * @brief  right shift Q31 version
+ * @param[in]  a        input positive value to be shift.
+ * @param[in]  shift    input positive value, the number of bits to be shift.
+ * @param[out] result   the shifted a.
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is only used for right shift. So, the value of shift is
+ * between[1,31]. And the output value is rounding to +inf.
+ */
+  __STATIC_INLINE q31_t csky_pshr_pos_q31(
+  q31_t a,
+  q31_t shift)
+{
+  q31_t res;
+#ifdef CSKY_SIMD
+  __ASM volatile(
+                "asr.s32.r  %0, %1, %2\n\t"
+                :"=r"(res), "=r"(a),"=r"(shift):"0"(res), "1"(a), "2"(shift));
+#else
+  res = SHR((a) + (1<<(shift - 1)), shift);
+#endif
+  return res;
+}
+
+/**
+ * @}
+ */ // end of ShiftRight group
+
+
+/**
+ * @addtogroup ShiftRight
+ * @{
+ */
+/**
+ * @brief  right shift Q63 version
+ * @param[in]  a        input value to be shift.
+ * @param[in]  shift    input positive value, the number of bits to be shift.
+ * @param[out] result   the shifted a.
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is only used for right shift. So, the value of shift is
+ * between[1,63]. And the output value is rounding to +inf.
+ */
+  __STATIC_INLINE q63_t csky_pshr_q63(
+  q63_t a,
+  q31_t shift)
+{
+  q63_t res;
+#ifdef CSKY_SIMD
+  __ASM volatile(
+                "subi       t0, %2, 1\n\t"
+                "cmphsi     t0, 32\n\t"
+                "bt         1f\n\t"
+                "movi       t1, 1\n\t"
+                "lsl        t0, t1, t0\n\t"
+                "movi       t1, 0\n\t"
+                "add.s64.s  %1, %1, t0\n\t"
+                "dext       %0, %1, %R1, %2\n\t"
+                "asr        %R0, %R1, %2\n\t"
+                "br         2f\n\t"
+                "1:\n\t"
+                "subi       %2, %2, 32\n\t"
+                "subi       t0, t0, 32\n\t"
+                "movi       t1, 1\n\t"
+                "lsl        t1, t1, t0\n\t"
+                "add.s32.s  %R1, %R1, t1\n\t"
+                "asr        %0, %R1, %2\n\t"
+                "asri       %R0, %R1, 31\n\t"
+                "2:\n\t"
+                :"=r"(res), "=r"(a),"=r"(shift):"0"(res), "1"(a), "2"(shift):"t0", "t1");
+#else
+  res =  (a >= 0?(SHR((a) + ((q63_t)1<<(shift - 1)), shift))\
+               :(SHR((a) + (((q63_t)1<<shift)>>1) -1, shift)));
+#endif
+  return res;
+}
+
+/**
+ * @}
+ */ // end of ShiftRight group
+
+//#define SHR(a, shift)                 csky_shr_q31(a, shift)
+#define PSHR(a, shift)                csky_pshr_q31(a, shift)
+#define PSHR_POSITIVE(a, shift)       csky_pshr_pos_q31(a, shift)
+#define PSHR64(a, shift)              csky_pshr_q63(a, shift)
+
+
+#ifdef CSKY_SIMD
+#else
+/* SMMLAR */
+#define multAcc_32x32_keep32_R(a, x, y) \
+    a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+/* SMMLSR */
+#define multSub_32x32_keep32_R(a, x, y) \
+    a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+/* SMMULR */
+#define mult_32x32_keep32_R(a, x, y) \
+    a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32)
+
+/* SMMLA */
+#define multAcc_32x32_keep32(a, x, y) \
+    a += (q31_t) (((q63_t) x * y) >> 32)
+
+/* SMMLS */
+#define multSub_32x32_keep32(a, x, y) \
+    a -= (q31_t) (((q63_t) x * y) >> 32)
+
+/* SMMUL */
+#define mult_32x32_keep32(a, x, y) \
+    a = (q31_t) (((q63_t) x * y ) >> 32)
+#endif
+
+#ifdef   __cplusplus
+}
+#endif
+
+#endif /* _CSKY_MATH_H */
+
+/**
+ *
+ * End of file.
+ */

+ 140 - 0
include/arch/xt804/csi_dsp/csky_vdsp2_const_structs.h

@@ -0,0 +1,140 @@
+/******************************************************************************
+ * @file     csky_vdsp2_const_structs.h
+ * @brief    This file has constant structs that are initialized for
+ *           user convenience.  For example, some can be given as
+ *           arguments to the csky_vdsp2_cfft_f32() function.
+ * @version  V1.0
+ * @date     20. Dec 2016
+ ******************************************************************************/
+/* ---------------------------------------------------------------------------
+ * Copyright (C) 2016 CSKY Limited. All rights reserved.
+ *
+ * Redistribution and use of this software 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 CSKY Ltd. nor the names of CSKY's contributors may
+ *     be used to endorse or promote products derived from this software without
+ *     specific prior written permission of CSKY Ltd.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ * -------------------------------------------------------------------------- */
+
+#ifndef _CSKY_CONST_STRUCTS_H
+#define _CSKY_CONST_STRUCTS_H
+
+#include "csky_vdsp2_math.h"
+#include "csky_common_tables.h"
+
+   extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len16;
+   extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len32;
+   extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len64;
+   extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len128;
+   extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len256;
+   extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len512;
+   extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len1024;
+   extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len2048;
+   extern const csky_vdsp2_cfft_instance_f32 csky_vdsp2_cfft_sR_f32_len4096;
+
+   extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len16;
+   extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len32;
+   extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len64;
+   extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len128;
+   extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len256;
+   extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len512;
+   extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len1024;
+   extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len2048;
+   extern const csky_vdsp2_cfft_instance_q31 csky_vdsp2_cfft_sR_q31_len4096;
+
+   extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len16;
+   extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len32;
+   extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len64;
+   extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len128;
+   extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len256;
+   extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len512;
+   extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len1024;
+   extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len2048;
+   extern const csky_vdsp2_cfft_instance_q15 csky_vdsp2_cfft_sR_q15_len4096;
+
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len32;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len64;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len128;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len256;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len512;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len1024;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len2048;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len4096;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_rfft_sR_q15_len8192;
+
+
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len32;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len64;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len128;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len256;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len512;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len1024;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len2048;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len4096;
+   extern csky_vdsp2_rfft_instance_q15 csky_vdsp2_inv_rfft_sR_q15_len8192;
+
+
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len32;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len64;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len128;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len256;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len512;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len1024;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len2048;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len4096;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_rfft_sR_q31_len8192;
+
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len32;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len64;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len128;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len256;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len512;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len1024;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len2048;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len4096;
+   extern csky_vdsp2_rfft_instance_q31 csky_vdsp2_inv_rfft_sR_q31_len8192;
+
+
+   extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len32;
+   extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len64;
+   extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len128;
+   extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len256;
+   extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len512;
+   extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len1024;
+   extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len2048;
+   extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len4096;
+   extern csky_vdsp2_rfft_fast_instance_f32 csky_vdsp2_rfft_sR_f32_len8192;
+
+   extern csky_vdsp2_dct4_instance_q15 csky_vdsp2_dct4_sR_q15_len128;
+   extern csky_vdsp2_dct4_instance_q15 csky_vdsp2_dct4_sR_q15_len512;
+   extern csky_vdsp2_dct4_instance_q15 csky_vdsp2_dct4_sR_q15_len2048;
+   extern csky_vdsp2_dct4_instance_q15 csky_vdsp2_dct4_sR_q15_len8192;
+
+   extern csky_vdsp2_dct4_instance_q31 csky_vdsp2_dct4_sR_q31_len128;
+   extern csky_vdsp2_dct4_instance_q31 csky_vdsp2_dct4_sR_q31_len512;
+   extern csky_vdsp2_dct4_instance_q31 csky_vdsp2_dct4_sR_q31_len2048;
+   extern csky_vdsp2_dct4_instance_q31 csky_vdsp2_dct4_sR_q31_len8192;
+
+   extern csky_vdsp2_dct4_instance_f32 csky_vdsp2_dct4_sR_f32_len128;
+   extern csky_vdsp2_dct4_instance_f32 csky_vdsp2_dct4_sR_f32_len512;
+   extern csky_vdsp2_dct4_instance_f32 csky_vdsp2_dct4_sR_f32_len2048;
+   extern csky_vdsp2_dct4_instance_f32 csky_vdsp2_dct4_sR_f32_len8192;
+#endif

+ 2291 - 0
include/arch/xt804/csi_dsp/csky_vdsp2_math.h

@@ -0,0 +1,2291 @@
+/******************************************************************************
+ * @file     csky_vdsp2_math.h
+ * @brief    Public header file for CSI DSP Library.
+ * @version  V1.0
+ * @date     20. Dec 2016
+ ******************************************************************************/
+/* ---------------------------------------------------------------------------
+ * Copyright (C) 2016 CSKY Limited. All rights reserved.
+ *
+ * Redistribution and use of this software 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 CSKY Ltd. nor the names of CSKY's contributors may
+ *     be used to endorse or promote products derived from this software without
+ *     specific prior written permission of CSKY Ltd.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ * -------------------------------------------------------------------------- */
+
+#ifndef _CSKY_VDSP2_MATH_H
+#define _CSKY_VDSP2_MATH_H
+
+#include "csky_math.h"
+
+#ifdef   __cplusplus
+extern "C"
+{
+#endif
+
+  /**
+   * @brief Error status returned by some functions in the library.
+   */
+
+  typedef enum
+  {
+    CSKY_VDSP2_MATH_SUCCESS = 0,                /**< No error */
+    CSKY_VDSP2_MATH_ARGUMENT_ERROR = -1,        /**< One or more arguments are incorrect */
+    CSKY_VDSP2_MATH_LENGTH_ERROR = -2,          /**< Length of data buffer is incorrect */
+    CSKY_VDSP2_MATH_SIZE_MISMATCH = -3,         /**< Size of matrices is not compatible with the operation. */
+    CSKY_VDSP2_MATH_NANINF = -4,                /**< Not-a-number (NaN) or infinity is generated */
+    CSKY_VDSP2_MATH_SINGULAR = -5,              /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */
+    CSKY_VDSP2_MATH_TEST_FAILURE = -6           /**< Test Failed  */
+  } csky_vdsp2_status;
+
+  /**
+   * @brief Instance structure for the Q7 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;        /**< number of filter coefficients in the filter. */
+    q7_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q7_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+  } csky_vdsp2_fir_instance_q7;
+
+  /**
+   * @brief Instance structure for the Q15 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;         /**< number of filter coefficients in the filter. */
+    q15_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+  } csky_vdsp2_fir_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;         /**< number of filter coefficients in the filter. */
+    q31_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps. */
+  } csky_vdsp2_fir_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of filter coefficients in the filter. */
+    float32_t *pState;    /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;   /**< points to the coefficient array. The array is of length numTaps. */
+  } csky_vdsp2_fir_instance_f32;
+
+  void csky_vdsp2_fir_q7(
+  const csky_vdsp2_fir_instance_q7 * S,
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_init_q7(
+  csky_vdsp2_fir_instance_q7 * S,
+  uint16_t numTaps,
+  q7_t * pCoeffs,
+  q7_t * pState,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_q15(
+  const csky_vdsp2_fir_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_fast_q15(
+  const csky_vdsp2_fir_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  csky_vdsp2_status csky_vdsp2_fir_init_q15(
+  csky_vdsp2_fir_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_q31(
+  const csky_vdsp2_fir_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_fast_q31(
+  const csky_vdsp2_fir_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_init_q31(
+  csky_vdsp2_fir_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_f32(
+  const csky_vdsp2_fir_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_init_f32(
+  csky_vdsp2_fir_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    int8_t numStages;        /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q15_t *pState;           /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    q15_t *pCoeffs;          /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+    int8_t postShift;        /**< Additional shift, in bits, applied to each output sample. */
+  } csky_vdsp2_biquad_casd_df1_inst_q15;
+
+  /**
+   * @brief Instance structure for the Q31 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint32_t numStages;      /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q31_t *pState;           /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    q31_t *pCoeffs;          /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+    uint8_t postShift;       /**< Additional shift, in bits, applied to each output sample. */
+  } csky_vdsp2_biquad_casd_df1_inst_q31;
+
+ /**
+   * @brief Instance structure for the Q31 Biquad cascade filter.
+   */
+
+  /**
+   * @brief Instance structure for the floating-point Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint32_t numStages;      /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;       /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    float32_t *pCoeffs;      /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+  } csky_vdsp2_biquad_casd_df1_inst_f32;
+
+  void csky_vdsp2_biquad_cascade_df1_q15(
+  const csky_vdsp2_biquad_casd_df1_inst_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_biquad_cascade_df1_init_q15(
+  csky_vdsp2_biquad_casd_df1_inst_q15 * S,
+  uint8_t numStages,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  int8_t postShift);
+
+  void csky_vdsp2_biquad_cascade_df1_fast_q15(
+  const csky_vdsp2_biquad_casd_df1_inst_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_biquad_cascade_df1_q31(
+  const csky_vdsp2_biquad_casd_df1_inst_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_biquad_cascade_df1_fast_q31(
+  const csky_vdsp2_biquad_casd_df1_inst_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_biquad_cascade_df1_init_q31(
+  csky_vdsp2_biquad_casd_df1_inst_q31 * S,
+  uint8_t numStages,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  int8_t postShift);
+
+  void csky_vdsp2_biquad_cascade_df1_f32(
+  const csky_vdsp2_biquad_casd_df1_inst_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_biquad_cascade_df1_init_f32(
+  csky_vdsp2_biquad_casd_df1_inst_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  /**
+   * @brief Instance structure for the floating-point matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    float32_t *pData;     /**< points to the data of the matrix. */
+  } csky_vdsp2_matrix_instance_f32;
+
+
+  /**
+   * @brief Instance structure for the floating-point matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    float64_t *pData;     /**< points to the data of the matrix. */
+  } csky_vdsp2_matrix_instance_f64;
+
+  /**
+   * @brief Instance structure for the Q15 matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    q15_t *pData;         /**< points to the data of the matrix. */
+  } csky_vdsp2_matrix_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 matrix structure.
+   */
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    q31_t *pData;         /**< points to the data of the matrix. */
+  } csky_vdsp2_matrix_instance_q31;
+
+  csky_vdsp2_status csky_vdsp2_mat_add_f32(
+  const csky_vdsp2_matrix_instance_f32 * pSrcA,
+  const csky_vdsp2_matrix_instance_f32 * pSrcB,
+  csky_vdsp2_matrix_instance_f32 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_add_q15(
+  const csky_vdsp2_matrix_instance_q15 * pSrcA,
+  const csky_vdsp2_matrix_instance_q15 * pSrcB,
+  csky_vdsp2_matrix_instance_q15 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_add_q31(
+  const csky_vdsp2_matrix_instance_q31 * pSrcA,
+  const csky_vdsp2_matrix_instance_q31 * pSrcB,
+  csky_vdsp2_matrix_instance_q31 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_cmplx_mult_f32(
+  const csky_vdsp2_matrix_instance_f32 * pSrcA,
+  const csky_vdsp2_matrix_instance_f32 * pSrcB,
+  csky_vdsp2_matrix_instance_f32 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_cmplx_mult_q15(
+  const csky_vdsp2_matrix_instance_q15 * pSrcA,
+  const csky_vdsp2_matrix_instance_q15 * pSrcB,
+  csky_vdsp2_matrix_instance_q15 * pDst,
+  q15_t * pScratch);
+
+  csky_vdsp2_status csky_vdsp2_mat_cmplx_mult_q31(
+  const csky_vdsp2_matrix_instance_q31 * pSrcA,
+  const csky_vdsp2_matrix_instance_q31 * pSrcB,
+  csky_vdsp2_matrix_instance_q31 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_trans_f32(
+  const csky_vdsp2_matrix_instance_f32 * pSrc,
+  csky_vdsp2_matrix_instance_f32 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_trans_q15(
+  const csky_vdsp2_matrix_instance_q15 * pSrc,
+  csky_vdsp2_matrix_instance_q15 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_trans_q31(
+  const csky_vdsp2_matrix_instance_q31 * pSrc,
+  csky_vdsp2_matrix_instance_q31 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_mult_f32(
+  const csky_vdsp2_matrix_instance_f32 * pSrcA,
+  const csky_vdsp2_matrix_instance_f32 * pSrcB,
+  csky_vdsp2_matrix_instance_f32 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_mult_q15(
+  const csky_vdsp2_matrix_instance_q15 * pSrcA,
+  const csky_vdsp2_matrix_instance_q15 * pSrcB,
+  csky_vdsp2_matrix_instance_q15 * pDst,
+  q15_t * pState);
+
+  csky_vdsp2_status csky_vdsp2_mat_mult_trans_q15(
+  const csky_vdsp2_matrix_instance_q15 * pSrcA,
+  const csky_vdsp2_matrix_instance_q15 * pSrcB,
+  csky_vdsp2_matrix_instance_q15 * pDst,
+  q15_t * pState);
+
+  csky_vdsp2_status csky_vdsp2_mat_mult_fast_q15(
+  const csky_vdsp2_matrix_instance_q15 * pSrcA,
+  const csky_vdsp2_matrix_instance_q15 * pSrcB,
+  csky_vdsp2_matrix_instance_q15 * pDst,
+  q15_t * pState);
+
+  csky_vdsp2_status csky_vdsp2_mat_mult_q31(
+  const csky_vdsp2_matrix_instance_q31 * pSrcA,
+  const csky_vdsp2_matrix_instance_q31 * pSrcB,
+  csky_vdsp2_matrix_instance_q31 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_mult_trans_q31(
+  const csky_vdsp2_matrix_instance_q31 * pSrcA,
+  const csky_vdsp2_matrix_instance_q31 * pSrcB,
+  csky_vdsp2_matrix_instance_q31 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_mult_fast_q31(
+  const csky_vdsp2_matrix_instance_q31 * pSrcA,
+  const csky_vdsp2_matrix_instance_q31 * pSrcB,
+  csky_vdsp2_matrix_instance_q31 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_sub_f32(
+  const csky_vdsp2_matrix_instance_f32 * pSrcA,
+  const csky_vdsp2_matrix_instance_f32 * pSrcB,
+  csky_vdsp2_matrix_instance_f32 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_sub_q15(
+  const csky_vdsp2_matrix_instance_q15 * pSrcA,
+  const csky_vdsp2_matrix_instance_q15 * pSrcB,
+  csky_vdsp2_matrix_instance_q15 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_sub_q31(
+  const csky_vdsp2_matrix_instance_q31 * pSrcA,
+  const csky_vdsp2_matrix_instance_q31 * pSrcB,
+  csky_vdsp2_matrix_instance_q31 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_scale_f32(
+  const csky_vdsp2_matrix_instance_f32 * pSrc,
+  float32_t scale,
+  csky_vdsp2_matrix_instance_f32 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_scale_q15(
+  const csky_vdsp2_matrix_instance_q15 * pSrc,
+  q15_t scaleFract,
+  int32_t shift,
+  csky_vdsp2_matrix_instance_q15 * pDst);
+
+  csky_vdsp2_status csky_vdsp2_mat_scale_q31(
+  const csky_vdsp2_matrix_instance_q31 * pSrc,
+  q31_t scaleFract,
+  int32_t shift,
+  csky_vdsp2_matrix_instance_q31 * pDst);
+
+  void csky_vdsp2_mat_init_q31(
+  csky_vdsp2_matrix_instance_q31 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  q31_t * pData);
+
+  void csky_vdsp2_mat_init_q15(
+  csky_vdsp2_matrix_instance_q15 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  q15_t * pData);
+
+  void csky_vdsp2_mat_init_f32(
+  csky_vdsp2_matrix_instance_f32 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  float32_t * pData);
+
+  void csky_vdsp2_mult_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_mult_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_mult_rnd_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_mult_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_mult_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q15_t *pTwiddle;                 /**< points to the Sin twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } csky_vdsp2_cfft_radix2_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q15 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q15_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } csky_vdsp2_cfft_radix4_instance_q15;
+
+  /**
+   * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q31_t *pTwiddle;                 /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } csky_vdsp2_cfft_radix2_instance_q31;
+
+  /**
+   * @brief Instance structure for the Q31 CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q31_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } csky_vdsp2_cfft_radix4_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    uint8_t ifftFlag;                  /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;            /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    float32_t *pTwiddle;               /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;            /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;         /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;             /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+    float32_t onebyfftLen;             /**< value of 1/fftLen. */
+  } csky_vdsp2_cfft_radix2_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    uint8_t ifftFlag;                  /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;            /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    float32_t *pTwiddle;               /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;            /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;         /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;             /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+    float32_t onebyfftLen;             /**< value of 1/fftLen. */
+  } csky_vdsp2_cfft_radix4_instance_f32;
+
+  /**
+   * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const q15_t *pTwiddle;             /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } csky_vdsp2_cfft_instance_q15;
+
+void csky_vdsp2_cfft_q15(
+    const csky_vdsp2_cfft_instance_q15 * S,
+    q15_t * p1,
+    uint8_t ifftFlag,
+    uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const q31_t *pTwiddle;             /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } csky_vdsp2_cfft_instance_q31;
+
+void csky_vdsp2_cfft_q31(
+    const csky_vdsp2_cfft_instance_q31 * S,
+    q31_t * p1,
+    uint8_t ifftFlag,
+    uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const float32_t *pTwiddle;         /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } csky_vdsp2_cfft_instance_f32;
+
+  void csky_vdsp2_cfft_f32(
+  const csky_vdsp2_cfft_instance_f32 * S,
+  float32_t * p1,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the Q15 RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                      /**< length of the real FFT. */
+    uint8_t ifftFlagR;                        /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                  /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;               /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    q15_t *pTwiddleAReal;                     /**< points to the real twiddle factor table. */
+    const csky_vdsp2_cfft_instance_q15 *pCfft;      /**< points to the complex FFT instance. */
+  } csky_vdsp2_rfft_instance_q15;
+
+  csky_vdsp2_status csky_vdsp2_rfft_init_q15(
+  csky_vdsp2_rfft_instance_q15 * S,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void csky_vdsp2_rfft_q15(
+  const csky_vdsp2_rfft_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst);
+
+  /**
+   * @brief Instance structure for the Q31 RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                        /**< length of the real FFT. */
+    uint8_t ifftFlagR;                          /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                    /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;                 /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    q31_t *pTwiddleAReal;                       /**< points to the real twiddle factor table. */
+    const csky_vdsp2_cfft_instance_q31 *pCfft;        /**< points to the complex FFT instance. */
+  } csky_vdsp2_rfft_instance_q31;
+
+  csky_vdsp2_status csky_vdsp2_rfft_init_q31(
+  csky_vdsp2_rfft_instance_q31 * S,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void csky_vdsp2_rfft_q31(
+  const csky_vdsp2_rfft_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst);
+
+  /**
+   * @brief Instance structure for the floating-point RFFT/RIFFT function.
+   */
+  typedef struct
+  {
+    uint32_t fftLenReal;                        /**< length of the real FFT. */
+    uint16_t fftLenBy2;                         /**< length of the complex FFT. */
+    uint8_t ifftFlagR;                          /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                    /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;                 /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    float32_t *pTwiddleAReal;                   /**< points to the real twiddle factor table. */
+    float32_t *pTwiddleBReal;                   /**< points to the imag twiddle factor table. */
+    csky_vdsp2_cfft_radix4_instance_f32 *pCfft;       /**< points to the complex FFT instance. */
+  } csky_vdsp2_rfft_instance_f32;
+
+  csky_vdsp2_status csky_vdsp2_rfft_init_f32(
+  csky_vdsp2_rfft_instance_f32 * S,
+  csky_vdsp2_cfft_radix4_instance_f32 * S_CFFT,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void csky_vdsp2_rfft_f32(
+  const csky_vdsp2_rfft_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst);
+
+  /**
+   * @brief Instance structure for the floating-point RFFT/RIFFT function.
+   */
+typedef struct
+  {
+    csky_vdsp2_cfft_instance_f32 Sint;     /**< Internal CFFT structure. */
+    uint16_t fftLenRFFT;             /**< length of the real sequence */
+    float32_t * pTwiddleRFFT;        /**< Twiddle factors real stage  */
+  } csky_vdsp2_rfft_fast_instance_f32 ;
+
+csky_vdsp2_status csky_vdsp2_rfft_fast_init_f32 (
+   csky_vdsp2_rfft_fast_instance_f32 * S,
+   uint16_t fftLen);
+
+void csky_vdsp2_rfft_fast_f32(
+  csky_vdsp2_rfft_fast_instance_f32 * S,
+  float32_t * p, float32_t * pOut,
+  uint8_t ifftFlag);
+
+  /**
+   * @brief Instance structure for the floating-point DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                           /**< length of the DCT4. */
+    uint16_t Nby2;                        /**< half of the length of the DCT4. */
+    float32_t normalize;                  /**< normalizing factor. */
+    float32_t *pTwiddle;                  /**< points to the twiddle factor table. */
+    float32_t *pCosFactor;                /**< points to the cosFactor table. */
+    csky_vdsp2_rfft_fast_instance_f32 *pRfft;   /**< points to the real FFT fast instance. */
+    csky_vdsp2_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+  } csky_vdsp2_dct4_instance_f32;
+
+  csky_vdsp2_status csky_vdsp2_dct4_init_f32(
+  csky_vdsp2_dct4_instance_f32 * S,
+  csky_vdsp2_rfft_fast_instance_f32 * S_RFFT,
+  csky_vdsp2_cfft_radix4_instance_f32 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  float32_t normalize);
+
+  void csky_vdsp2_dct4_f32(
+  const csky_vdsp2_dct4_instance_f32 * S,
+  float32_t * pState,
+  float32_t * pInlineBuffer);
+
+
+  /**
+   * @brief Instance structure for the Q31 DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                           /**< length of the DCT4. */
+    uint16_t Nby2;                        /**< half of the length of the DCT4. */
+    q31_t normalize;                      /**< normalizing factor. */
+    q31_t *pTwiddle;                      /**< points to the twiddle factor table. */
+    q31_t *pCosFactor;                    /**< points to the cosFactor table. */
+    csky_vdsp2_rfft_instance_q31 *pRfft;        /**< points to the real FFT instance. */
+    csky_vdsp2_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+  } csky_vdsp2_dct4_instance_q31;
+
+  csky_vdsp2_status csky_vdsp2_dct4_init_q31(
+  csky_vdsp2_dct4_instance_q31 * S,
+  csky_vdsp2_rfft_instance_q31 * S_RFFT,
+  csky_vdsp2_cfft_radix4_instance_q31 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  q31_t normalize);
+
+  void csky_vdsp2_dct4_q31(
+  const csky_vdsp2_dct4_instance_q31 * S,
+  q31_t * pState,
+  q31_t * pInlineBuffer);
+
+  /**
+   * @brief Instance structure for the Q15 DCT4/IDCT4 function.
+   */
+  typedef struct
+  {
+    uint16_t N;                           /**< length of the DCT4. */
+    uint16_t Nby2;                        /**< half of the length of the DCT4. */
+    q15_t normalize;                      /**< normalizing factor. */
+    q15_t *pTwiddle;                      /**< points to the twiddle factor table. */
+    q15_t *pCosFactor;                    /**< points to the cosFactor table. */
+    csky_vdsp2_rfft_instance_q15 *pRfft;        /**< points to the real FFT instance. */
+    csky_vdsp2_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+  } csky_vdsp2_dct4_instance_q15;
+
+  csky_vdsp2_status csky_vdsp2_dct4_init_q15(
+  csky_vdsp2_dct4_instance_q15 * S,
+  csky_vdsp2_rfft_instance_q15 * S_RFFT,
+  csky_vdsp2_cfft_radix4_instance_q15 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  q15_t normalize);
+
+  void csky_vdsp2_dct4_q15(
+  const csky_vdsp2_dct4_instance_q15 * S,
+  q15_t * pState,
+  q15_t * pInlineBuffer);
+
+  void csky_vdsp2_add_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_add_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_add_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_add_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_sub_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_sub_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_sub_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_sub_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_scale_f32(
+  float32_t * pSrc,
+  float32_t scale,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_scale_q7(
+  q7_t * pSrc,
+  q7_t scaleFract,
+  int8_t shift,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_scale_q15(
+  q15_t * pSrc,
+  q15_t scaleFract,
+  int8_t shift,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_scale_q31(
+  q31_t * pSrc,
+  q31_t scaleFract,
+  int8_t shift,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_abs_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_abs_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_abs_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_abs_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_abs_max_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_abs_max_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  void csky_vdsp2_dot_prod_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  uint32_t blockSize,
+  float32_t * result);
+
+  void csky_vdsp2_dot_prod_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  uint32_t blockSize,
+  q31_t * result);
+
+  void csky_vdsp2_dot_prod_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  uint32_t blockSize,
+  q63_t * result);
+
+  void csky_vdsp2_dot_prod_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  uint32_t blockSize,
+  q63_t * result);
+
+  void csky_vdsp2_shift_q7(
+  q7_t * pSrc,
+  int8_t shiftBits,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_shift_q15(
+  q15_t * pSrc,
+  int8_t shiftBits,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_shift_q31(
+  q31_t * pSrc,
+  int8_t shiftBits,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_offset_f32(
+  float32_t * pSrc,
+  float32_t offset,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_offset_q7(
+  q7_t * pSrc,
+  q7_t offset,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_offset_q15(
+  q15_t * pSrc,
+  q15_t offset,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_offset_q31(
+  q31_t * pSrc,
+  q31_t offset,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_negate_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_negate_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_negate_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_negate_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_copy_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_copy_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_copy_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_copy_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fill_f32(
+  float32_t value,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fill_q7(
+  q7_t value,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fill_q15(
+  q15_t value,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fill_q31(
+  q31_t value,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_conv_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst);
+
+  void csky_vdsp2_conv_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  void csky_vdsp2_conv_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+  void csky_vdsp2_conv_fast_q15(
+          q15_t * pSrcA,
+          uint32_t srcALen,
+          q15_t * pSrcB,
+          uint32_t srcBLen,
+          q15_t * pDst);
+
+  void csky_vdsp2_conv_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  void csky_vdsp2_conv_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+  void csky_vdsp2_conv_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+  void csky_vdsp2_conv_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  void csky_vdsp2_conv_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst);
+
+  csky_vdsp2_status csky_vdsp2_conv_partial_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  csky_vdsp2_status csky_vdsp2_conv_partial_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  csky_vdsp2_status csky_vdsp2_conv_partial_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  csky_vdsp2_status csky_vdsp2_conv_partial_fast_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  csky_vdsp2_status csky_vdsp2_conv_partial_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  csky_vdsp2_status csky_vdsp2_conv_partial_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  csky_vdsp2_status csky_vdsp2_conv_partial_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  csky_vdsp2_status csky_vdsp2_conv_partial_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  csky_vdsp2_status csky_vdsp2_conv_partial_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  /**
+   * @brief Instance structure for the Q15 FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    q15_t *pCoeffs;             /**< points to the coefficient array. The array is of length numTaps.*/
+    q15_t *pState;              /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } csky_vdsp2_fir_decimate_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    q31_t *pCoeffs;             /**< points to the coefficient array. The array is of length numTaps.*/
+    q31_t *pState;              /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } csky_vdsp2_fir_decimate_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR decimator.
+   */
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    float32_t *pCoeffs;         /**< points to the coefficient array. The array is of length numTaps.*/
+    float32_t *pState;          /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } csky_vdsp2_fir_decimate_instance_f32;
+
+  void csky_vdsp2_fir_decimate_f32(
+  const csky_vdsp2_fir_decimate_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  csky_vdsp2_status csky_vdsp2_fir_decimate_init_f32(
+  csky_vdsp2_fir_decimate_instance_f32 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_decimate_q15(
+  const csky_vdsp2_fir_decimate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_decimate_fast_q15(
+  const csky_vdsp2_fir_decimate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  csky_vdsp2_status csky_vdsp2_fir_decimate_init_q15(
+  csky_vdsp2_fir_decimate_instance_q15 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_decimate_q31(
+  const csky_vdsp2_fir_decimate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_decimate_fast_q31(
+  csky_vdsp2_fir_decimate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  csky_vdsp2_status csky_vdsp2_fir_decimate_init_q31(
+  csky_vdsp2_fir_decimate_instance_q31 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                      /**< upsample factor. */
+    uint16_t phaseLength;           /**< length of each polyphase filter component. */
+    q15_t *pCoeffs;                 /**< points to the coefficient array. The array is of length L*phaseLength. */
+    q15_t *pState;                  /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+  } csky_vdsp2_fir_interpolate_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                      /**< upsample factor. */
+    uint16_t phaseLength;           /**< length of each polyphase filter component. */
+    q31_t *pCoeffs;                 /**< points to the coefficient array. The array is of length L*phaseLength. */
+    q31_t *pState;                  /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+  } csky_vdsp2_fir_interpolate_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR interpolator.
+   */
+  typedef struct
+  {
+    uint8_t L;                     /**< upsample factor. */
+    uint16_t phaseLength;          /**< length of each polyphase filter component. */
+    float32_t *pCoeffs;            /**< points to the coefficient array. The array is of length L*phaseLength. */
+    float32_t *pState;             /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */
+  } csky_vdsp2_fir_interpolate_instance_f32;
+
+  void csky_vdsp2_fir_interpolate_q15(
+  const csky_vdsp2_fir_interpolate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  csky_vdsp2_status csky_vdsp2_fir_interpolate_init_q15(
+  csky_vdsp2_fir_interpolate_instance_q15 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_interpolate_q31(
+  const csky_vdsp2_fir_interpolate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  csky_vdsp2_status csky_vdsp2_fir_interpolate_init_q31(
+  csky_vdsp2_fir_interpolate_instance_q31 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_interpolate_f32(
+  const csky_vdsp2_fir_interpolate_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  csky_vdsp2_status csky_vdsp2_fir_interpolate_init_f32(
+  csky_vdsp2_fir_interpolate_instance_f32 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the high precision Q31 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;       /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q63_t *pState;           /**< points to the array of state coefficients.  The array is of length 4*numStages. */
+    q31_t *pCoeffs;          /**< points to the array of coefficients.  The array is of length 5*numStages. */
+    uint8_t postShift;       /**< additional shift, in bits, applied to each output sample. */
+  } csky_vdsp2_biquad_cas_df1_32x64_ins_q31;
+
+  void csky_vdsp2_biquad_cas_df1_32x64_q31(
+  const csky_vdsp2_biquad_cas_df1_32x64_ins_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_biquad_cas_df1_32x64_init_q31(
+  csky_vdsp2_biquad_cas_df1_32x64_ins_q31 * S,
+  uint8_t numStages,
+  q31_t * pCoeffs,
+  q63_t * pState,
+  uint8_t postShift);
+
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;         /**< points to the array of state coefficients.  The array is of length 2*numStages. */
+    float32_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } csky_vdsp2_biquad_cascade_df2T_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;         /**< points to the array of state coefficients.  The array is of length 4*numStages. */
+    float32_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } csky_vdsp2_biquad_cascade_stereo_df2T_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float64_t *pState;         /**< points to the array of state coefficients.  The array is of length 2*numStages. */
+    float64_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } csky_vdsp2_biquad_cascade_df2T_instance_f64;
+
+  void csky_vdsp2_biquad_cascade_df2T_f32(
+  const csky_vdsp2_biquad_cascade_df2T_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_biquad_cascade_stereo_df2T_f32(
+  const csky_vdsp2_biquad_cascade_stereo_df2T_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_biquad_cascade_df2T_f64(
+  const csky_vdsp2_biquad_cascade_df2T_instance_f64 * S,
+  float64_t * pSrc,
+  float64_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_biquad_cascade_df2T_init_f32(
+  csky_vdsp2_biquad_cascade_df2T_instance_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+  void csky_vdsp2_biquad_cascade_stereo_df2T_init_f32(
+  csky_vdsp2_biquad_cascade_stereo_df2T_instance_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  void csky_vdsp2_biquad_cascade_df2T_init_f64(
+  csky_vdsp2_biquad_cascade_df2T_instance_f64 * S,
+  uint8_t numStages,
+  float64_t * pCoeffs,
+  float64_t * pState);
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    q15_t *pState;                       /**< points to the state variable array. The array is of length numStages. */
+    q15_t *pCoeffs;                      /**< points to the coefficient array. The array is of length numStages. */
+  } csky_vdsp2_fir_lattice_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    q31_t *pState;                       /**< points to the state variable array. The array is of length numStages. */
+    q31_t *pCoeffs;                      /**< points to the coefficient array. The array is of length numStages. */
+  } csky_vdsp2_fir_lattice_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    float32_t *pState;                   /**< points to the state variable array. The array is of length numStages. */
+    float32_t *pCoeffs;                  /**< points to the coefficient array. The array is of length numStages. */
+  } csky_vdsp2_fir_lattice_instance_f32;
+
+  void csky_vdsp2_fir_lattice_init_q15(
+  csky_vdsp2_fir_lattice_instance_q15 * S,
+  uint16_t numStages,
+  q15_t * pCoeffs,
+  q15_t * pState);
+
+  void csky_vdsp2_fir_lattice_q15(
+  const csky_vdsp2_fir_lattice_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_lattice_init_q31(
+  csky_vdsp2_fir_lattice_instance_q31 * S,
+  uint16_t numStages,
+  q31_t * pCoeffs,
+  q31_t * pState);
+
+  void csky_vdsp2_fir_lattice_q31(
+  const csky_vdsp2_fir_lattice_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_lattice_init_f32(
+  csky_vdsp2_fir_lattice_instance_f32 * S,
+  uint16_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+  void csky_vdsp2_fir_lattice_f32(
+  const csky_vdsp2_fir_lattice_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    q15_t *pState;                       /**< points to the state variable array. The array is of length numStages+blockSize. */
+    q15_t *pkCoeffs;                     /**< points to the reflection coefficient array. The array is of length numStages. */
+    q15_t *pvCoeffs;                     /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } csky_vdsp2_iir_lattice_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    q31_t *pState;                       /**< points to the state variable array. The array is of length numStages+blockSize. */
+    q31_t *pkCoeffs;                     /**< points to the reflection coefficient array. The array is of length numStages. */
+    q31_t *pvCoeffs;                     /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } csky_vdsp2_iir_lattice_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of stages in the filter. */
+    float32_t *pState;                   /**< points to the state variable array. The array is of length numStages+blockSize. */
+    float32_t *pkCoeffs;                 /**< points to the reflection coefficient array. The array is of length numStages. */
+    float32_t *pvCoeffs;                 /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } csky_vdsp2_iir_lattice_instance_f32;
+
+  void csky_vdsp2_iir_lattice_f32(
+  const csky_vdsp2_iir_lattice_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_iir_lattice_init_f32(
+  csky_vdsp2_iir_lattice_instance_f32 * S,
+  uint16_t numStages,
+  float32_t * pkCoeffs,
+  float32_t * pvCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+  void csky_vdsp2_iir_lattice_q31(
+  const csky_vdsp2_iir_lattice_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_iir_lattice_init_q31(
+  csky_vdsp2_iir_lattice_instance_q31 * S,
+  uint16_t numStages,
+  q31_t * pkCoeffs,
+  q31_t * pvCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+  void csky_vdsp2_iir_lattice_q15(
+  const csky_vdsp2_iir_lattice_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_iir_lattice_init_q15(
+  csky_vdsp2_iir_lattice_instance_q15 * S,
+  uint16_t numStages,
+  q15_t * pkCoeffs,
+  q15_t * pvCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the floating-point LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    float32_t *pState;   /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;  /**< points to the coefficient array. The array is of length numTaps. */
+    float32_t mu;        /**< step size that controls filter coefficient updates. */
+  } csky_vdsp2_lms_instance_f32;
+
+  void csky_vdsp2_lms_f32(
+  const csky_vdsp2_lms_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pRef,
+  float32_t * pOut,
+  float32_t * pErr,
+  uint32_t blockSize);
+
+  void csky_vdsp2_lms_init_f32(
+  csky_vdsp2_lms_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  float32_t mu,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    q15_t *pState;       /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;      /**< points to the coefficient array. The array is of length numTaps. */
+    q15_t mu;            /**< step size that controls filter coefficient updates. */
+    uint32_t postShift;  /**< bit shift applied to coefficients. */
+  } csky_vdsp2_lms_instance_q15;
+
+  void csky_vdsp2_lms_init_q15(
+  csky_vdsp2_lms_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  q15_t mu,
+  uint32_t blockSize,
+  uint32_t postShift);
+
+  void csky_vdsp2_lms_q15(
+  const csky_vdsp2_lms_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pRef,
+  q15_t * pOut,
+  q15_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q31 LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    q31_t *pState;       /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;      /**< points to the coefficient array. The array is of length numTaps. */
+    q31_t mu;            /**< step size that controls filter coefficient updates. */
+    uint32_t postShift;  /**< bit shift applied to coefficients. */
+  } csky_vdsp2_lms_instance_q31;
+
+  void csky_vdsp2_lms_q31(
+  const csky_vdsp2_lms_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pRef,
+  q31_t * pOut,
+  q31_t * pErr,
+  uint32_t blockSize);
+
+  void csky_vdsp2_lms_init_q31(
+  csky_vdsp2_lms_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  q31_t mu,
+  uint32_t blockSize,
+  uint32_t postShift);
+
+
+  /**
+   * @brief Instance structure for the floating-point normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of coefficients in the filter. */
+    float32_t *pState;    /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;   /**< points to the coefficient array. The array is of length numTaps. */
+    float32_t mu;         /**< step size that control filter coefficient updates. */
+    float32_t energy;     /**< saves previous frame energy. */
+    float32_t x0;         /**< saves previous input sample. */
+  } csky_vdsp2_lms_norm_instance_f32;
+
+  void csky_vdsp2_lms_norm_f32(
+  csky_vdsp2_lms_norm_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pRef,
+  float32_t * pOut,
+  float32_t * pErr,
+  uint32_t blockSize);
+
+  void csky_vdsp2_lms_norm_init_f32(
+  csky_vdsp2_lms_norm_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  float32_t mu,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q31 normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of coefficients in the filter. */
+    q31_t *pState;        /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;       /**< points to the coefficient array. The array is of length numTaps. */
+    q31_t mu;             /**< step size that controls filter coefficient updates. */
+    uint8_t postShift;    /**< bit shift applied to coefficients. */
+    q31_t *recipTable;    /**< points to the reciprocal initial value table. */
+    q31_t energy;         /**< saves previous frame energy. */
+    q31_t x0;             /**< saves previous input sample. */
+  } csky_vdsp2_lms_norm_instance_q31;
+
+  void csky_vdsp2_lms_norm_q31(
+  csky_vdsp2_lms_norm_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pRef,
+  q31_t * pOut,
+  q31_t * pErr,
+  uint32_t blockSize);
+
+  void csky_vdsp2_lms_norm_init_q31(
+  csky_vdsp2_lms_norm_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  q31_t mu,
+  uint32_t blockSize,
+  uint8_t postShift);
+
+
+  /**
+   * @brief Instance structure for the Q15 normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< Number of coefficients in the filter. */
+    q15_t *pState;        /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;       /**< points to the coefficient array. The array is of length numTaps. */
+    q15_t mu;             /**< step size that controls filter coefficient updates. */
+    uint8_t postShift;    /**< bit shift applied to coefficients. */
+    q15_t *recipTable;    /**< Points to the reciprocal initial value table. */
+    q15_t energy;         /**< saves previous frame energy. */
+    q15_t x0;             /**< saves previous input sample. */
+  } csky_vdsp2_lms_norm_instance_q15;
+
+  void csky_vdsp2_lms_norm_q15(
+  csky_vdsp2_lms_norm_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pRef,
+  q15_t * pOut,
+  q15_t * pErr,
+  uint32_t blockSize);
+
+  void csky_vdsp2_lms_norm_init_q15(
+  csky_vdsp2_lms_norm_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  q15_t mu,
+  uint32_t blockSize,
+  uint8_t postShift);
+
+  void csky_vdsp2_correlate_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst);
+
+  void csky_vdsp2_correlate_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch);
+
+  void csky_vdsp2_correlate_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+  void csky_vdsp2_correlate_fast_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+  void csky_vdsp2_correlate_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch);
+
+  void csky_vdsp2_correlate_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+  void csky_vdsp2_correlate_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+  void csky_vdsp2_correlate_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+  void csky_vdsp2_correlate_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst);
+
+
+  /**
+   * @brief Instance structure for the floating-point sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    float32_t *pState;            /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    float32_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } csky_vdsp2_fir_sparse_instance_f32;
+
+  /**
+   * @brief Instance structure for the Q31 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q31_t *pState;                /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q31_t *pCoeffs;               /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } csky_vdsp2_fir_sparse_instance_q31;
+
+  /**
+   * @brief Instance structure for the Q15 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q15_t *pState;                /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q15_t *pCoeffs;               /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } csky_vdsp2_fir_sparse_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q7 sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q7_t *pState;                 /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q7_t *pCoeffs;                /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } csky_vdsp2_fir_sparse_instance_q7;
+
+  void csky_vdsp2_fir_sparse_f32(
+  csky_vdsp2_fir_sparse_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  float32_t * pScratchIn,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_sparse_init_f32(
+  csky_vdsp2_fir_sparse_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_sparse_q31(
+  csky_vdsp2_fir_sparse_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  q31_t * pScratchIn,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_sparse_init_q31(
+  csky_vdsp2_fir_sparse_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_sparse_q15(
+  csky_vdsp2_fir_sparse_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  q15_t * pScratchIn,
+  q31_t * pScratchOut,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_sparse_init_q15(
+  csky_vdsp2_fir_sparse_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_sparse_q7(
+  csky_vdsp2_fir_sparse_instance_q7 * S,
+  q7_t * pSrc,
+  q7_t * pDst,
+  q7_t * pScratchIn,
+  q31_t * pScratchOut,
+  uint32_t blockSize);
+
+  void csky_vdsp2_fir_sparse_init_q7(
+  csky_vdsp2_fir_sparse_instance_q7 * S,
+  uint16_t numTaps,
+  q7_t * pCoeffs,
+  q7_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+  void csky_vdsp2_sin_cos_f32(
+  float32_t theta,
+  float32_t * pSinVal,
+  float32_t * pCosVal);
+
+  void csky_vdsp2_sin_cos_q31(
+  q31_t theta,
+  q31_t * pSinVal,
+  q31_t * pCosVal);
+
+  void csky_vdsp2_cmplx_conj_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_conj_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_conj_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mag_squared_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mag_squared_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mag_squared_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_vsqrt_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_vsqrt_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_vsqrt_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_q7_to_q31(
+  q7_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_q7_to_q15(
+  q7_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_q7_to_float(
+  q7_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_q31_to_float(
+  q31_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  csky_vdsp2_status csky_vdsp2_sqrt_f32(
+  float32_t in,
+  float32_t * pOut);
+
+  csky_vdsp2_status csky_vdsp2_sqrt_q31(
+  q31_t in,
+  q31_t * pOut);
+
+  csky_vdsp2_status csky_vdsp2_sqrt_q15(
+  q15_t in,
+  q15_t * pOut);
+
+  void csky_vdsp2_power_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+  void csky_vdsp2_power_int32(
+  int32_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+  void csky_vdsp2_power_int32(
+  int32_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+  void csky_vdsp2_power_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  void csky_vdsp2_power_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+  void csky_vdsp2_power_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  void csky_vdsp2_mean_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * pResult);
+
+  void csky_vdsp2_mean_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+  void csky_vdsp2_mean_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  void csky_vdsp2_mean_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  void csky_vdsp2_var_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  void csky_vdsp2_var_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  void csky_vdsp2_var_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+  void csky_vdsp2_rms_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  void csky_vdsp2_rms_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  void csky_vdsp2_rms_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+  void csky_vdsp2_std_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  void csky_vdsp2_std_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  void csky_vdsp2_std_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+  void csky_vdsp2_cmplx_mag_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mag_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mag_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_dot_prod_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  uint32_t numSamples,
+  q31_t * realResult,
+  q31_t * imagResult);
+
+  void csky_vdsp2_cmplx_dot_prod_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  uint32_t numSamples,
+  q63_t * realResult,
+  q63_t * imagResult);
+
+  void csky_vdsp2_cmplx_dot_prod_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  uint32_t numSamples,
+  float32_t * realResult,
+  float32_t * imagResult);
+
+  void csky_vdsp2_cmplx_mult_real_q15(
+  q15_t * pSrcCmplx,
+  q15_t * pSrcReal,
+  q15_t * pCmplxDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mult_real_q31(
+  q31_t * pSrcCmplx,
+  q31_t * pSrcReal,
+  q31_t * pCmplxDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mult_real_f32(
+  float32_t * pSrcCmplx,
+  float32_t * pSrcReal,
+  float32_t * pCmplxDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_min_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * result,
+  uint32_t * index);
+
+  void csky_vdsp2_min_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_vdsp2_min_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_vdsp2_min_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_vdsp2_max_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_vdsp2_max_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_vdsp2_max_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_vdsp2_max_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult,
+  uint32_t * pIndex);
+
+  void csky_vdsp2_cmplx_mult_cmplx_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mult_cmplx_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mult_cmplx_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mult_cmplx_re_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mult_cmplx_re_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  void csky_vdsp2_cmplx_mult_cmplx_re_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+
+  void csky_vdsp2_float_to_q31(
+  float32_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_float_to_q15(
+  float32_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_float_to_q7(
+  float32_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_q31_to_q15(
+  q31_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_q31_to_q7(
+  q31_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_q15_to_float(
+  q15_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_q15_to_q31(
+  q15_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  void csky_vdsp2_q15_to_q7(
+  q15_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+#endif /* _CSKY_VDSP2_MATH_H */
+
+/**
+ *
+ * End of file.
+ */

+ 248 - 0
include/bt/wm_ble.h

@@ -0,0 +1,248 @@
+/**
+ * @file    wm_ble.h
+ *
+ * @brief   Bluetooth API
+ *
+ * @author  WinnerMicro
+ *
+ * Copyright (c) 2020 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_BLE_H
+#define WM_BLE_H
+
+#include "wm_bt_def.h"
+
+/**
+ * @defgroup BT_APIs Bluetooth APIs
+ * @brief Bluetooth related APIs
+ */
+
+/**
+ * @addtogroup BT_APIs
+ * @{
+ */
+
+/**
+ * @defgroup BLE_APIs BLE APIs
+ * @brief BLE APIs
+ */
+
+/**
+ * @addtogroup BLE_APIs
+ * @{
+ */
+
+/**
+ * @brief          initialize the application callback function
+ *
+ * @param[in]      *p_callback      pointer on callback function
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_dm_init(tls_ble_dm_callback_t callback);
+
+/**
+ * @brief          start/stop ble advertisement
+ *
+ * @param[in]      start      1 connectable and discoverable; 2 disconnectable and discoverable; 0 stop
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_adv(uint8_t adv_state);
+
+/**
+ * @brief          configure the advertisment content
+ *
+ * @param[in]      *data        @ref btif_dm_adv_data_t
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           if pure_data equals to true, the filed of manufacturer equals to all fileds of advetisement data.
+ *                     otherwise, the filed manufacturer will be advertised in 0xFF filed. 
+ *
+ */
+tls_bt_status_t tls_ble_set_adv_data(tls_ble_dm_adv_data_t *data);
+
+/**
+ * @brief          configure the advertisment parameters
+ *
+ * @param[in]      *param        @ref btif_dm_adv_param_t
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_set_adv_param(tls_ble_dm_adv_param_t *param);
+
+/**
+ * @brief          configure the advertisment extented parameters
+ *
+ * @param[in]      *param        @ref tls_ble_dm_adv_ext_param_t
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           if you know how to config all the parameters, you can use this function; otherwise, tls_ble_set_adv_param will be recommanded strongly;
+ */
+tls_bt_status_t tls_ble_set_adv_ext_param(tls_ble_dm_adv_ext_param_t *param);
+
+
+/**
+ * @brief          start/stop ble scan
+ *
+ * @param[in]      start        TRUE enable; FALSE disable
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_scan(bool start);
+
+/**
+ * @brief          configure the scan parameters
+ *
+ * @param[in]      window        scan window size
+ * @param[in]      interval      scan interval length
+ * @param[in]     scan mode    0 passive scan; 1 active scan;
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           interval should greater or equals to windows,
+ *                 both range should be within (0x0004, 0x4000)
+ */
+tls_bt_status_t tls_ble_set_scan_param(int window, int interval, uint8_t scan_mode);
+
+/**
+ * @brief          enable a async process evt
+ *
+ * @param[in]      id               user specific definition
+ * @param[in]      *p_callback      callback function
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_dm_evt_triger(int id, tls_ble_dm_triger_callback_t callback);
+
+/**
+ * @brief          configure the max transmit unit
+ *
+ * @param[in]      *bd_addr     the remote device address
+ * @param[in]      length       range [27 - 251]
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_dm_set_data_length(tls_bt_addr_t *bd_addr, uint16_t length);
+
+/**
+ * @brief          configure the ble privacy
+ *
+ * @param[in]      enable   TRUE:  using rpa/random address, updated every 15 mins
+ **                         FALSE: public address
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_dm_set_privacy(uint8_t enable);
+
+/**
+ * @brief          update the connection parameters
+ *
+ * @param[in]      *bd_addr         remote device address
+ * @param[in]      min_interval
+ * @param[in]      max_interval
+ * @param[in]      latency
+ * @param[in]      timeout
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_conn_parameter_update(const tls_bt_addr_t *bd_addr, 
+                                             int min_interval,
+                                             int max_interval, 
+                                             int latency, 
+                                             int timeout);
+
+/**
+ * @brief          read the remote device signal strength connected
+ *
+ * @param[in]      *bd_addr         remote device address
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_dm_read_remote_rssi(const tls_bt_addr_t *bd_addr);
+
+
+/**
+ * @brief          config the io capabilities of local device
+ *
+ * @param[in]      io_cap        
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_ble_set_sec_io_cap(uint8_t io_cap);
+
+/**
+ * @brief          config the auth requirement of local device
+ *
+ * @param[in]      auth_req        
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_ble_set_sec_auth_req(uint8_t auth_req);
+
+/**
+ * @brief       This function is called to ensure that connection is
+ *                  encrypted.  Should be called only on an open connection.
+ *                  Typically only needed for connections that first want to
+ *                  bring up unencrypted links, then later encrypt them.
+
+ * @param[in]sec_act       - This is the security action to indicate
+ *                                 what knid of BLE security level is required for
+ *                                 the BLE link if the BLE is supported      
+ * @param[in]bd_addr       - Address of the peer device
+ * @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_ble_set_sec(const tls_bt_addr_t *bd_addr, uint8_t sec_act);
+
+/**
+ * @brief          only used to start/stop ble advertisement
+ *
+ * @param[in]      start  1 start advertisement; 0 stop advertisement;
+ * @param[in]     duration valid for start advertisement. 0 for forever, otherwise the last seconds of advertisement
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_ble_gap_adv(uint8_t start, int duration);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+ 
+#endif /* WM_BLE_H */
+

+ 480 - 0
include/bt/wm_ble_gatt.h

@@ -0,0 +1,480 @@
+/**
+ * @file    wm_ble_gatt.h
+ *
+ * @brief   Bluetooth API
+ *
+ * @author  WinnerMicro
+ *
+ * Copyright (c) 2020 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_BLE_GATT_H
+#define WM_BLE_GATT_H
+
+#include "wm_bt_def.h"
+
+/**
+ * @defgroup BT_APIs Bluetooth APIs
+ * @brief Bluetooth related APIs
+ */
+
+/**
+ * @addtogroup BT_APIs
+ * @{
+ */
+
+/**
+ * @defgroup BLE_GATT_Client_APIs BLE GATT Client APIs
+ * @brief BLE GATT Client APIs
+ */
+
+/**
+ * @addtogroup BLE_GATT_Client_APIs
+ * @{
+ */
+
+/**
+ * @brief          initialize the btif_gatt_client callback function
+ *
+ * @param[in]      *p_callback      pointer on callback function
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_app_init(tls_ble_callback_t callback);
+
+/**
+ * @brief          free the tls_ble_callback_t pointer
+ *
+ * @param          None
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_app_deinit(void);
+
+/**
+ * @brief          this function is called to register client application
+ *
+ * @param[in]      *uuid      pointer on uuid
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_app_register(tls_bt_uuid_t *uuid);
+
+/**
+ * @brief          this function is called to unregister client application
+ *
+ * @param[in]      client_if      gatt client access interface
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_app_unregister(uint8_t client_if);
+
+/**
+ * @brief          this function is called to open an BLE connection  to a remote
+ *                 device or add a background auto connection
+ *
+ * @param[in]      client_if        gatt client access interface
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * @param[in]      is_direct        direct connection or background auto connection
+ * @param[in]      transport        specific BLE/BR-EDR/mixed
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_connect(uint8_t client_if, const tls_bt_addr_t *bd_addr, uint8_t is_direct, int transport);
+
+/**
+ * @brief          this function is called to disconnect with gatt server connection
+ *
+ * @param[in]      client_if        gatt client access interface
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * @param[in]      conn_id          connection ID to be closed
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_disconnect(uint8_t client_if, const tls_bt_addr_t *bd_addr,  int conn_id);
+
+/**
+ * @brief          start or stop advertisements to listen for incoming connections
+ *
+ * @param[in]      client_if        gatt client access interface
+ * @param[in]      start            start: 1; stop 0
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_listen(uint8_t client_if, uint8_t start);
+
+/**
+ * @brief          clear the attribute cache for a given device
+ *
+ * @param[in]      client_if        gatt client access interface
+ * @param[in]      *bd_addr         remote device address
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_refresh(uint8_t client_if, const tls_bt_addr_t *bd_addr);
+
+/**
+ * @brief          enumerate all GATT services on a connected device
+ *
+ * @param[in]      conn_id          connection indicator return value when connected
+ * @param[in]      *filter_uuid     filter this uuid
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           Optionally, the results can be filtered for a given UUID
+ */
+tls_bt_status_t tls_ble_client_search_service(uint16_t conn_id, tls_bt_uuid_t *filter_uuid);
+
+/**
+ * @brief          write a remote characteristic
+ *
+ * @param[in]      conn_id        connection indicator return value when connected
+ * @param[in]      handle         the character attribute handle
+ * @param[in]      write_type     the type of attribute write operation
+ * @param[in]      len            length of the value to be written
+ * @param[in]      auth_req       authentication request
+ * @param[in]      *p_value       the value to be written
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_write_characteristic(uint16_t conn_id, uint16_t handle, int write_type, int len, int auth_req, char *p_value);
+
+/**
+ * @brief          read a characteristic on a remote device
+ *
+ * @param[in]      conn_id        connection indicator return value when connected
+ * @param[in]      handle         the character attribute handle
+ * @param[in]      auth_req       authentication request
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_read_characteristic(uint16_t conn_id, uint16_t handle, int auth_req);
+
+/**
+ * @brief          read the descriptor for a given characteristic
+ *
+ * @param[in]      conn_id        connection indicator return value when connected
+ * @param[in]      handle         the character attribute handle
+ * @param[in]      auth_req       authentication request
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_read_descriptor(uint16_t conn_id, uint16_t handle, int auth_req);
+
+/**
+ * @brief          write a remote descriptor for a given characteristic
+ *
+ * @param[in]      conn_id        connection indicator return value when connected
+ * @param[in]      handle         the character attribute handle
+ * @param[in]      write_type     the type of attribute write operation
+ * @param[in]      len            length of the value to be written
+ * @param[in]      auth_req       authentication request
+ * @param[in]      *p_value       the value to be written
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_write_descriptor(uint16_t conn_id, uint16_t handle, int write_type, int len, int auth_req, char *p_value);
+
+/**
+ * @brief          execute a prepared write operation
+ *
+ * @param[in]      conn_id        connection indicator return value when connected
+ * @param[in]      execute        execute or cancel
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_execute_write(uint16_t conn_id, int execute);
+
+/**
+ * @brief          Register to receive notifications or indications for a given
+ *                 characteristic
+ *
+ * @param[in]      client_if        gatt client access interface
+ * @param[in]      *bd_addr         the target server address
+ * @param[in]      handle           the attribute handle of characteristic
+ * @param[in]     conn_id          the connection id 
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_register_for_notification(int client_if, const tls_bt_addr_t *bd_addr, uint16_t handle, uint16_t conn_id);
+
+/**
+ * @brief          deregister a previous request for notifications/indications
+ *
+ * @param[in]      client_if        gatt client access interface
+ * @param[in]      *bd_addr         the target server address
+ * @param[in]      handle           the attribute handle of characteristic
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_deregister_for_notification(int client_if, const tls_bt_addr_t *bd_addr, uint16_t handle,uint16_t conn_id);
+
+/**
+ * @brief          configure the MTU for a given connection
+ *
+ * @param[in]      conn_id      connection indicator return value when connected
+ * @param[in]      mtu          the max transmit unit of this connection
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_configure_mtu(uint16_t conn_id, uint16_t mtu);
+
+/**
+ * @brief          get gatt db content
+ *
+ * @param[in]      conn_id      connection indicator return value when connected
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_client_get_gatt_db(uint16_t conn_id);
+
+/**
+ * @}
+ */
+
+
+
+/**
+ * @defgroup BLE_GATT_Server_APIs BLE GATT Server APIs
+ * @brief BLE GATT Server APIs
+ */
+
+/**
+ * @addtogroup BLE_GATT_Server_APIs
+ * @{
+ */
+
+/**
+ * @brief          initialize the btif_gatt_server callback function
+ *
+ * @param[in]      *p_callback      pointer on callback function
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_app_init(tls_ble_callback_t callback);
+
+ /*******************************************************************************
+ **
+ ** Function         tls_ble_server_app_deinit
+ **
+ ** Description      free the tls_ble_callback_t pointer
+ **
+ ** Parameters       None
+ **
+ ** Returns          TLS_BT_STATUS_SUCCESS
+ **                  TLS_BT_STATUS_DONE
+ **       
+ *******************************************************************************/
+tls_bt_status_t tls_ble_server_app_deinit();
+
+/**
+ * @brief          this function is called to register server application
+ *
+ * @param[in]      *uuid      pointer on uuid
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_app_register(tls_bt_uuid_t *uuid);
+
+/**
+ * @brief          this function is called to unregister server application
+ *
+ * @param[in]      server_if      assigned after app registering
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_app_unregister(uint8_t server_if);
+
+/**
+ * @brief          create a new service
+ *
+ * @param[in]      server_if        the gatt server access interface created by app register
+ * @param[in]      inst_id          instance identifier of this service
+ * @param[in]      primay           is primary or not service
+ * @param[in]      *uuid            the id property of this service
+ * @param[in]      num_handles      number of handle requested for this service
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_add_service(uint8_t server_if, int inst_id, int primay, tls_bt_uuid_t *uuid, int num_handles);
+
+/**
+ * @brief          add a characteristic to a service
+ *
+ * @param[in]      server_if        the gatt server access interface created by app register
+ * @param[in]      service_handle   the handle of this service assigned when creating a service
+ * @param[in]      *uuid            the id property of this characteristic
+ * @param[in]      properties       access properties
+ * @param[in]      permission       access permission
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_add_characteristic(uint8_t server_if, uint16_t service_handle, tls_bt_uuid_t *uuid, int properties, int permission);
+
+/**
+ * @brief          add a descriptor to a given service
+ *
+ * @param[in]      server_if        the gatt server access interface created by app register
+ * @param[in]      service_handle   the handle of this service assigned when creating a service
+ * @param[in]      *uuid            the id property of this characteristic
+ * @param[in]      permission       access permission
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_add_descriptor(uint8_t server_if, uint16_t service_handle, tls_bt_uuid_t *uuid, int permissions);
+
+/**
+ * @brief          starts a local service
+ *
+ * @param[in]      server_if        the gatt server access interface created by app register
+ * @param[in]      service_handle   the handle of this service assigned when creating a service
+ * @param[in]      transport        tranport type, BLE/BR-EDR/MIXED
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_start_service(uint8_t server_if, uint16_t service_handle, int transport);
+
+/**
+ * @brief          stop a local service
+ *
+ * @param[in]      server_if        the gatt server access interface created by app register
+ * @param[in]      service_handle   the handle of this service assigned when creating a service
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_stop_service(uint8_t server_if, uint16_t service_handle);
+
+/**
+ * @brief          delete a local service
+ *
+ * @param[in]      server_if        the gatt server access interface created by app register
+ * @param[in]      service_handle   the handle of this service assigned when creating a service
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_delete_service(uint8_t server_if, uint16_t service_handle);
+
+/**
+ * @brief          create a connection to a remote peripheral
+ *
+ * @param[in]      server_if        the gatt server access interface created by app register
+ * @param[in]      *bd_addr         the remote device address
+ * @param[in]      is_direct        true direct connection; false: background auto connection
+ * @param[in]      transport        tranport type, BLE/BR-EDR/MIXED
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_connect(uint8_t server_if, const tls_bt_addr_t *bd_addr, uint8_t is_direct, int transport);
+
+/**
+ * @brief          disconnect an established connection or cancel a pending one
+ *
+ * @param[in]      server_if        the gatt server access interface created by app register
+ * @param[in]      *bd_addr         the remote device address
+ * @param[in]      conn_id          connection id create when connection established
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_disconnect(uint8_t server_if, const tls_bt_addr_t *bd_addr, uint16_t conn_id);
+
+/**
+ * @brief          send value indication to a remote device
+ *
+ * @param[in]      server_if            the gatt server access interface created by app register
+ * @param[in]      attribute_handle     the handle of characteristic
+ * @param[in]      conn_id              connection id create when connection established
+ * @param[in]      len                  the length of value to be sent
+ * @param[in]      confirm              need the remote device acked after receive the message , normally
+ *                                      Whether a confirmation is required. FALSE sends a GATT notification, 
+ *                                      TRUE sends a GATT indication
+ * @param[in]      *p_value             the value to be written
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_send_indication(uint8_t server_if, uint16_t attribute_handle, uint16_t conn_id, int len, int confirm, char *p_value);
+
+/**
+ * @brief          send a response to a read/write operation
+ *
+ * @param[in]      conn_id          connection id create when connection established
+ * @param[in]      trans_id         the transation identifier
+ * @param[in]      status           TODO:
+ * @param[in]      offset           the offset the fragmented value
+ * @param[in]      attr_handle      the attribute handle
+ * @param[in]      auth_req         access properties
+ * @param[in]      *p_value         the value to be written
+ * @param[in]      len              the length of value to be written
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_ble_server_send_response(uint16_t conn_id, uint32_t trans_id, uint8_t status, int offset, uint16_t attr_handle, int auth_req, uint8_t *p_value, int len);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_BLE_GATT_H */
+

+ 422 - 0
include/bt/wm_bt.h

@@ -0,0 +1,422 @@
+/**
+ * @file    wm_bt.h
+ *
+ * @brief   Bluetooth API
+ *
+ * @author  WinnerMicro
+ *
+ * Copyright (c) 2020 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_BT_H
+#define WM_BT_H
+
+#include "wm_bt_def.h"
+
+/**
+ * @defgroup BT_APIs Bluetooth APIs
+ * @brief Bluetooth related APIs
+ */
+
+/**
+ * @addtogroup BT_APIs
+ * @{
+ */
+
+/**
+ * @defgroup BT_Host_APIs BT Host APIs
+ * @brief BT Host APIs
+ */
+
+/**
+ * @addtogroup BT_Host_APIs
+ * @{
+ */
+
+
+/**
+ * @brief          reply the pin request
+ *
+ * @param[in]      *bd_addr         remote device address
+ * @param[in]      accept
+ * @param[in]      pin_len
+ * @param[in]      *pin_code
+ *
+ * @return		@ref tls_bt_status_t
+
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_bt_pin_reply(const tls_bt_addr_t *bd_addr, uint8_t accept,
+                     uint8_t pin_len, tls_bt_pin_code_t *pin_code);
+
+/**
+ * @brief          reply the ssp request
+ *
+ * @param[in]      *bd_addr         remote device address
+ * @param[in]      variant           @ref tls_bt_ssp_variant_t
+ * @param[in]      accept
+ * @param[in]      passkey
+ *
+ * @return		@ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_bt_ssp_reply(const tls_bt_addr_t *bd_addr, tls_bt_ssp_variant_t variant,
+                     uint8_t accept, uint32_t passkey);
+
+/**
+ * @brief          set the adapter property
+ *
+ * @param[in]      *property         remote device address
+ * @param[in]      update_to_flash  save the property to flash or not
+ *
+ * @return	       @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_set_adapter_property(const tls_bt_property_t *property, uint8_t update_to_flash);
+
+/**
+ * @brief          get the adapter property
+ *
+ * @param[in]      type         @ref tls_bt_property_type_t
+ *
+ * @return	       @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_get_adapter_property(tls_bt_property_type_t type);
+
+/**
+ * @brief          
+ *
+ * @param          None
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_start_discovery(void);
+
+/**
+ * @brief          
+ *
+ * @param          None
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_cancel_discovery(void);
+
+/**
+ * @brief          
+ *
+ * @param[in]      *bd_addr
+ * @param[in]      transport
+ *
+ * @return	       @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_create_bond(const tls_bt_addr_t *bd_addr, int transport);
+
+/**
+ * @brief          
+ *
+ * @param[in]      *bd_addr
+ *
+ * @return	       @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_cancel_bond(const tls_bt_addr_t *bd_addr);
+
+/**
+ * @brief          
+ *
+ * @param[in]      *bd_addr
+ *
+ * @return	       @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_remove_bond(const tls_bt_addr_t *bd_addr);
+
+/**
+ * @brief          
+ *
+ * @param          None
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_host_cleanup(void);
+
+/**
+ * @brief          
+ *
+ * @param[in]      callback
+ * @param[in]      *p_hci_if
+ * @param[in]      log_level
+ *
+ * @return	       @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_enable(tls_bt_host_callback_t callback, tls_bt_hci_if_t *p_hci_if, tls_bt_log_level_t log_level);
+
+/**
+ * @brief          
+ *
+ * @param          None
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_disable();
+
+
+/**
+ * @}
+ */
+
+
+
+/**
+ * @defgroup BT_Controller_APIs BT Controller APIs
+ * @brief BT Controller APIs
+ */
+
+/**
+ * @addtogroup BT_Controller_APIs
+ * @{
+ */
+
+/**
+ * @brief          enable the bluetooth controller stack
+ *
+ * @param[in]      *p_hci_if     pointer on uart property
+ * @param[in]       log_level    @ref tls_bt_log_level_t
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_ctrl_enable(tls_bt_hci_if_t *p_hci_if, tls_bt_log_level_t log_level);
+
+
+/**
+ * @brief          disable the bluetooth controller stack
+ *
+ * @param          None
+ *
+ * @return         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_ctrl_disable(void);
+
+/**
+ * @brief          configure the ble emit power of different ble handle type
+ *
+ * @param[in]      power_type     @ref tls_ble_power_type_t
+ * @param[in]      power_level_index    [1,2,3,4,5] map to[1,4,7,10,13]dBm
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           power_type, supports TLS_BLE_PWR_TYPE_DEFAULT only. 
+ */
+tls_bt_status_t tls_ble_set_tx_power(tls_ble_power_type_t power_type, int8_t power_level_index);
+
+/**
+ * @brief          get the ble emit power of different ble handle type
+ *
+ * @param[in]      power_type     @ref tls_ble_power_type_t
+ *
+ * @retval         power value db
+ *
+ * @note           power_type, supports TLS_BLE_PWR_TYPE_DEFAULT only. 
+ */
+int8_t  tls_ble_get_tx_power(tls_ble_power_type_t power_type);
+
+/**
+ * @brief          configure the classic/enhanced bluetooth transmit power
+ *
+ * @param[in]      min_power_level    power level[1,13]dBm
+ * @param[in]      max_power_level    power level[1,13]dBm
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bredr_set_tx_power(int8_t min_power_level,int8_t max_power_level);
+
+/**
+ * @brief          get the classic/enhanced bluetooth transmit power level
+ *
+ * @param[in]      *min_power_level    pointer on min_power_level
+ * @param[in]      *max_power_level    pointer on max_power_level
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t  tls_bredr_get_tx_power(int8_t* min_power_level, int8_t* max_power_level);
+
+/**
+ * @brief          configure the voice output path
+ *
+ * @param[in]      data_path    @ref tls_sco_data_path_t
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bredr_sco_datapath_set(tls_sco_data_path_t data_path);
+
+/**
+ * @brief          get controller stack status
+ *
+ * @param          None
+ *
+ * @retval         @ref tls_bt_ctrl_status_t
+ *
+ * @note           None
+ */
+tls_bt_ctrl_status_t tls_bt_controller_get_status(void);
+
+/**
+ * @brief          this function receive the hci message from host hci_h4 inteface
+ *
+ * @param[in]      *data    hci formated message
+ * @param[in]       len     command length
+ *
+ * @retval         @ref tls_bt_ctrl_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_vuart_host_send_packet( uint8_t *data, uint16_t len);
+
+/**
+ * @brief          this function register the host stack receive message function 
+ *                 and indication the controller receive hci command avaiable
+ *
+ * @param[in]      *p_host_if       @ref tls_bt_host_if_t
+ *
+ * @retval         @ref tls_bt_ctrl_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_ctrl_if_register(const tls_bt_host_if_t *p_host_if);
+
+/**
+ * @brief          this function unregister the host stack receive message function 
+ *                 and indication the controller receive hci command avaiable
+ *
+ * @param     None
+ *
+ * @retval         @ref tls_bt_ctrl_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_ctrl_if_unregister();
+
+
+/**
+ * @brief          this function configure the controller enter into sleep mode when controller
+ *                 is in idle mode
+ *
+ * @param[in]      enable       TRUE:  enable
+ *                              FALSE: didsable
+ *
+ * @retval         @ref tls_bt_ctrl_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_ctrl_sleep(bool enable);
+
+/**
+ * @brief          this function look up the controller is in sleep mode or not
+ *
+ * @param          None
+ *
+ * @retval         TRUE:  sleep mode
+ *                 FALSE: not sleep mode
+ *
+ * @note           None
+ */
+bool  tls_bt_ctrl_is_sleep(void);
+
+/**
+ * @brief          this function wake up the controller, in other words exit sleep mode
+ *
+ * @param          None
+ *
+ * @retval         @ref tls_bt_ctrl_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_ctrl_wakeup(void);
+
+/**
+ * @brief          this function check controller can handle hci commands yes or no
+ *
+ * @param          None
+ *
+ * @retval         @ref bool TRUE or FALSE
+ *
+ * @note           None
+ */
+
+bool tls_bt_vuart_host_check_send_available();
+
+/**
+ * @brief          this function exit bluetooth test mode
+ *
+ * @param          None
+ *
+ * @retval         @ref tls_bt_ctrl_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t exit_bt_test_mode();
+
+/**
+ * @brief          this function enable bluetooth test mode
+ *
+ * @param[in]       p_hci_if, specific the uart port property
+ *
+ * @retval         @ref tls_bt_ctrl_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t enable_bt_test_mode(tls_bt_hci_if_t *p_hci_if);
+
+/**
+ * @brief          this function enable rf to bluetooth mode
+ *
+ * @param[in]       1, bluetooth mode, 0 wifi/bluetooth mode
+ *
+ * @retval         None
+ *
+ * @note           None
+ */
+
+void tls_rf_bt_mode(uint8_t enable);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_BT_H */
+

+ 300 - 0
include/bt/wm_bt_av.h

@@ -0,0 +1,300 @@
+/**
+ * @file    wm_bt_av.h
+ *
+ * @brief   Bluetooth API
+ *
+ * @author  WinnerMicro
+ *
+ * Copyright (c) 2020 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef __WM_BT_A2DP_H__
+#define __WM_BT_A2DP_H__
+
+#include "wm_bt.h"
+
+/**
+ * @defgroup BT_APIs Bluetooth APIs
+ * @brief Bluetooth related APIs
+ */
+
+/**
+ * @addtogroup BT_APIs
+ * @{
+ */
+
+/**
+ * @defgroup BT_AV_APIs
+ * @brief BT_AV APIs
+ */
+
+/**
+ * @addtogroup BT_AV_APIs
+ * @{
+ */
+
+/**sink realed api*/
+/**
+ * @brief          Initializes the AV interface for sink mode
+ *
+ * @param[in]     callback      pointer on callback function
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_av_sink_init(tls_bt_a2dp_sink_callback_t callback);
+
+/**
+ * @brief          Shuts down the AV sink interface and does the cleanup
+ *
+ * @param       None
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_av_sink_deinit(void);
+
+/**
+ * @brief          Establishes the AV signalling channel with the source
+ *
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_av_sink_connect_src(tls_bt_addr_t *bd_addr);
+
+
+/**
+ * @brief          Tears down the AV signalling channel with the source side
+ *
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_av_sink_disconnect(tls_bt_addr_t *bd_addr);
+
+/**src realed api*/
+
+/**
+ * @brief          Initializes the AV interface for source mode
+ *
+ * @param[in]     callback      pointer on callback function
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_av_src_init(tls_bt_a2dp_src_callback_t callback);
+
+/**
+ * @brief          Shuts down the AV source interface and does the cleanup
+ *
+ * @param       None
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_av_src_deinit(void);
+
+/**
+ * @brief          Establishes the AV signalling channel with the sink
+ *
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_av_src_connect_sink(tls_bt_addr_t *bd_addr);
+
+/**
+ * @brief          Tears down the AV signalling channel with the sink side
+ *
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_av_src_disconnect(tls_bt_addr_t *bd_addr);
+
+/**btrc related api supported by now*/
+
+/**
+ * @brief          Initializes the AVRC interface
+ *
+ * @param[in]     callback      pointer on callback function
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_btrc_init(tls_btrc_callback_t callback);
+
+/**
+ * @brief          Closes the AVRC interface
+ *
+ * @param       None
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_btrc_deinit(void);
+
+/**
+ * @brief          Returns the current play status.
+ *
+ * @param[in]     tls_btrc_play_status_t      stopped, playing, paused...
+ * @param[in]     song_len     seconds of the song 
+ * @param[in]     song_pos    played seconds of the song
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           This method is called in response to GetPlayStatus request.
+ */
+tls_bt_status_t tls_btrc_get_play_status_rsp(tls_btrc_play_status_t play_status, uint32_t song_len,
+                                       uint32_t song_pos);
+
+/**
+ * @brief          Returns the current songs' element attributes in text
+ *
+ * @param[in]     num_attr     counter of song`s element attributes
+ * @param[in]     p_attrs     pointer of element attributes
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_btrc_get_element_attr_rsp(uint8_t num_attr, tls_btrc_element_attr_val_t *p_attrs);
+
+/**
+ * @brief          Response to the register notification request in text
+ *
+ * @param[in]     event_id      play_status, track or play_pos changed
+ * @param[in]     type     notification type
+ * @param[in]     p_param    pointer to details of notification structer
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_btrc_register_notification_rsp(tls_btrc_event_id_t event_id,
+        tls_btrc_notification_type_t type, tls_btrc_register_notification_t *p_param);
+
+
+/**
+ * @brief          Send current volume setting to remote side
+ *
+ * @param[in]    volue      Should be in the range 0-127. bit7 is reseved and cannot be set
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           Support limited to SetAbsoluteVolume
+ * 			 This can be enhanced to support Relative Volume (AVRCP 1.0).
+ *                   With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN
+ *                   as opposed to absolute volume level
+ */
+tls_bt_status_t tls_btrc_set_volume(uint8_t volume);
+
+/**btrc ctrl related api supported by now*/
+
+/**
+ * @brief          Initializes the AVRC ctrl interface
+ *
+ * @param[in]     callback      pointer on callback function
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_btrc_ctrl_init(tls_btrc_ctrl_callback_t callback);
+
+/**
+ * @brief          Closes the AVRC ctrl interface
+ *
+ * @param       None
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_btrc_ctrl_deinit(void);
+
+/**
+ * @brief           Send Pass-Through command
+ *
+ * @param[in]     bd_addr      remote device bluetooth device address
+ * @param[in]     key_code    code definition of the key
+ * @param[in]     key_state    key stae
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_btrc_ctrl_send_passthrough_cmd(tls_bt_addr_t *bd_addr, uint8_t key_code, uint8_t key_state);
+
+/**
+ * @brief           Send group  navigation command
+ *
+ * @param[in]     bd_addr      remote device bluetooth device address
+ * @param[in]     key_code    code definition of the key
+ * @param[in]     key_state    key stae
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_btrc_ctrl_send_groupnavigation_cmd(tls_bt_addr_t *bd_addr, uint8_t key_code, uint8_t key_state);
+
+/**
+ * @brief           Set current values of Player Attributes
+ *
+ * @param[in]     bd_addr        remote device bluetooth device address
+ * @param[in]     num_attrib    couner of attributes
+ * @param[in]     attrib_ids     atrribute of index indicator
+  * @param[in]    attrib_vals    attribute of values
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_btrc_ctrl_change_player_app_setting(tls_bt_addr_t *bd_addr, uint8_t num_attrib, uint8_t *attrib_ids, uint8_t *attrib_vals);
+
+
+/**
+ * @brief          Rsp for SetAbsoluteVolume Command
+ *
+ * @param[in]     bd_addr        remote device bluetooth device address
+ * @param[in]     abs_vol       the absolute volume
+ * @param[in]     label           label indicator
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_btrc_ctrl_set_volume_rsp(tls_bt_addr_t *bd_addr, uint8_t abs_vol, uint8_t label);
+
+
+/**
+ * @brief          Rsp for Notification of Absolute Volume
+ *
+ * @param[in]     bd_addr        remote device bluetooth device address
+ * @param[in]     rsp_type       interim or changed
+  * @param[in]    abs_vol      the absolute volume value
+ * @param[in]     label           label indicator
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_btrc_ctrl_volume_change_notification_rsp(tls_bt_addr_t *bd_addr, tls_btrc_notification_type_t rsp_type,uint8_t abs_vol, uint8_t label);
+
+#endif

+ 1893 - 0
include/bt/wm_bt_def.h

@@ -0,0 +1,1893 @@
+/**
+ * @file    wm_bt_def.h
+ *
+ * @brief   Bluetooth Define
+ *
+ * @author  WinnerMicro
+ *
+ * Copyright (c) 2020 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_BT_DEF_H
+#define WM_BT_DEF_H
+
+/** Bluetooth Error Status */
+typedef enum
+{
+    TLS_BT_STATUS_SUCCESS, /**< success */
+    TLS_BT_STATUS_FAIL,
+    TLS_BT_STATUS_NOT_READY,
+    TLS_BT_STATUS_NOMEM, /**< alloc memory failed */
+    TLS_BT_STATUS_BUSY,
+    TLS_BT_STATUS_DONE,        /**< request already completed */
+    TLS_BT_STATUS_UNSUPPORTED,
+    TLS_BT_STATUS_PARM_INVALID,
+    TLS_BT_STATUS_UNHANDLED,
+    TLS_BT_STATUS_AUTH_FAILURE,
+    TLS_BT_STATUS_RMT_DEV_DOWN,
+    TLS_BT_STATUS_AUTH_REJECTED,
+    TLS_BT_STATUS_THREAD_FAILED, /**< create internal thread failed */
+    TLS_BT_STATUS_INTERNAL_ERROR, /**< controller stack internal error */
+    TLS_BT_STATUS_CTRL_ENABLE_FAILED,
+    TLS_BT_STATUS_HOST_ENABLE_FAILED,
+    TLS_BT_STATUS_CTRL_DISABLE_FAILED,
+    TLS_BT_STATUS_HOST_DISABLE_FAILED,
+
+} tls_bt_status_t;
+
+typedef enum
+{
+    TLS_BT_CTRL_IDLE     =              (1<<0),
+    TLS_BT_CTRL_ENABLED  =              (1<<1),
+    TLS_BT_CTRL_SLEEPING =              (1<<2),
+    TLS_BT_CTRL_BLE_ROLE_MASTER =       (1<<3),
+    TLS_BT_CTRL_BLE_ROLE_SLAVE =        (1<<4),
+    TLS_BT_CTRL_BLE_ROLE_END =          (1<<5),
+    TLS_BT_CTRL_BLE_STATE_IDLE =        (1<<6),
+    TLS_BT_CTRL_BLE_STATE_ADVERTISING = (1<<7),
+    TLS_BT_CTRL_BLE_STATE_SCANNING =    (1<<8),
+    TLS_BT_CTRL_BLE_STATE_INITIATING =  (1<<9),
+    TLS_BT_CTRL_BLE_STATE_STOPPING =    (1<<10),
+    TLS_BT_CTRL_BLE_STATE_TESTING =     (1<<11),
+} tls_bt_ctrl_status_t;
+
+/** Bluetooth Adapter State */
+typedef enum
+{
+    WM_BT_STATE_OFF,
+    WM_BT_STATE_ON
+} tls_bt_state_t;
+
+/** bluetooth host statck events */
+typedef enum
+{
+    WM_BT_ADAPTER_STATE_CHG_EVT = (0x01<<0),        
+    WM_BT_ADAPTER_PROP_CHG_EVT  = (0x01<<1),   
+    WM_BT_RMT_DEVICE_PROP_EVT   = (0x01<<2),               
+    WM_BT_DEVICE_FOUND_EVT      = (0x01<<3), 
+    WM_BT_DISCOVERY_STATE_CHG_EVT=(0x01<<4),
+    WM_BT_REQUEST_EVT           = (0x01<<5),
+    WM_BT_SSP_REQUEST_EVT       = (0x01<<6),
+    WM_BT_PIN_REQUEST_EVT       = (0x01<<7),
+    WM_BT_BOND_STATE_CHG_EVT    = (0x01<<8),
+    WM_BT_ACL_STATE_CHG_EVT     = (0x01<<9),
+    WM_BT_ENERGY_INFO_EVT       = (0x01<<10),
+    WM_BT_LE_TEST_EVT           = (0x01<<11),
+} tls_bt_host_evt_t;
+
+typedef struct
+{
+    tls_bt_state_t         status; /**< bluetooth adapter state */
+} tls_bt_adapter_state_change_msg_t;
+
+/** Bluetooth Adapter and Remote Device property types */
+typedef enum
+{
+    /* Properties common to both adapter and remote device */
+    /**
+     * Description - Bluetooth Device Name
+     * Access mode - Adapter name can be GET/SET. Remote device can be GET
+     * Data type   - bt_bdname_t
+     */
+    WM_BT_PROPERTY_BDNAME = 0x1,
+    /**
+     * Description - Bluetooth Device Address
+     * Access mode - Only GET.
+     * Data type   - bt_bdaddr_t
+     */
+    WM_BT_PROPERTY_BDADDR,
+    /**
+     * Description - Bluetooth Service 128-bit UUIDs
+     * Access mode - Only GET.
+     * Data type   - Array of bt_uuid_t (Array size inferred from property length).
+     */
+    WM_BT_PROPERTY_UUIDS,
+    /**
+     * Description - Bluetooth Class of Device as found in Assigned Numbers
+     * Access mode - Only GET.
+     * Data type   - uint32_t.
+     */
+    WM_BT_PROPERTY_CLASS_OF_DEVICE,
+    /**
+     * Description - Device Type - BREDR, BLE or DUAL Mode
+     * Access mode - Only GET.
+     * Data type   - bt_device_type_t
+     */
+    WM_BT_PROPERTY_TYPE_OF_DEVICE,
+    /**
+     * Description - Bluetooth Service Record
+     * Access mode - Only GET.
+     * Data type   - bt_service_record_t
+     */
+    WM_BT_PROPERTY_SERVICE_RECORD,
+
+    /* Properties unique to adapter */
+    /**
+     * Description - Bluetooth Adapter scan mode
+     * Access mode - GET and SET
+     * Data type   - bt_scan_mode_t.
+     */
+    WM_BT_PROPERTY_ADAPTER_SCAN_MODE,
+    /**
+     * Description - List of bonded devices
+     * Access mode - Only GET.
+     * Data type   - Array of bt_bdaddr_t of the bonded remote devices
+     *               (Array size inferred from property length).
+     */
+    WM_BT_PROPERTY_ADAPTER_BONDED_DEVICES,
+    /**
+     * Description - Bluetooth Adapter Discovery timeout (in seconds)
+     * Access mode - GET and SET
+     * Data type   - uint32_t
+     */
+    WM_BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
+
+    /* Properties unique to remote device */
+    /**
+     * Description - User defined friendly name of the remote device
+     * Access mode - GET and SET
+     * Data type   - bt_bdname_t.
+     */
+    WM_BT_PROPERTY_REMOTE_FRIENDLY_NAME,
+    /**
+     * Description - RSSI value of the inquired remote device
+     * Access mode - Only GET.
+     * Data type   - int32_t.
+     */
+    WM_BT_PROPERTY_REMOTE_RSSI,
+    /**
+     * Description - Remote version info
+     * Access mode - SET/GET.
+     * Data type   - bt_remote_version_t.
+     */
+
+    WM_BT_PROPERTY_REMOTE_VERSION_INFO,
+
+    /**
+     * Description - Local LE features
+     * Access mode - GET.
+     * Data type   - bt_local_le_features_t.
+     */
+    WM_BT_PROPERTY_LOCAL_LE_FEATURES,
+
+    WM_BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP = 0xFF,
+} tls_bt_property_type_t;
+
+/** Bluetooth Adapter Property data structure */
+typedef struct
+{
+    tls_bt_property_type_t type;
+    int len;
+    void *val;
+} tls_bt_property_t;
+
+typedef struct
+{
+    tls_bt_status_t     status; 
+	int num_properties;
+	tls_bt_property_t *properties; /**< bluetooth adapter property data */
+} tls_bt_adapter_prop_msg_t; 
+
+typedef enum
+{ 
+    WM_BLE_SCAN_STOP = 0,
+    WM_BLE_SCAN_PASSIVE = 1,
+    WM_BLE_SCAN_ACTIVE = 2,
+    
+} wm_ble_scan_type_t;
+
+typedef enum
+{
+    WM_BLE_ADV_DATA = 0,
+    WM_BLE_ADV_RSP_DATA,
+} wm_ble_gap_data_t;
+
+typedef enum{
+    WM_BLE_ADV_STOP = 0,
+    WM_BLE_ADV_IND,
+    WM_BLE_ADV_DIRECT_IND_HDC,  /*<high duty cycle, directed advertising>*/
+    WM_BLE_ADV_SCAN_IND,
+    WM_BLE_ADV_NONCONN_IND,
+    WM_BLE_ADV_DIRECT_IND_LDC,  /*<low duty cycle, directed advertising>*/
+} wm_ble_adv_type_t;
+
+#define WM_BLE_GAP_EVENT_CONNECT               (0x01<<0)
+#define WM_BLE_GAP_EVENT_DISCONNECT            (0x01<<1)
+/* Reserved                                 2 */
+#define WM_BLE_GAP_EVENT_CONN_UPDATE           (0x01<<3)
+#define WM_BLE_GAP_EVENT_CONN_UPDATE_REQ       (0x01<<4)
+#define WM_BLE_GAP_EVENT_L2CAP_UPDATE_REQ      (0x01<<5)
+#define WM_BLE_GAP_EVENT_TERM_FAILURE          (0x01<<6)
+#define WM_BLE_GAP_EVENT_DISC                  (0x01<<7)
+#define WM_BLE_GAP_EVENT_DISC_COMPLETE         (0x01<<8)
+#define WM_BLE_GAP_EVENT_ADV_COMPLETE          (0x01<<9)
+#define WM_BLE_GAP_EVENT_ENC_CHANGE            (0x01<<10)
+#define WM_BLE_GAP_EVENT_PASSKEY_ACTION        (0x01<<11)
+#define WM_BLE_GAP_EVENT_NOTIFY_RX             (0x01<<12)
+#define WM_BLE_GAP_EVENT_NOTIFY_TX             (0x01<<13)
+#define WM_BLE_GAP_EVENT_SUBSCRIBE             (0x01<<14)
+#define WM_BLE_GAP_EVENT_MTU                   (0x01<<15)
+#define WM_BLE_GAP_EVENT_IDENTITY_RESOLVED     (0x01<<16)
+#define WM_BLE_GAP_EVENT_REPEAT_PAIRING        (0x01<<17)
+#define WM_BLE_GAP_EVENT_PHY_UPDATE_COMPLETE   (0x01<<18)
+#define WM_BLE_GAP_EVENT_EXT_DISC              (0x01<<19)
+#define WM_BLE_GAP_EVENT_PERIODIC_SYNC         (0x01<<20)
+#define WM_BLE_GAP_EVENT_PERIODIC_REPORT       (0x01<<21)
+#define WM_BLE_GAP_EVENT_PERIODIC_SYNC_LOST    (0x01<<22)
+#define WM_BLE_GAP_EVENT_SCAN_REQ_RCVD         (0x01<<23)
+#define WM_BLE_GAP_EVENT_PERIODIC_TRANSFER     (0x01<<24)
+
+
+/** Bluetooth Address */
+typedef struct
+{
+    uint8_t address[6];
+} __attribute__((packed))tls_bt_addr_t;
+
+typedef struct
+{
+    tls_bt_status_t     status;
+	tls_bt_addr_t     *address;
+	int num_properties;
+	tls_bt_property_t *properties; /**< bluetooth adapter property data */
+} tls_bt_remote_dev_prop_msg_t;
+
+typedef struct
+{
+	int num_properties;
+	tls_bt_property_t *properties; /**< bluetooth adapter property data */
+} tls_bt_device_found_msg_t;
+
+/** Bluetooth Adapter Discovery state */
+typedef enum
+{
+    WM_BT_DISCOVERY_STOPPED,
+    WM_BT_DISCOVERY_STARTED
+} tls_bt_discovery_state_t;
+
+typedef struct
+{
+	tls_bt_discovery_state_t state;
+} tls_bt_discovery_state_chg_msg_t;
+
+/** Bluetooth Device Name */
+typedef struct
+{
+    uint8_t name[249];
+} __attribute__((packed))tls_bt_bdname_t;
+
+typedef struct
+{
+	tls_bt_addr_t *remote_bd_addr;
+	tls_bt_bdname_t *bd_name;
+	uint32_t cod;
+	uint8_t  min_16_digit;
+} tls_bt_pin_request_msg_t;
+
+/** Bluetooth SSP Bonding Variant */
+typedef enum
+{
+    WM_BT_SSP_VARIANT_PASSKEY_CONFIRMATION,
+    WM_BT_SSP_VARIANT_PASSKEY_ENTRY,
+    WM_BT_SSP_VARIANT_CONSENT,
+    WM_BT_SSP_VARIANT_PASSKEY_NOTIFICATION
+} tls_bt_ssp_variant_t;
+
+/** Bluetooth PinKey Code */
+typedef struct
+{
+    uint8_t pin[16];
+} __attribute__((packed))tls_bt_pin_code_t;
+
+typedef struct
+{
+	tls_bt_addr_t *remote_bd_addr;
+	tls_bt_bdname_t *bd_name;
+	uint32_t cod;
+	tls_bt_ssp_variant_t pairing_variant;
+	uint32_t pass_key;
+} tls_bt_ssp_request_msg_t;
+
+/** Bluetooth Bond state */
+typedef enum
+{
+    WM_BT_BOND_STATE_NONE,
+    WM_BT_BOND_STATE_BONDING,
+    WM_BT_BOND_STATE_BONDED
+} tls_bt_bond_state_t;
+
+typedef struct
+{
+	tls_bt_status_t status;
+	tls_bt_addr_t *remote_bd_addr;
+	tls_bt_bond_state_t state;
+} tls_bt_bond_state_chg_msg_t;
+
+/** Bluetooth ACL connection state */
+typedef enum
+{
+    WM_BT_ACL_STATE_CONNECTED,
+    WM_BT_ACL_STATE_DISCONNECTED
+} tls_bt_acl_state_t;
+
+typedef struct
+{
+	tls_bt_status_t status;
+	tls_bt_addr_t *remote_address;
+    uint8_t link_type;
+	tls_bt_acl_state_t state;
+} tls_bt_acl_state_chg_msg_t;
+
+typedef struct
+{
+    uint8_t status;
+    uint8_t ctrl_state;     /* stack reported state */
+    uint64_t tx_time;       /* in ms */
+    uint64_t rx_time;       /* in ms */
+    uint64_t idle_time;     /* in ms */
+    uint64_t energy_used;   /* a product of mA, V and ms */
+} __attribute__((packed))tls_bt_activity_energy_info;
+
+typedef struct
+{
+	tls_bt_activity_energy_info *energy_info;
+} tls_bt_energy_info_msg_t;
+
+typedef struct
+{
+	uint8_t status;
+	uint32_t count;
+} tls_bt_ble_test_msg_t;
+
+typedef union
+{
+	tls_bt_adapter_state_change_msg_t	     adapter_state_change;	  
+	tls_bt_adapter_prop_msg_t	             adapter_prop;	  
+	tls_bt_remote_dev_prop_msg_t		     remote_device_prop;
+	tls_bt_device_found_msg_t                device_found;
+	tls_bt_discovery_state_chg_msg_t         discovery_state;
+	tls_bt_pin_request_msg_t                 pin_request;
+	tls_bt_ssp_request_msg_t                 ssp_request;
+	tls_bt_bond_state_chg_msg_t              bond_state;
+	tls_bt_acl_state_chg_msg_t               acl_state;
+	tls_bt_energy_info_msg_t                 energy_info;
+	tls_bt_ble_test_msg_t                    ble_test;
+} tls_bt_host_msg_t;
+
+/** BT host callback function */
+typedef void (*tls_bt_host_callback_t)(tls_bt_host_evt_t event, tls_bt_host_msg_t *p_data);
+
+
+typedef enum
+{
+	TLS_BT_LOG_NONE = 0,
+	TLS_BT_LOG_ERROR = 1,
+	TLS_BT_LOG_WARNING = 2,
+	TLS_BT_LOG_API = 3,
+	TLS_BT_LOG_EVENT = 4,
+	TLS_BT_LOG_DEBUG = 5,
+	TLS_BT_LOG_VERBOSE = 6,
+} tls_bt_log_level_t;
+
+typedef struct
+{
+  uint8_t  uart_index;  /**< uart port index, 1~4 */
+  uint32_t band_rate;   /**< band rate: 115200 ~ 2M */
+  uint8_t data_bit;     /**< data bit:5 ~ 8 */
+  uint8_t verify_bit;   /**< 0:NONE, 1 ODD, 2 EVEN */
+  uint8_t stop_bit;     /**< 0:1bit; 1:1.5bit; 2:2bits */
+} tls_bt_hci_if_t;
+
+typedef enum
+{
+	TLS_BLE_PWR_TYPE_CONN_HDL0,
+	TLS_BLE_PWR_TYPE_CONN_HDL1,
+	TLS_BLE_PWR_TYPE_CONN_HDL2,
+	TLS_BLE_PWR_TYPE_CONN_HDL3,
+	TLS_BLE_PWR_TYPE_CONN_HDL4,
+	TLS_BLE_PWR_TYPE_CONN_HDL5,
+	TLS_BLE_PWR_TYPE_CONN_HDL6,
+	TLS_BLE_PWR_TYPE_CONN_HDL7,
+	TLS_BLE_PWR_TYPE_CONN_HDL8,
+	TLS_BLE_PWR_TYPE_ADV,
+	TLS_BLE_PWR_TYPE_SCAN,
+	TLS_BLE_PWR_TYPE_DEFAULT,
+} tls_ble_power_type_t;
+
+typedef enum
+{
+	WM_AUDIO_OVER_HCI = 0,
+	WM_AUDIO_INTERNAL_MODE,
+} tls_sco_data_path_t;
+
+
+typedef struct
+{
+	void (*notify_controller_avaiable_hci_buffer)(int cnt);
+	void (*notify_host_recv_h4)(uint8_t *ptr, uint16_t length);
+} tls_bt_host_if_t;
+
+
+/*****************************************************************************
+ **  Constants and Type Definitions
+ *****************************************************************************/
+
+
+/** Attribute permissions */
+#define WM_GATT_PERM_READ              (1 << 0) /**< bit 0 -  0x0001 */
+#define WM_GATT_PERM_READ_ENCRYPTED    (1 << 1) /**< bit 1 -  0x0002 */
+#define WM_GATT_PERM_READ_ENC_MITM     (1 << 2) /**< bit 2 -  0x0004 */
+#define WM_GATT_PERM_WRITE             (1 << 4) /**< bit 4 -  0x0010 */
+#define WM_GATT_PERM_WRITE_ENCRYPTED   (1 << 5) /**< bit 5 -  0x0020 */
+#define WM_GATT_PERM_WRITE_ENC_MITM    (1 << 6) /**< bit 6 -  0x0040 */
+#define WM_GATT_PERM_WRITE_SIGNED      (1 << 7) /**< bit 7 -  0x0080 */
+#define WM_GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /**< bit 8 -  0x0100 */
+
+/** definition of characteristic properties */
+#define WM_GATT_CHAR_PROP_BIT_BROADCAST    (1 << 0)   /**< 0x01 */
+#define WM_GATT_CHAR_PROP_BIT_READ         (1 << 1)   /**< 0x02 */
+#define WM_GATT_CHAR_PROP_BIT_WRITE_NR     (1 << 2)   /**< 0x04 */
+#define WM_GATT_CHAR_PROP_BIT_WRITE        (1 << 3)   /**< 0x08 */
+#define WM_GATT_CHAR_PROP_BIT_NOTIFY       (1 << 4)   /**< 0x10 */
+#define WM_GATT_CHAR_PROP_BIT_INDICATE     (1 << 5)   /**< 0x20 */
+#define WM_GATT_CHAR_PROP_BIT_AUTH         (1 << 6)   /**< 0x40 */
+#define WM_GATT_CHAR_PROP_BIT_EXT_PROP     (1 << 7)   /**< 0x80 */
+
+#define WM_BLE_MAX_ATTR_LEN    600
+
+
+
+/** max client application WM BLE Client can support */
+#ifndef WM_BLE_CLIENT_MAX
+    #define WM_BLE_CLIENT_MAX              3
+#endif
+
+/** max server application WM BLE Server can support */
+#define WM_BLE_SERVER_MAX              4
+#define WM_BLE_ATTRIBUTE_MAX           50
+
+#ifndef WM_BLE_SERVER_SECURITY
+    #define WM_BLE_SERVER_SECURITY         BTA_DM_BLE_SEC_NONE
+#endif
+
+#define WM_BLE_INVALID_IF              0xFF
+#define WM_BLE_INVALID_CONN            0xFFFF
+
+#define WM_BLE_GATT_TRANSPORT_LE                           0x02
+#define WM_BLE_GATT_TRANSPORT_BR_EDR                       0x01
+#define WM_BLE_GATT_TRANSPORT_LE_BR_EDR                    0x03
+
+#define WM_BLE_MAX_PDU_LENGTH                              251
+
+
+/** BLE events */
+typedef enum
+{
+    /** BLE Client events */
+    WM_BLE_CL_REGISTER_EVT,      /**< BLE client is registered. */
+    WM_BLE_CL_DEREGISTER_EVT,    /**< BLE client is deregistered. */
+    WM_BLE_CL_READ_CHAR_EVT,
+    WM_BLE_CL_WRITE_CHAR_EVT,
+    WM_BLE_CL_PREP_WRITE_EVT,
+    WM_BLE_CL_EXEC_CMPL_EVT,     /**< Execute complete event */
+    WM_BLE_CL_SEARCH_CMPL_EVT,   /**< GATT discovery complete event */
+    WM_BLE_CL_SEARCH_RES_EVT,    /**< GATT discovery result event */
+    WM_BLE_CL_READ_DESCR_EVT,
+    WM_BLE_CL_WRITE_DESCR_EVT,
+    WM_BLE_CL_NOTIF_EVT,         /**< GATT attribute notification event */
+    WM_BLE_CL_OPEN_EVT,          /**< BLE open request status  event */
+    WM_BLE_CL_CLOSE_EVT,         /**< GATTC  close request status event */
+    WM_BLE_CL_LISTEN_EVT,
+    WM_BLE_CL_CFG_MTU_EVT,       /**< configure MTU complete event */
+    WM_BLE_CL_CONGEST_EVT,       /**< GATT congestion/uncongestion event */
+    WM_BLE_CL_REPORT_DB_EVT,
+    WM_BLE_CL_REG_NOTIFY_EVT,
+    WM_BLE_CL_DEREG_NOTIFY_EVT,
+
+
+    /** BLE Server events */
+    WM_BLE_SE_REGISTER_EVT,      /**< BLE Server is registered */
+    WM_BLE_SE_DEREGISTER_EVT,    /**< BLE Server is deregistered */
+    WM_BLE_SE_CONNECT_EVT,
+    WM_BLE_SE_DISCONNECT_EVT,
+    WM_BLE_SE_CREATE_EVT,        /**< Service is created */
+    WM_BLE_SE_ADD_INCL_SRVC_EVT,
+    WM_BLE_SE_ADD_CHAR_EVT,       /**< char data is added */
+    WM_BLE_SE_ADD_CHAR_DESCR_EVT,
+    WM_BLE_SE_START_EVT,         /**< Service is started */
+    WM_BLE_SE_STOP_EVT,          /**< Service is stopped */
+    WM_BLE_SE_DELETE_EVT,
+    WM_BLE_SE_READ_EVT,          /**< Read request from client */
+    WM_BLE_SE_WRITE_EVT,         /**< Write request from client */
+    WM_BLE_SE_EXEC_WRITE_EVT,    /**< Execute Write request from client */
+    WM_BLE_SE_CONFIRM_EVT,       /**< Confirm event */
+    WM_BLE_SE_RESP_EVT,
+    WM_BLE_SE_CONGEST_EVT,       /**< Congestion event */
+    WM_BLE_SE_MTU_EVT,
+
+} tls_ble_evt_t;
+
+/* WM BLE Client Host callback events */
+/* Client callback function events */
+
+/** Bluetooth 128-bit UUID */
+typedef struct
+{
+    uint8_t uu[16];
+} tls_bt_uuid_t;
+
+/* callback event data for WM_BLE_CL_REGISTER_EVT/ event */
+typedef struct
+{
+    uint8_t         status; /**< operation status */
+    uint8_t         client_if; /**< Client interface ID */
+    tls_bt_uuid_t          app_uuid;  /**< Client uuid*/
+
+} tls_ble_cl_register_msg_t;
+
+/** callback event data for WM_BLE_CL_READ_CHAR_EVT /WM_BLE_CL_READ_CHAR_EVTevent */
+typedef struct
+{
+    uint16_t              conn_id;
+    uint8_t         status;
+    uint16_t              handle;
+    uint16_t              len;
+    uint8_t               *value;
+    uint16_t              value_type;
+} tls_ble_cl_read_msg_t;
+
+/** callback event data for WM_BLE_CL_WRITE_CHAR_EVT/WM_BLE_CL_PREP_WRITE_EVT/WM_BLE_CL_WRITE_DESCR_EVT event */
+typedef struct
+{
+    uint16_t              conn_id;
+    uint8_t         status;
+    uint16_t            handle;
+} tls_ble_cl_write_msg_t;
+
+/** callback event data for WM_BLE_CL_EXEC_CMPL_EVT event */
+typedef struct
+{
+    uint16_t              conn_id;
+    uint8_t         status;
+} tls_ble_cl_exec_cmpl_msg_t;
+
+/** callback event data for WM_BLE_CL_SEARCH_CMPL_EVT event */
+typedef struct
+{
+    uint16_t              conn_id;
+    uint8_t         status; /**< operation status */
+} tls_ble_cl_search_cmpl_msg_t;
+
+/** callback event data for WM_BLE_CL_SEARCH_RES_EVT event */
+typedef struct
+{
+    uint16_t              conn_id;
+    tls_bt_uuid_t             uuid;
+    uint8_t               inst_id;
+} tls_ble_cl_search_res_msg_t;
+
+/** callback event data for WM_BLE_CL_NOTIF_EVT event */
+typedef struct
+{
+    uint16_t              conn_id;
+    uint8_t               *value;
+    uint8_t             bda[6];
+    uint16_t            handle;
+    uint16_t              len;
+    bool             is_notify;
+} tls_ble_cl_notify_msg_t;
+
+/** callback event data for WM_BLE_CL_OPEN_EVT event */
+typedef struct
+{
+    uint16_t              conn_id;
+    uint8_t         status; /**< operation status */
+    uint8_t         client_if; /**< Client interface ID */
+    uint8_t             bd_addr[6];
+} tls_ble_cl_open_msg_t;
+
+/** callback event data for WM_BLE_CL_CLOSE_EVT event */
+typedef struct
+{
+    uint16_t              conn_id;
+    uint8_t         status;
+    uint8_t         client_if;
+    uint8_t             remote_bda[6];
+    uint16_t     reason;         /**< disconnect reason code, not useful when connect event is reported */
+} tls_ble_cl_close_msg_t;
+
+/** callback event data for WM_BLE_CL_LISTEN_EVT event */
+typedef struct
+{
+    uint8_t         status;
+    uint8_t        client_if;
+} tls_ble_cl_listen_msg_t;
+
+/** callback event data for WM_BLE_CL_CFG_MTU_EVT event */
+typedef struct
+{
+    uint16_t conn_id;
+    uint8_t         status;
+    uint16_t mtu;
+} tls_ble_cl_cfg_mtu_msg_t;
+
+typedef struct
+{
+    uint16_t              conn_id;
+    bool             congested; /**< congestion indicator */
+} tls_ble_cl_congest_msg_t;
+
+typedef enum
+{
+    WM_BTGATT_DB_PRIMARY_SERVICE,
+    WM_BTGATT_DB_SECONDARY_SERVICE,
+    WM_BTGATT_DB_INCLUDED_SERVICE,
+    WM_BTGATT_DB_CHARACTERISTIC,
+    WM_BTGATT_DB_DESCRIPTOR,
+} tls_bt_gatt_db_attribute_type_t;
+
+typedef struct
+{
+    uint16_t             id;
+    tls_bt_uuid_t           uuid;
+    tls_bt_gatt_db_attribute_type_t type;
+    uint16_t            attribute_handle;
+
+    /*
+     * If |type| is |BTGATT_DB_PRIMARY_SERVICE|, or
+     * |BTGATT_DB_SECONDARY_SERVICE|, this contains the start and end attribute
+     * handles.
+     */
+    uint16_t            start_handle;
+    uint16_t            end_handle;
+
+    /*
+     * If |type| is |BTGATT_DB_CHARACTERISTIC|, this contains the properties of
+     * the characteristic.
+     */
+    uint8_t             properties;
+} tls_btgatt_db_element_t;
+
+typedef struct
+{
+	uint16_t conn_id;
+	tls_btgatt_db_element_t *db;
+	int count;
+	uint8_t status;
+} tls_ble_cl_gatt_db_msg_t;
+
+typedef struct
+{
+	uint16_t conn_id;
+	uint8_t status;
+	bool reg;
+	uint16_t handle;
+	
+} tls_ble_cl_reg_notify_msg_t;
+
+
+/* WM BLE Server Host callback events */
+/* Server callback function events */
+
+/** callback event data for WM_BLE_SE_REGISTER_EVT/WM_BLE_SE_DEREGISTER_EVT event */
+typedef struct
+{
+    uint8_t         status; /* operation status */
+    uint8_t         server_if; /* Server interface ID */
+    tls_bt_uuid_t app_uuid;
+} tls_ble_se_register_msg_t;
+
+/** callback event data for WM_BLE_SE_CONNECT_EVT/WM_BLE_SE_DISCONNECT_EVT event */
+typedef struct
+{
+    uint16_t conn_id;
+    uint8_t         server_if; /**< Server interface ID */
+    bool connected;
+    uint16_t reason;
+    uint8_t addr[6];
+} tls_ble_se_connect_msg_t;
+
+typedef tls_ble_se_connect_msg_t tls_ble_se_disconnect_msg_t;
+
+/** callback event data for WM_BLE_SE_CREATE_EVT event */
+typedef struct
+{
+    uint8_t         status; /**< operation status */
+    uint8_t         server_if;
+    bool is_primary;
+    uint8_t inst_id;
+    tls_bt_uuid_t uuid;
+    uint16_t              service_id;
+} tls_ble_se_create_msg_t;
+
+/** callback event data for WM_BLE_SE_ADD_INCL_SRVC_EVT event */
+typedef struct
+{
+    uint8_t         status; /**< operation status */
+    uint8_t         server_if;
+    uint16_t           service_id;
+    uint16_t           attr_id;
+} tls_ble_se_add_incl_srvc_msg_t;
+
+/** callback event data for WM_BLE_SE_ADDCHAR_EVT event */
+typedef struct
+{
+    uint8_t         status; /**< operation status */
+    uint8_t         server_if;
+    tls_bt_uuid_t uuid;
+    uint16_t              service_id;
+    uint16_t              attr_id;
+} tls_ble_se_add_char_msg_t;
+
+typedef tls_ble_se_add_char_msg_t tls_ble_se_add_char_descr_msg_t;
+
+
+
+/** callback event data for WM_BLE_SE_START_EVT event */
+typedef struct
+{
+    uint8_t         status; /**< operation status */
+    uint8_t         server_if;
+    uint16_t              service_id;
+} tls_ble_se_start_msg_t;
+
+typedef tls_ble_se_start_msg_t tls_ble_se_stop_msg_t;
+
+typedef tls_ble_se_start_msg_t tls_ble_se_delete_msg_t;
+
+typedef struct
+{
+    uint16_t        conn_id;
+    uint32_t        trans_id;
+    uint8_t       remote_bda[6];
+    uint16_t        handle;
+    uint16_t        offset;
+    bool       is_long;
+} tls_ble_se_read_msg_t;
+
+typedef struct
+{
+    uint16_t              conn_id;
+    uint32_t              trans_id;
+    uint8_t             remote_bda[6];
+    uint16_t              handle;     /**< attribute handle */
+    uint16_t              offset;    /**< attribute value offset, if no offset is needed for the command, ignore it */
+    uint16_t              len;        /**< length of attribute value */
+    bool             need_rsp;   /**< need write response */
+    bool             is_prep;    /**< is prepare write */
+    uint8_t               *value;  /**< the actual attribute value */
+} tls_ble_se_write_msg_t;
+
+typedef struct
+{
+    uint16_t              conn_id;
+    uint32_t              trans_id;
+    uint8_t             remote_bda[6];
+    uint8_t exec_write;
+} tls_ble_se_exec_write_msg_t;
+
+typedef struct
+{
+    uint16_t              conn_id;
+    uint8_t         status; /**< operation status */
+
+} tls_ble_se_confirm_msg_t;
+
+typedef struct
+{
+    
+    uint8_t         status; /* operation status */
+	uint16_t        conn_id;
+	uint16_t        trans_id;
+
+} tls_ble_se_response_msg_t;
+
+typedef struct
+{
+    uint16_t              conn_id;
+    bool             congested; /**< congestion indicator */
+} tls_ble_se_congest_msg_t;
+
+typedef struct
+{
+    uint16_t              conn_id;
+    uint16_t            mtu;
+} tls_ble_se_mtu_msg_t;
+
+
+/** Union of data associated with HD callback */
+typedef union
+{
+    tls_ble_cl_register_msg_t    cli_register;      /**< WM_BLE_CL_REGISTER_EVT */
+    tls_ble_cl_read_msg_t        cli_read;          /**< WM_BLE_CL_READ_EVT */
+    tls_ble_cl_write_msg_t       cli_write;         /**< WM_BLE_CL_WRITE_EVT */
+    tls_ble_cl_exec_cmpl_msg_t   cli_exec_cmpl;     /**< WM_BLE_CL_EXEC_CMPL_EVT */
+    tls_ble_cl_search_cmpl_msg_t cli_search_cmpl;   /**< WM_BLE_CL_SEARCH_CMPL_EVT */
+    tls_ble_cl_search_res_msg_t  cli_search_res;    /**< WM_BLE_CL_SEARCH_RES_EVT */
+    tls_ble_cl_notify_msg_t      cli_notif;         /**< WM_BLE_CL_NOTIF_EVT */
+    tls_ble_cl_open_msg_t        cli_open;          /**< WM_BLE_CL_OPEN_EVT */
+    tls_ble_cl_close_msg_t       cli_close;         /**< WM_BLE_CL_CLOSE_EVT */
+    tls_ble_cl_listen_msg_t      cli_listen;        /**< WM_BLE_CL_LISTEN_EVT */
+    tls_ble_cl_cfg_mtu_msg_t     cli_cfg_mtu;       /**< WM_BLE_CL_CFG_MTU_EVT */
+    tls_ble_cl_congest_msg_t     cli_congest;       /**< WM_BLE_CL_CONGEST_EVT */
+	tls_ble_cl_gatt_db_msg_t     cli_db;            /* WM_BLE_CL_REPORT_DB_EVT*/
+	tls_ble_cl_reg_notify_msg_t  cli_reg_notify;
+
+
+    tls_ble_se_register_msg_t    ser_register;     /**< WM_BLE_SE_REGISTER_EVT */
+    tls_ble_se_connect_msg_t     ser_connect;      /**< WM_BLE_SE_OPEN_EVT */
+    tls_ble_se_disconnect_msg_t  ser_disconnect;   /**< WM_BLE_SE_CLOSE_EVT */
+    tls_ble_se_create_msg_t      ser_create;       /**< WM_BLE_SE_CREATE_EVT */
+    tls_ble_se_add_incl_srvc_msg_t ser_add_incl_srvc;
+    tls_ble_se_add_char_msg_t    ser_add_char;     /**< WM_BLE_SE_ADDCHAR_EVT */
+    tls_ble_se_add_char_descr_msg_t ser_add_char_descr;
+    tls_ble_se_start_msg_t       ser_start_srvc;   /**< WM_BLE_SE_START_EVT */
+    tls_ble_se_stop_msg_t        ser_stop_srvc;    /**< WM_BLE_SE_STOP_EVT */
+    tls_ble_se_delete_msg_t      ser_delete_srvc;
+    tls_ble_se_read_msg_t        ser_read;         /**< WM_BLE_SE_READ_EVT */
+    tls_ble_se_write_msg_t       ser_write;        /**< WM_BLE_SE_WRITE_EVT */
+    tls_ble_se_exec_write_msg_t  ser_exec_write;   /**< WM_BLE_SE_EXEC_WRITE_EVT */
+    tls_ble_se_confirm_msg_t     ser_confirm;      /**< WM_BLE_SE_CONFIRM_EVT */
+    tls_ble_se_congest_msg_t     ser_congest;      /**< WM_BLE_CL_CONGEST_EVT */
+    tls_ble_se_mtu_msg_t         ser_mtu;
+	tls_ble_se_response_msg_t    ser_resp;
+
+} tls_ble_msg_t;
+
+/** WM BLE Client callback function */
+typedef void (*tls_ble_callback_t)(tls_ble_evt_t event, tls_ble_msg_t *p_data);
+
+typedef void (*tls_ble_output_func_ptr)(uint8_t *p_data, uint32_t length);
+
+
+/** BLE dm events */
+typedef enum
+{
+    WM_BLE_DM_SET_ADV_DATA_CMPL_EVT = (0x01<<0),        /**< BLE DM set advertisement data completed*/
+    WM_BLE_DM_TIMER_EXPIRED_EVT     = (0x01<<1),        /**< BLE DM timer expired event. */
+    WM_BLE_DM_TRIGER_EVT            = (0x01<<2),        /**< BLE DM event trigered event, async processing*/
+    WM_BLE_DM_SCAN_RES_EVT          = (0x01<<3),        /**< BLE DM scan result evt*/
+	WM_BLE_DM_SET_SCAN_PARAM_CMPL_EVT=(0x01<<4),
+	WM_BLE_DM_REPORT_RSSI_EVT       = (0x01<<5),
+	WM_BLE_DM_SCAN_RES_CMPL_EVT     = (0x01<<6),
+	WM_BLE_DM_SEC_EVT               = (0x01<<7),
+	WM_BLE_DM_ADV_STARTED_EVT       = (0x01<<8),
+    WM_BLE_DM_ADV_STOPPED_EVT       = (0x01<<9),
+	
+} tls_ble_dm_evt_t;
+
+
+/** callback event data for WM_BLE_DM_SET_ADV_DATA */
+typedef struct
+{
+    uint8_t         status; /**< operation status */
+} tls_ble_dm_set_adv_data_cmpl_msg_t;
+
+typedef struct
+{
+	uint8_t status;
+	uint8_t dm_id; //dummy value; who care this value;
+} tls_ble_dm_set_scan_param_cmpl_msg_t;
+
+typedef struct
+{
+    uint32_t id;
+    int32_t func_ptr;
+} tls_ble_dm_timer_expired_msg_t;
+
+typedef tls_ble_dm_timer_expired_msg_t tls_ble_dm_evt_triger_msg_t;
+
+typedef struct
+{
+    uint8_t address[6];                    /**< device address */
+    int8_t rssi;                        /**< signal strength */
+    uint8_t *value; /**< adv /scan resp value */
+} tls_ble_dm_scan_res_msg_t;
+
+typedef struct
+{
+	uint8_t address[6];
+	int8_t rssi;
+	uint8_t status;
+} tls_ble_report_rssi_msg_t;
+typedef struct
+{
+	uint8_t address[6];
+	int8_t transport;
+	uint8_t status;    
+} tls_ble_sec_msg_t;
+
+typedef struct
+{
+    uint16_t num_responses;
+} tls_ble_dm_scan_res_cmpl_msg_t;
+
+typedef tls_ble_dm_set_adv_data_cmpl_msg_t tls_ble_dm_adv_cmpl_msg_t;
+typedef union
+{
+    tls_ble_dm_set_adv_data_cmpl_msg_t   dm_set_adv_data_cmpl;
+    tls_ble_dm_timer_expired_msg_t       dm_timer_expired;
+    tls_ble_dm_evt_triger_msg_t          dm_evt_trigered;
+    tls_ble_dm_scan_res_msg_t            dm_scan_result;
+	tls_ble_dm_set_scan_param_cmpl_msg_t dm_set_scan_param_cmpl;
+    tls_ble_dm_scan_res_cmpl_msg_t       dm_scan_result_cmpl;
+	tls_ble_report_rssi_msg_t            dm_report_rssi;
+    tls_ble_sec_msg_t                    dm_sec_result;
+    tls_ble_dm_adv_cmpl_msg_t            dm_adv_cmpl;
+    
+} tls_ble_dm_msg_t;
+
+typedef struct
+{
+    bool set_scan_rsp;
+    bool include_name;
+    bool include_txpower;
+	bool pure_data;
+    int min_interval;
+    int max_interval;
+    int appearance;
+    uint16_t manufacturer_len;
+    uint8_t manufacturer_data[31];
+    uint16_t service_data_len;
+    uint8_t service_data[31];
+    uint16_t service_uuid_len;
+    uint8_t service_uuid[31];
+} __attribute__((packed)) tls_ble_dm_adv_data_t;
+
+typedef struct
+{
+    uint16_t      adv_int_min;            /* minimum adv interval */
+    uint16_t      adv_int_max;            /* maximum adv interval */
+    tls_bt_addr_t   *dir_addr;
+} __attribute__((packed)) tls_ble_dm_adv_param_t;
+
+typedef struct
+{
+    uint16_t      adv_int_min;            /* minimum adv interval */
+    uint16_t      adv_int_max;            /* maximum adv interval */
+    uint8_t       adv_type;
+    uint8_t       own_addr_type;
+    uint8_t       chnl_map;
+    uint8_t         afp;
+    uint8_t         peer_addr_type;
+    tls_bt_addr_t   *dir_addr;
+} __attribute__((packed)) tls_ble_dm_adv_ext_param_t;
+
+
+/** WM BLE device manager callback function */
+typedef void (*tls_ble_dm_callback_t)(tls_ble_dm_evt_t event, tls_ble_dm_msg_t *p_data);
+
+/** WM BLE dm timer callback function */
+typedef void (*tls_ble_dm_timer_callback_t)(uint8_t timer_id);
+
+/** WM BLE device evt triger callback function */
+typedef void (*tls_ble_dm_triger_callback_t)(uint32_t evt_id);
+
+typedef void (*tls_ble_scan_res_notify_t)(tls_ble_dm_scan_res_msg_t *msg);
+
+/*********************************************************************************************************/
+/* Bluetooth AV connection states */
+typedef enum
+{
+    WM_BTAV_CONNECTION_STATE_DISCONNECTED = 0,
+    WM_BTAV_CONNECTION_STATE_CONNECTING,
+    WM_BTAV_CONNECTION_STATE_CONNECTED,
+    WM_BTAV_CONNECTION_STATE_DISCONNECTING
+} tls_btav_connection_state_t;
+
+/* Bluetooth AV datapath states */
+typedef enum
+{
+    WM_BTAV_AUDIO_STATE_REMOTE_SUSPEND = 0,
+    WM_BTAV_AUDIO_STATE_STOPPED,
+    WM_BTAV_AUDIO_STATE_STARTED,
+} tls_btav_audio_state_t;
+
+/** BR-EDR A2DP sink events */
+typedef enum
+{
+    WMBT_A2DP_CONNECTION_STATE_EVT,
+	WMBT_A2DP_AUDIO_STATE_EVT,
+	WMBT_A2DP_AUDIO_CONFIG_EVT,
+	WMBT_A2DP_AUDIO_PAYLOAD_EVT,
+} tls_bt_av_evt_t;
+
+typedef struct
+{
+	tls_btav_connection_state_t stat;
+	tls_bt_addr_t *bd_addr;
+} tls_bt_av_connection_state_t;
+
+typedef struct
+{
+	tls_btav_audio_state_t stat;
+	tls_bt_addr_t *bd_addr;	
+} tls_bt_av_audio_state_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+	uint32_t sample_rate;
+	uint8_t channel_count;
+} tls_bt_av_audio_config_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+	uint8_t audio_format;
+	uint8_t *payload;
+	uint16_t payload_length;
+} tls_bt_av_audio_payload_t;
+
+typedef union
+{
+	tls_bt_av_connection_state_t av_connection_state;
+	tls_bt_av_audio_state_t av_audio_state;
+	tls_bt_av_audio_config_t av_audio_config;
+	tls_bt_av_audio_payload_t av_audio_payload;
+	
+} tls_bt_av_msg_t;
+
+/** WM BT A2DP SINK callback function */
+typedef void (*tls_bt_a2dp_sink_callback_t)(tls_bt_av_evt_t event, tls_bt_av_msg_t *p_data);
+
+/**WM BT A2DP SRC callback function */
+///////////////TODO////////////////
+typedef void (*tls_bt_a2dp_src_callback_t)(tls_bt_av_evt_t event, tls_bt_av_msg_t *p_data);
+
+
+/** BR-EDR WMBT-RC Controller callback events */
+
+#define WM_BTRC_MAX_ATTR_STR_LEN       255
+#define WM_BTRC_UID_SIZE               8
+#define WM_BTRC_MAX_APP_SETTINGS       8
+#define WM_BTRC_MAX_FOLDER_DEPTH       4
+#define WM_BTRC_MAX_APP_ATTR_SIZE      16
+#define WM_BTRC_MAX_ELEM_ATTR_SIZE     7
+
+typedef uint8_t tls_btrc_uid_t[WM_BTRC_UID_SIZE];
+typedef enum
+{
+    WM_BTRC_PLAYSTATE_STOPPED = 0x00,    /* Stopped */
+    WM_BTRC_PLAYSTATE_PLAYING = 0x01,    /* Playing */
+    WM_BTRC_PLAYSTATE_PAUSED = 0x02,    /* Paused  */
+    WM_BTRC_PLAYSTATE_FWD_SEEK = 0x03,    /* Fwd Seek*/
+    WM_BTRC_PLAYSTATE_REV_SEEK = 0x04,    /* Rev Seek*/
+    WM_BTRC_PLAYSTATE_ERROR = 0xFF,    /* Error   */
+} tls_btrc_play_status_t;
+
+typedef enum
+{
+    WM_BTRC_FEAT_NONE = 0x00,    /* AVRCP 1.0 */
+    WM_BTRC_FEAT_METADATA = 0x01,    /* AVRCP 1.3 */
+    WM_BTRC_FEAT_ABSOLUTE_VOLUME = 0x02,    /* Supports TG role and volume sync */
+    WM_BTRC_FEAT_BROWSE = 0x04,    /* AVRCP 1.4 and up, with Browsing support */
+} tls_btrc_remote_features_t;
+typedef enum
+{
+    WM_BTRC_NOTIFICATION_TYPE_INTERIM = 0,
+    WM_BTRC_NOTIFICATION_TYPE_CHANGED = 1,
+} tls_btrc_notification_type_t;
+
+typedef enum
+{
+    WM_BTRC_PLAYER_ATTR_EQUALIZER = 0x01,
+    WM_BTRC_PLAYER_ATTR_REPEAT = 0x02,
+    WM_BTRC_PLAYER_ATTR_SHUFFLE = 0x03,
+    WM_BTRC_PLAYER_ATTR_SCAN = 0x04,
+} tls_btrc_player_attr_t;
+
+typedef enum
+{
+    WM_BTRC_MEDIA_ATTR_TITLE = 0x01,
+    WM_BTRC_MEDIA_ATTR_ARTIST = 0x02,
+    WM_BTRC_MEDIA_ATTR_ALBUM = 0x03,
+    WM_BTRC_MEDIA_ATTR_TRACK_NUM = 0x04,
+    WM_BTRC_MEDIA_ATTR_NUM_TRACKS = 0x05,
+    WM_BTRC_MEDIA_ATTR_GENRE = 0x06,
+    WM_BTRC_MEDIA_ATTR_PLAYING_TIME = 0x07,
+} tls_btrc_media_attr_t;
+
+typedef enum
+{
+    WM_BTRC_PLAYER_VAL_OFF_REPEAT = 0x01,
+    WM_BTRC_PLAYER_VAL_SINGLE_REPEAT = 0x02,
+    WM_BTRC_PLAYER_VAL_ALL_REPEAT = 0x03,
+    WM_BTRC_PLAYER_VAL_GROUP_REPEAT = 0x04
+} tls_btrc_player_repeat_val_t;
+
+typedef enum
+{
+    WM_BTRC_EVT_PLAY_STATUS_CHANGED = 0x01,
+    WM_BTRC_EVT_TRACK_CHANGE = 0x02,
+    WM_BTRC_EVT_TRACK_REACHED_END = 0x03,
+    WM_BTRC_EVT_TRACK_REACHED_START = 0x04,
+    WM_BTRC_EVT_PLAY_POS_CHANGED = 0x05,
+    WM_BTRC_EVT_APP_SETTINGS_CHANGED = 0x08,
+} tls_btrc_event_id_t;
+
+typedef struct
+{
+    uint8_t num_attr;
+    uint8_t attr_ids[WM_BTRC_MAX_APP_SETTINGS];
+    uint8_t attr_values[WM_BTRC_MAX_APP_SETTINGS];
+} tls_btrc_player_settings_t;
+
+typedef struct
+{
+    uint32_t attr_id;
+    uint8_t text[WM_BTRC_MAX_ATTR_STR_LEN];
+} tls_btrc_element_attr_val_t;
+
+typedef struct
+{
+    uint8_t attr_id;
+    uint8_t num_val;
+    uint8_t attr_val[WM_BTRC_MAX_APP_ATTR_SIZE];
+} tls_btrc_player_app_attr_t;
+typedef struct
+{
+    uint8_t   val;
+    uint16_t  charset_id;
+    uint16_t  str_len;
+    uint8_t   *p_str;
+} tls_btrc_player_app_ext_attr_val_t;
+
+typedef struct
+{
+    uint8_t   attr_id;
+    uint16_t  charset_id;
+    uint16_t  str_len;
+    uint8_t   *p_str;
+    uint8_t   num_val;
+    tls_btrc_player_app_ext_attr_val_t ext_attr_val[WM_BTRC_MAX_APP_ATTR_SIZE];
+} tls_btrc_player_app_ext_attr_t;
+
+typedef union
+{
+    tls_btrc_play_status_t play_status;
+    tls_btrc_uid_t track; /* queue position in NowPlaying */
+    uint32_t song_pos;
+    tls_btrc_player_settings_t player_setting;
+} tls_btrc_register_notification_t;
+
+
+typedef enum
+{
+	WM_BTRC_PASSTHROUGH_RSP_EVT,
+	WM_BTRC_GROUPNAVIGATION_RSP_EVT,
+	WM_BTRC_CONNECTION_STATE_EVT,
+	WM_BTRC_CTRL_GETRCFEATURES_EVT,
+	WM_BTRC_CTRL_SETPLAYERAPPLICATIONSETTING_RSP_EVT,
+	WM_BTRC_CTRL_PLAYERAPPLICATIONSETTING_EVT,
+	WM_BTRC_CTRL_PLAYERAPPLICATIONSETTING_CHANGED_EVT,
+	WM_BTRC_CTRL_SETABSVOL_CMD_EVT,
+	WM_BTRC_CTRL_REGISTERNOTIFICATION_ABS_VOL_EVT,
+	WM_BTRC_CTRL_TRACK_CHANGED_EVT,
+	WM_BTRC_CTRL_PLAY_POSITION_CHANGED_EVT,
+	WM_BTRC_CTRL_PLAY_STATUS_CHANGED_EVT,
+} tls_btrc_ctrl_evt_t;
+
+typedef struct
+{
+	int id;
+	int key_state;
+} tls_btrc_passthrough_rsp_msg_t;
+
+typedef struct
+{
+	int id;
+	int key_state;
+} tls_btrc_groupnavigation_rsp_msg_t;
+
+typedef struct
+{
+	uint8_t state;
+	tls_bt_addr_t *bd_addr;
+} tls_btrc_connection_state_msg_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+	int features;
+} tls_btrc_ctrl_getrcfeatures_msg_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+	uint8_t abs_vol;
+	uint8_t label;
+} tls_btrc_ctrl_setabsvol_msg_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+	uint8_t label;
+} tls_btrc_ctrl_registernotification_abs_vol_msg_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+	uint8_t accepted;
+} tls_btrc_ctrl_setplayerapplicationsetting_rsp_msg_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+	uint8_t num_attr;
+	tls_btrc_player_app_attr_t *app_attrs;
+	uint8_t num_ext_attr;
+	tls_btrc_player_app_ext_attr_t *ext_attrs;
+} tls_btrc_ctrl_playerapplicationsetting_msg_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+    tls_btrc_player_settings_t *p_vals;	
+} tls_btrc_ctrl_playerapplicationsetting_changed_msg_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+	uint8_t num_attr;
+	tls_btrc_element_attr_val_t *p_attrs;
+
+} tls_btrc_ctrl_track_changed_msg_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+	uint32_t song_len;
+	uint32_t song_pos;
+} tls_btrc_ctrl_play_position_changed_msg_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+	tls_btrc_play_status_t play_status;
+} tls_btrc_ctrl_play_status_changed_msg_t;
+
+typedef union
+{
+	tls_btrc_passthrough_rsp_msg_t				passthrough_rsp;
+	tls_btrc_groupnavigation_rsp_msg_t			groupnavigation_rsp;
+	tls_btrc_connection_state_msg_t			connection_state;
+	tls_btrc_ctrl_getrcfeatures_msg_t			getrcfeatures;
+	tls_btrc_ctrl_setabsvol_msg_t				setabsvol;
+	tls_btrc_ctrl_registernotification_abs_vol_msg_t 		registernotification_abs_vol;
+	tls_btrc_ctrl_setplayerapplicationsetting_rsp_msg_t	setplayerapplicationsetting_rsp;
+	tls_btrc_ctrl_playerapplicationsetting_msg_t			playerapplicationsetting;
+	tls_btrc_ctrl_playerapplicationsetting_changed_msg_t 	playerapplicationsetting_changed;
+	tls_btrc_ctrl_track_changed_msg_t 						track_changed;
+	tls_btrc_ctrl_play_position_changed_msg_t	play_position_changed;
+	tls_btrc_ctrl_play_status_changed_msg_t	play_status_changed;
+	
+} tls_btrc_ctrl_msg_t;
+
+/** WM BT RC CTRL callback function */
+typedef void (*tls_btrc_ctrl_callback_t)(tls_btrc_ctrl_evt_t event, tls_btrc_ctrl_msg_t *p_data);
+
+
+typedef enum
+{
+	WM_BTRC_REMOTE_FEATURE_EVT,
+	WM_BTRC_GET_PLAY_STATUS_EVT,
+	WM_BTRC_LIST_PLAYER_APP_ATTR_EVT,
+	WM_BTRC_LIST_PLAYER_APP_VALUES_EVT,
+	WM_BTRC_GET_PLAYER_APP_VALUE_EVT,
+	WM_BTRC_GET_PLAYER_APP_ATTRS_TEXT_EVT,
+	WM_BTRC_GET_PLAYER_APP_VALUES_TEXT_EVT,
+	WM_BTRC_SET_PLAYER_APP_VALUE_EVT,
+	WM_BTRC_GET_ELEMENT_ATTR_EVT,
+	WM_BTRC_REGISTER_NOTIFICATION_EVT,
+	WM_BTRC_VOLUME_CHANGED_EVT,
+	WM_BTRC_PASSTHROUGH_CMD_EVT,
+} tls_btrc_evt_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+    tls_btrc_remote_features_t features;	
+} tls_btrc_remote_features_msg_t;
+
+typedef struct
+{
+	void *reserved;
+} tls_btrc_get_play_status_msg_t;
+
+typedef struct
+{
+	void *reserved;
+} tls_btrc_list_player_app_attr_msg_t;
+
+typedef struct
+{
+	tls_btrc_player_attr_t attr_id;
+} tls_btrc_list_player_app_values_msg_t;
+
+typedef struct
+{
+	uint8_t num_attr;
+	tls_btrc_player_attr_t *p_attrs;
+
+} tls_btrc_get_player_app_value_msg_t;
+
+typedef struct
+{
+	uint8_t attr_id;
+	uint8_t num_val;
+	uint8_t *p_vals;
+} tls_btrc_get_player_app_attrs_text_msg_t;
+
+typedef struct
+{
+	uint8_t num_attr;
+	tls_btrc_player_attr_t *p_attrs;
+
+} tls_btrc_get_player_app_values_text_msg_t;
+
+typedef struct
+{
+	tls_btrc_player_settings_t *p_vals;
+		
+} tls_btrc_set_player_app_value_msg_t;
+
+typedef struct
+{
+	uint8_t num_attr;
+	tls_btrc_media_attr_t *p_attrs;
+		
+} tls_btrc_get_element_attr_msg_t;
+
+typedef struct
+{
+	tls_btrc_event_id_t event_id; 
+	uint32_t param;
+	
+} tls_btrc_register_notification_msg_t;
+
+typedef struct
+{
+	uint8_t volume; 
+	uint8_t ctype;
+} tls_btrc_volume_change_msg_t;
+
+typedef struct
+{
+	int id;
+	int key_state;
+
+} tls_btrc_passthrough_cmd_msg_t;
+
+typedef union
+{
+	tls_btrc_remote_features_msg_t		remote_features;
+	tls_btrc_get_play_status_msg_t  	get_play_status;
+	tls_btrc_list_player_app_attr_msg_t		list_player_app_attr;
+	tls_btrc_list_player_app_values_msg_t 	list_player_app_values;
+	tls_btrc_get_player_app_value_msg_t   	get_player_app_value;
+	tls_btrc_get_player_app_attrs_text_msg_t 	get_player_app_attrs_text;
+	tls_btrc_get_player_app_values_text_msg_t 	get_player_app_values_text;
+	tls_btrc_set_player_app_value_msg_t 	set_player_app_value;
+	tls_btrc_get_element_attr_msg_t 		get_element_attr;
+	tls_btrc_register_notification_msg_t 	register_notification;
+	tls_btrc_volume_change_msg_t 		volume_change;
+	tls_btrc_passthrough_cmd_msg_t 		passthrough_cmd;
+	
+} tls_btrc_msg_t;
+
+/** WM BT RC callback function */
+typedef void (*tls_btrc_callback_t)(tls_btrc_evt_t event, tls_btrc_msg_t *p_data);

+
+
+/*************************************************************************************************************/
+
+typedef enum
+{
+    WM_BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED = 0,
+    WM_BTHF_CLIENT_CONNECTION_STATE_CONNECTING,
+    WM_BTHF_CLIENT_CONNECTION_STATE_CONNECTED,
+    WM_BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED,
+    WM_BTHF_CLIENT_CONNECTION_STATE_DISCONNECTING
+} tls_bthf_client_connection_state_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_AUDIO_STATE_DISCONNECTED = 0,
+    WM_BTHF_CLIENT_AUDIO_STATE_CONNECTING,
+    WM_BTHF_CLIENT_AUDIO_STATE_CONNECTED,
+    WM_BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC,
+} tls_bthf_client_audio_state_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_VR_STATE_STOPPED = 0,
+    WM_BTHF_CLIENT_VR_STATE_STARTED
+} tls_bthf_client_vr_state_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_VOLUME_TYPE_SPK = 0,
+    WM_BTHF_CLIENT_VOLUME_TYPE_MIC
+} tls_bthf_client_volume_type_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_NETWORK_STATE_NOT_AVAILABLE = 0,
+    WM_BTHF_CLIENT_NETWORK_STATE_AVAILABLE
+} tls_bthf_client_network_state_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_SERVICE_TYPE_HOME = 0,
+    WM_BTHF_CLIENT_SERVICE_TYPE_ROAMING
+} tls_bthf_client_service_type_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_CALL_STATE_ACTIVE = 0,
+    WM_BTHF_CLIENT_CALL_STATE_HELD,
+    WM_BTHF_CLIENT_CALL_STATE_DIALING,
+    WM_BTHF_CLIENT_CALL_STATE_ALERTING,
+    WM_BTHF_CLIENT_CALL_STATE_INCOMING,
+    WM_BTHF_CLIENT_CALL_STATE_WAITING,
+    WM_BTHF_CLIENT_CALL_STATE_HELD_BY_RESP_HOLD,
+} tls_bthf_client_call_state_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_CALL_NO_CALLS_IN_PROGRESS = 0,
+    WM_BTHF_CLIENT_CALL_CALLS_IN_PROGRESS
+} tls_bthf_client_call_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_CALLSETUP_NONE = 0,
+    WM_BTHF_CLIENT_CALLSETUP_INCOMING,
+    WM_BTHF_CLIENT_CALLSETUP_OUTGOING,
+    WM_BTHF_CLIENT_CALLSETUP_ALERTING
+
+} tls_bthf_client_callsetup_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_CALLHELD_NONE = 0,
+    WM_BTHF_CLIENT_CALLHELD_HOLD_AND_ACTIVE,
+    WM_BTHF_CLIENT_CALLHELD_HOLD,
+} tls_bthf_client_callheld_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_RESP_AND_HOLD_HELD = 0,
+    WM_BTRH_CLIENT_RESP_AND_HOLD_ACCEPT,
+    WM_BTRH_CLIENT_RESP_AND_HOLD_REJECT,
+} tls_bthf_client_resp_and_hold_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_CALL_DIRECTION_OUTGOING = 0,
+    WM_BTHF_CLIENT_CALL_DIRECTION_INCOMING
+} tls_bthf_client_call_direction_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE = 0,
+    WM_BTHF_CLIENT_CALL_MPTY_TYPE_MULTI
+} tls_bthf_client_call_mpty_type_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_CMD_COMPLETE_OK = 0,
+    WM_BTHF_CLIENT_CMD_COMPLETE_ERROR,
+    WM_BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_CARRIER,
+    WM_BTHF_CLIENT_CMD_COMPLETE_ERROR_BUSY,
+    WM_BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_ANSWER,
+    WM_BTHF_CLIENT_CMD_COMPLETE_ERROR_DELAYED,
+    WM_BTHF_CLIENT_CMD_COMPLETE_ERROR_BLACKLISTED,
+    WM_BTHF_CLIENT_CMD_COMPLETE_ERROR_CME
+} tls_bthf_client_cmd_complete_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_CALL_ACTION_CHLD_0 = 0,
+    WM_BTHF_CLIENT_CALL_ACTION_CHLD_1,
+    WM_BTHF_CLIENT_CALL_ACTION_CHLD_2,
+    WM_BTHF_CLIENT_CALL_ACTION_CHLD_3,
+    WM_BTHF_CLIENT_CALL_ACTION_CHLD_4,
+    WM_BTHF_CLIENT_CALL_ACTION_CHLD_1x,
+    WM_BTHF_CLIENT_CALL_ACTION_CHLD_2x,
+    WM_BTHF_CLIENT_CALL_ACTION_ATA,
+    WM_BTHF_CLIENT_CALL_ACTION_CHUP,
+    WM_BTHF_CLIENT_CALL_ACTION_BTRH_0,
+    WM_BTHF_CLIENT_CALL_ACTION_BTRH_1,
+    WM_BTHF_CLIENT_CALL_ACTION_BTRH_2,
+} tls_bthf_client_call_action_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_SERVICE_UNKNOWN = 0,
+    WM_BTHF_CLIENT_SERVICE_VOICE,
+    WM_BTHF_CLIENT_SERVICE_FAX
+} tls_bthf_client_subscriber_service_type_t;
+
+typedef enum
+{
+    WM_BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED = 0,
+    WM_BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED,
+} tls_bthf_client_in_band_ring_state_t;
+
+/* Peer features masks */
+#define WM_BTHF_CLIENT_PEER_FEAT_3WAY   0x00000001  /* Three-way calling */
+#define WM_BTHF_CLIENT_PEER_FEAT_ECNR   0x00000002  /* Echo cancellation and/or noise reduction */
+#define WM_BTHF_CLIENT_PEER_FEAT_VREC   0x00000004  /* Voice recognition */
+#define WM_BTHF_CLIENT_PEER_FEAT_INBAND 0x00000008  /* In-band ring tone */
+#define WM_BTHF_CLIENT_PEER_FEAT_VTAG   0x00000010  /* Attach a phone number to a voice tag */
+#define WM_BTHF_CLIENT_PEER_FEAT_REJECT 0x00000020  /* Ability to reject incoming call */
+#define WM_BTHF_CLIENT_PEER_FEAT_ECS    0x00000040  /* Enhanced Call Status */
+#define WM_BTHF_CLIENT_PEER_FEAT_ECC    0x00000080  /* Enhanced Call Control */
+#define WM_BTHF_CLIENT_PEER_FEAT_EXTERR 0x00000100  /* Extended error codes */
+#define WM_BTHF_CLIENT_PEER_FEAT_CODEC  0x00000200  /* Codec Negotiation */
+
+/* Peer call handling features masks */
+#define WM_BTHF_CLIENT_CHLD_FEAT_REL           0x00000001  /* 0  Release waiting call or held calls */
+#define WM_BTHF_CLIENT_CHLD_FEAT_REL_ACC       0x00000002  /* 1  Release active calls and accept other
+                                                              (waiting or held) cal */
+#define WM_BTHF_CLIENT_CHLD_FEAT_REL_X         0x00000004  /* 1x Release specified active call only */
+#define WM_BTHF_CLIENT_CHLD_FEAT_HOLD_ACC      0x00000008  /* 2  Active calls on hold and accept other
+                                                              (waiting or held) call */
+#define WM_BTHF_CLIENT_CHLD_FEAT_PRIV_X        0x00000010  /* 2x Request private mode with specified
+                                                              call (put the rest on hold) */
+#define WM_BTHF_CLIENT_CHLD_FEAT_MERGE         0x00000020  /* 3  Add held call to multiparty */
+#define WM_BTHF_CLIENT_CHLD_FEAT_MERGE_DETACH  0x00000040  /* 4  Connect two calls and leave
+                                                              (disconnect from) multiparty */
+
+
+typedef enum
+{
+	WM_BTHF_CLIENT_CONNECTION_STATE_EVT,
+	WM_BTHF_CLIENT_AUDIO_STATE_EVT,
+	WM_BTHF_CLIENT_VR_CMD_EVT,
+	WM_BTHF_CLIENT_NETWORK_STATE_EVT,
+	WM_BTHF_CLIENT_NETWORK_ROAMING_EVT,
+	WM_BTHF_CLIENT_NETWORK_SIGNAL_EVT,
+	WM_BTHF_CLIENT_BATTERY_LEVEL_EVT,
+	WM_BTHF_CLIENT_CURRENT_OPERATOR_EVT,
+	WM_BTHF_CLIENT_CALL_EVT,
+	WM_BTHF_CLIENT_CALLSETUP_EVT,
+	WM_BTHF_CLIENT_CALLHELD_EVT,
+	WM_BTHF_CLIENT_RESP_AND_HOLD_EVT,
+	WM_BTHF_CLIENT_CLIP_EVT,
+	WM_BTHF_CLIENT_CALL_WAITING_EVT,
+	WM_BTHF_CLIENT_CURRENT_CALLS_EVT,
+	WM_BTHF_CLIENT_VOLUME_CHANGE_EVT,
+	WM_BTHF_CLIENT_CMD_COMPLETE_EVT,
+	WM_BTHF_CLIENT_SUBSCRIBER_INFO_EVT,
+	WM_BTHF_CLIENT_IN_BAND_RING_TONE_EVT,
+	WM_BTHF_CLIENT_LAST_VOICE_TAG_NUMBER_EVT,
+	WM_BTHF_CLIENT_RING_INDICATION_EVT,
+	WM_BTHF_CLIENT_AUDIO_PAYLOAD_EVT,
+} tls_bthf_client_evt_t;
+
+typedef struct
+{
+	tls_bthf_client_connection_state_t state;
+	unsigned int peer_feat;
+	unsigned int chld_feat;
+	tls_bt_addr_t *bd_addr;
+} tls_bthf_client_connection_state_msg_t;
+
+typedef struct
+{
+	tls_bthf_client_audio_state_t state;
+	tls_bt_addr_t *bd_addr;	
+} tls_bthf_client_audio_state_msg_t;
+
+typedef struct
+{
+	tls_bthf_client_vr_state_t state;
+
+} tls_bthf_client_vr_cmd_msg_t;
+
+typedef struct
+{
+	tls_bthf_client_network_state_t state;
+
+} tls_bthf_client_network_state_msg_t;
+
+typedef struct
+{
+	tls_bthf_client_service_type_t type;
+
+} tls_bthf_client_network_roaming_msg_t;
+
+typedef struct
+{
+	int signal_strength;
+
+} tls_bthf_client_network_signal_msg_t;
+
+typedef struct
+{
+	int battery_level;
+
+} tls_bthf_client_battery_level_msg_t;
+
+typedef struct
+{
+	char* name;
+
+} tls_bthf_client_current_operator_msg_t;
+
+typedef struct
+{
+	tls_bthf_client_call_t call;
+
+} tls_bthf_client_call_msg_t;
+
+typedef struct
+{
+	tls_bthf_client_callsetup_t callsetup;
+
+} tls_bthf_client_callsetup_msg_t;
+
+typedef struct
+{
+	tls_bthf_client_callheld_t callheld;
+
+} tls_bthf_client_callheld_msg_t;
+
+typedef struct
+{
+	tls_bthf_client_resp_and_hold_t resp_and_hold;
+
+} tls_bthf_client_resp_and_hold_msg_t;
+
+typedef struct
+{
+	char *number;
+
+} tls_bthf_client_clip_msg_t;
+
+typedef struct
+{
+	char *number;
+
+} tls_bthf_client_call_waiting_msg_t;
+
+typedef struct
+{
+	int index;
+	tls_bthf_client_call_direction_t dir;
+	tls_bthf_client_call_state_t state;
+	tls_bthf_client_call_mpty_type_t mpty;
+	char *number;
+} tls_bthf_client_current_calls_msg_t;
+
+typedef struct
+{
+	tls_bthf_client_volume_type_t type;
+	int volume;
+
+} tls_bthf_client_volume_change_msg_t;
+
+typedef struct
+{
+	tls_bthf_client_cmd_complete_t type;
+	int cme;
+
+} tls_bthf_client_cmd_complete_msg_t;
+
+typedef struct
+{
+	const char *name;
+	tls_bthf_client_subscriber_service_type_t type;
+
+} tls_bthf_client_subscriber_info_msg_t;
+
+typedef struct
+{
+	tls_bthf_client_in_band_ring_state_t state;
+
+} tls_bthf_client_in_band_ring_tone_msg_t;
+
+typedef struct
+{
+	char *number;
+
+} tls_bthf_client_last_voice_tag_number_msg_t;
+
+typedef struct
+{
+	int ring;
+
+} tls_bthf_client_ring_indication_msg_t;
+
+typedef struct
+{
+	tls_bt_addr_t *bd_addr;
+	uint8_t audio_format;
+	uint8_t *payload;
+	uint16_t payload_length;
+} tls_bthf_audio_payload_msg_t;
+
+
+typedef union
+{
+	tls_bthf_client_connection_state_msg_t	connection_state_msg;
+	tls_bthf_client_audio_state_msg_t		audio_state_msg;
+	tls_bthf_client_vr_cmd_msg_t			vr_cmd_msg;
+	tls_bthf_client_network_state_msg_t	 	network_state_msg;
+	tls_bthf_client_network_roaming_msg_t	network_roaming_msg;
+	tls_bthf_client_network_signal_msg_t    network_signal_msg;
+	tls_bthf_client_battery_level_msg_t	    battery_level_msg;
+	tls_bthf_client_current_operator_msg_t	current_operator_msg;
+	tls_bthf_client_call_msg_t 				call_msg;
+	tls_bthf_client_callsetup_msg_t 		callsetup_msg;
+	tls_bthf_client_callheld_msg_t 			callheld_msg;
+	tls_bthf_client_resp_and_hold_msg_t 	resp_and_hold_msg;
+	tls_bthf_client_clip_msg_t 				clip_msg;
+	tls_bthf_client_call_waiting_msg_t 		call_waiting_msg;
+	tls_bthf_client_current_calls_msg_t 	current_calls_msg;
+	tls_bthf_client_volume_change_msg_t 	volume_change_msg;
+	tls_bthf_client_cmd_complete_msg_t 		cmd_complete_msg;
+	tls_bthf_client_subscriber_info_msg_t 	subscriber_info_msg;
+	tls_bthf_client_in_band_ring_tone_msg_t in_band_ring_tone_msg;
+	tls_bthf_client_last_voice_tag_number_msg_t last_voice_tag_number_msg;
+	tls_bthf_client_ring_indication_msg_t 	ring_indication_msg;
+	tls_bthf_audio_payload_msg_t            audio_payload_msg;
+
+} tls_bthf_client_msg_t;
+
+/** WM BT HFP CLIENT callback function */
+typedef void (*tls_bthf_client_callback_t)(tls_bthf_client_evt_t event, tls_bthf_client_msg_t *p_data);

+
+
+/******************************************************************************************/
+/* Security Setting Mask */
+#define WM_SPP_SEC_NONE            0x0000    /* No security*/
+#define WM_SPP_SEC_AUTHORIZE       0x0001    /*Authorization required (only needed for out going connection ) */
+#define WM_SPP_SEC_AUTHENTICATE    0x0012    /*Authentication required*/
+#define WM_SPP_SEC_ENCRYPT         0x0024    /*Encryption required*/
+#define WM_SPP_SEC_MODE4_LEVEL4    0x0040    /*Mode 4 level 4 service, i.e. incoming/outgoing MITM and P-256 encryption*/
+#define WM_SPP_SEC_MITM            0x3000    /*Man-In-The_Middle protection*/
+#define WM_SPP_SEC_IN_16_DIGITS    0x4000    /*Min 16 digit for pin code*/
+typedef uint16_t wm_spp_sec_t;
+
+#define WM_SPP_MAX_SCN             31
+
+typedef enum {
+    WM_SPP_ROLE_CLIENT     = 0,          
+    WM_SPP_ROLE_SERVER      = 1,
+} tls_spp_role_t;
+
+typedef enum {
+    WM_SPP_INIT_EVT                    = 0,               
+    WM_SPP_DISCOVERY_COMP_EVT          = 8,               
+    WM_SPP_OPEN_EVT                    = 26,              
+    WM_SPP_CLOSE_EVT                   = 27,              
+    WM_SPP_START_EVT                   = 28,               
+    WM_SPP_CL_INIT_EVT                 = 29,              
+    WM_SPP_DATA_IND_EVT                = 30,              
+    WM_SPP_CONG_EVT                    = 31,               
+    WM_SPP_WRITE_EVT                   = 33,              
+    WM_SPP_SRV_OPEN_EVT                = 34,              
+} tls_spp_event_t;
+
+typedef struct {
+    uint8_t    status;         
+} tls_spp_init_msg_t ;
+
+typedef struct {
+    uint8_t    status;        
+    uint8_t    scn_num;       
+    uint8_t    scn[WM_SPP_MAX_SCN];   
+} tls_spp_disc_comp_msg_t;
+
+typedef struct {
+        uint8_t      status;        
+        uint32_t     handle;                   
+        uint8_t     addr[6];        
+} tls_spp_open_msg_t;
+
+typedef struct {
+        uint8_t    status;        
+        uint32_t   handle;        
+        uint32_t   new_listen_handle;         
+        uint8_t     addr[6];       
+} tls_spp_srv_open_msg_t;
+
+typedef struct {
+        uint8_t    status;         
+        uint32_t   port_status;    
+        uint32_t   handle;        
+        bool       local;         
+} tls_spp_close_msg_t; 
+
+typedef struct {
+        uint8_t    status;        
+        uint32_t   handle;         
+        uint8_t    sec_id;         
+        bool       use_co_rfc;        
+} tls_spp_start_msg_t; 
+
+typedef struct {
+        uint8_t    status;         
+        uint32_t   handle;         
+        uint8_t    sec_id;        
+        bool       use_co_rfc;         
+} tls_spp_cli_init_msg_t;
+
+typedef struct {
+        uint8_t    status;         
+        uint32_t   handle;         
+        int        length;            
+        bool       congest;          
+} tls_spp_write_msg_t;
+
+typedef struct {
+        uint8_t    status;        
+        uint32_t   handle;        
+        uint16_t   length;           
+        uint8_t    *data;         
+} tls_spp_data_ind_msg_t; 
+
+typedef struct {
+        uint8_t    status;        
+        uint32_t   handle;        
+        bool       congest;           
+} tls_spp_cong_msg_t; 
+
+typedef union
+{
+	tls_spp_init_msg_t	            init_msg;
+	tls_spp_disc_comp_msg_t		    disc_comp_msg;
+	tls_spp_open_msg_t			    open_msg;
+	tls_spp_srv_open_msg_t	 	    srv_open_msg;
+	tls_spp_close_msg_t	            close_msg;
+	tls_spp_start_msg_t             start_msg;
+	tls_spp_cli_init_msg_t	        cli_init_msg;
+	tls_spp_write_msg_t	            write_msg;
+	tls_spp_data_ind_msg_t 			data_ind_msg;
+	tls_spp_cong_msg_t 		        congest_msg;
+
+} tls_spp_msg_t;
+
+/** WM BT SPP callback function */
+typedef void (*tls_bt_spp_callback_t)(tls_spp_event_t event, tls_spp_msg_t *p_data);

+typedef enum
+{
+    BLE_UART_SERVER_MODE,
+    BLE_UART_CLIENT_MODE,
+    BLE_UART_UNKNOWN_MODE,
+} tls_ble_uart_mode_t;
+
+typedef void (*tls_ble_output_func_ptr)(uint8_t *p_data, uint32_t length);
+#define TLS_HAL_CBACK(P_CB, P_CBACK, ...)\
+    if (P_CB && P_CB->P_CBACK) {            \
+        P_CB->P_CBACK(__VA_ARGS__);         \
+    }                                       \
+    else {                                  \
+        assert(0);  \
+    }
+
+#endif /* WM_BT_DEF_H */
+

+ 261 - 0
include/bt/wm_bt_hf_client.h

@@ -0,0 +1,261 @@
+/**
+ * @file    wm_bt_hf_client.h
+ *
+ * @brief   Bluetooth API
+ *
+ * @author  WinnerMicro
+ *
+ * Copyright (c) 2020 Winner Microelectronics Co., Ltd.
+ */
+
+
+#ifndef __WM_BT_HF_CLIENT_H__
+#define __WM_BT_HF_CLIENT_H__
+
+#include "wm_bt.h"
+/**
+ * @defgroup BT_APIs Bluetooth APIs
+ * @brief Bluetooth related APIs
+ */
+
+/**
+ * @addtogroup BT_APIs
+ * @{
+ */
+
+/**
+ * @defgroup BT_HF_CLIENT_APIs
+ * @brief BT_HF_CLIENT APIs
+ */
+
+/**
+ * @addtogroup BT_HF_CLIENT_APIs
+ * @{
+ */
+
+
+
+/**
+ * @brief		   initializes the hf client interface
+ *
+ * @param[in]	  callback		pointer on callback function
+ *
+ * @retval		   @ref tls_bt_status_t
+ *
+ * @note		   None
+ */
+tls_bt_status_t tls_bt_hf_client_init(tls_bthf_client_callback_t callback);
+
+/**
+ * @brief          Closes the HF client interface
+ *
+ * @param       None
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_hf_client_deinit(void);
+
+/**
+ * @brief          connect to audio gateway
+ *
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_hf_client_connect(tls_bt_addr_t *bd_addr);
+
+
+/**
+ * @brief          disconnect from audio gateway
+ *
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_bt_hf_client_disconnect(tls_bt_addr_t *bd_addr);
+
+/**
+ * @brief           create an audio connection
+ *
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_hf_client_connect_audio(tls_bt_addr_t *bd_addr);
+
+/**
+ * @brief           close the audio connection
+ *
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_hf_client_disconnect_audio(tls_bt_addr_t *bd_addr);
+
+/**
+ * @brief           start voice recognition
+ *
+ * @param[in]    None
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_hf_client_start_voice_recognition(void);
+
+/**
+ * @brief           stop voice recognition
+ *
+ * @param[in]    None
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_hf_client_stop_voice_recognition(void);
+
+/**
+ * @brief           volume control
+ *
+ * @param[in]    type Mic or speaker

+ * @param[in]    volume index value
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_hf_client_volume_control(tls_bthf_client_volume_type_t type, int volume);
+
+/**
+ * @brief           place a call
+ *
+ * @param[in]    number  phone number to be called
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_hf_client_dial(const char *number);
+
+/**
+ * @brief          place a call with number specified by location (speed dial)
+ *
+ * @param[in]    location
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_hf_client_dial_memory(int location);
+
+/**
+ * @brief           handle specified call related action
+ *
+ * @param[in]    action  call action
+ * @param[in]    idx      index indicator
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_hf_client_handle_call_action(tls_bthf_client_call_action_t action, int idx);
+
+/**
+ * @brief           query list of current calls
+ *
+ * @param[in]    None
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_bt_hf_client_query_current_calls(void);
+
+/**
+ * @brief           query current selected operator name
+ *
+ * @param[in]    None
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_hf_client_query_current_operator_name(void);
+
+/**
+ * @brief            retrieve subscriber number information
+ *
+ * @param[in]    None
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_bt_hf_client_retrieve_subscriber_info(void);
+
+/**
+ * @brief            send dtmf
+ *
+ * @param[in]    code   number code
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_bt_hf_client_send_dtmf(char code);
+
+/**
+ * @brief            Request number from AG for VR purposes
+ *
+ * @param[in]    None
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_bt_hf_client_request_last_voice_tag_number(void);
+
+/**
+ * @brief             Send requested AT command to remote device
+ *
+ * @param[in]    cmd
+ * @param[in]    val1
+ * @param[in]    val2
+ * @param[in]    arg
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_bt_hf_client_send_at_cmd(int cmd, int val1, int val2, const char *arg);
+
+/**
+ * @brief             Send audio to audio gateway
+ *
+ * @param[in]    bd_addr    bluetooth address of audio gateway
+ * @param[in]    p_data      audio data
+ * @param[in]    length       audio length
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_bt_hf_client_send_audio(tls_bt_addr_t *bd_addr, uint8_t *p_data, uint16_t length);
+#endif

+ 151 - 0
include/bt/wm_bt_spp.h

@@ -0,0 +1,151 @@
+/**
+ * @file    wm_bt_spp.h
+ *
+ * @brief   Bluetooth API
+ *
+ * @author  WinnerMicro
+ *
+ * Copyright (c) 2020 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef __WM_BT_SPP_H__
+#define __WM_BT_SPP_H__
+
+#include "wm_bt.h"
+
+/**
+ * @defgroup BT_APIs Bluetooth APIs
+ * @brief Bluetooth related APIs
+ */
+
+/**
+ * @addtogroup BT_APIs
+ * @{
+ */
+
+/**
+ * @defgroup BT_SPP_APIs
+ * @brief BT_SPP APIs
+ */
+
+/**
+ * @addtogroup BT_SPP_APIs
+ * @{
+ */
+
+/**spp realed api*/
+/**
+ * @brief          Initializes the SPP interface
+ *
+ * @param[in]     callback      pointer on callback function
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_spp_init(tls_bt_spp_callback_t callback);
+
+/**
+ * @brief          Shuts down the SPP interface and does the cleanup
+ *
+ * @param       None
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_spp_deinit(void);
+
+/**
+ * @brief          Enable the bta jv interface
+ *
+ * @param[in]     None
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_spp_enable(void);
+
+/**
+ * @brief          Disable the bta jv interface and cleanup internal resource
+ *
+ * @param[in]     None
+ *
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_bt_spp_disable(void);
+
+
+/**
+ * @brief          Discovery the spp service by the given peer device.
+ *
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+
+tls_bt_status_t tls_bt_spp_start_discovery(tls_bt_addr_t *bd_addr, tls_bt_uuid_t *uuid);
+
+/**
+ * @brief          Create a spp connection to the remote device 
+ * 
+ * @param[in]   sec_mask:     Security Setting Mask
+ * @param[in]   role:         Server or client
+ * @param[in]   remote_scn:   Remote device bluetooth device SCN
+ * @param[in]      *bd_addr         remote device bluetooth device address
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_spp_connect(wm_spp_sec_t sec_mask,
+                          tls_spp_role_t role, uint8_t remote_scn, tls_bt_addr_t *bd_addr);
+
+/**
+ * @brief          Close a spp connection
+ *
+ * @param[in]   handle:    The connection handle
+ * 
+ * @retval         @ref tls_bt_status_t
+ *
+ * @note           None
+ */
+tls_bt_status_t tls_bt_spp_disconnect(uint32_t handle);
+
+/**
+ * @brief       This function create a SPP server and starts listening for an
+ *              SPP connection request from a remote Bluetooth device
+ *
+ * @param[in]   sec_mask:     Security Setting Mask .
+ * @param[in]   role:         Server or client.
+ * @param[in]   local_scn:    The specific channel you want to get.
+ *                            If channel is 0, means get any channel.
+ * @param[in]   name:         Server's name.
+ *
+ * @retval         @ref tls_bt_status_t
+
+ */
+tls_bt_status_t tls_bt_spp_start_server(wm_spp_sec_t sec_mask,
+                            tls_spp_role_t role, uint8_t local_scn, const char *name);
+
+/**
+ * @brief       This function is used to write data
+ *
+ * @param[in]   handle: The connection handle.
+ * @param[in]   len:    The length of the data written.
+ * @param[in]   p_data: The data written.
+ *
+ * @retval         @ref tls_bt_status_t
+
+ */
+tls_bt_status_t tls_bt_spp_write(uint32_t handle, uint8_t *p_data, int length);
+
+#endif
+
+

+ 270 - 0
include/driver/wm_7816.h

@@ -0,0 +1,270 @@
+/**************************************************************************//**
+ * @file     wm_7816.h
+ * @author
+ * @version
+ * @date
+ * @brief
+ * @copyright (c) 2014 Winner Microelectronics Co., Ltd. All rights reserved.
+ *****************************************************************************/
+#ifndef WM_7816_H_
+#define WM_7816_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+#include <stdbool.h>
+#include "wm_regs.h"
+#include "wm_type_def.h"
+#include "wm_io.h"
+
+#define WM_SC_RST_PIN		WM_IO_PB_23 //(23)    
+#define WM_SC_PWR_PIN		WM_IO_PB_24 //(29)	
+
+#define WM_SC_DEFAULT_FD	(372)
+
+typedef struct sc_io_map_ {
+	enum tls_io_name  clk_pin_num;
+	uint32_t  clk_opt;
+	enum tls_io_name io_pin_num;
+	uint32_t  io_opt;
+	uint8_t	initialed;
+} sc_io_map;
+
+extern sc_io_map sc_io;
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup 7816_Driver_APIs 7816 Driver APIs
+ * @brief 7816 driver APIs
+ */
+
+/**
+ * @addtogroup 7816_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief
+ *	This function is used to config the pin in gpio or 7816 mode for the 7816 power on timing
+ *
+ * @param[in] mode : 1--gpio mode ; 0--7816 mode	
+ *
+ * @retval
+ */
+void wm_sc_io_clk_config(uint8_t mode);
+
+/**
+ * @brief
+ *	close af to use as gpio
+ * @retval
+ */
+void wm_sc_powerInit(void);
+
+/**
+ * @brief
+ *	power on the 7816 device if power is controled by GPIO 
+ * @retval
+ */
+void wm_sc_poweron(void);
+
+/**
+ * @brief
+ *	power off the 7816 device if power is controled by GPIO 
+ * @retval
+ */
+void wm_sc_poweroff(void);
+
+/**
+ * @brief
+ *	driver the reset gpio in low level 
+ * @retval
+ */
+void wm_sc_rst_low(void);
+
+/**
+ * @brief
+ *	driver the reset gpio in high level 
+ * @retval
+ */
+void wm_sc_rst_high(void);
+
+/**
+ * @brief
+ *	hotrest the 7816 device obey the 7816-3 timing
+ * @retval
+ */
+void wm_sc_hotreset(void);
+
+/**
+ * @brief
+ *	colreset the 7816 device obey the 7816-3 timing
+ * @retval
+ */
+void wm_sc_colreset(void);
+
+/**
+ * @brief
+ *	deactive the 7816 device obey the 7816-3 timing
+ * @retval
+ */
+void wm_sc_deactive(void);
+
+/**
+ * @brief
+ *	This function is used to config the block guard time param in 7816 mode
+ * @param[in] bgt : the value of blcok guard time will be set	
+ * @retval
+ */
+void wm_sc_set_bgt(uint8_t bgt);
+
+/**
+ * @brief
+ *	This function is used to config the tx retry count when detect err signal
+ * @param[in] count : the value of retry time will be set 7 for max
+ * @retval
+ */
+void wm_sc_tx_retry_times(uint8_t count);
+
+/**
+ * @brief
+ *	This function is used to config the rx retry count when detect parity error
+ * @param[in] count : the value of retry time will be set 7 for max
+ * @retval
+ */
+void wm_sc_rx_retry_times(uint8_t count);
+
+/**
+ * @brief
+ *	This function is used to config the etu param
+ * @param[in] etu : the value of etu will be set
+ * @retval
+ */
+void wm_sc_set_etu(uint16_t etu);
+
+/**
+ * @brief
+ *	This function config the module clock freq
+ * @param[in] freq : the value of clock freq
+ * @retval
+ */
+void wm_sc_set_frequency(uint32_t freq);
+
+/**
+ * @brief
+ *	config recv or not when parity error 
+ * @param[in] bl :	1--- recv 
+ *					0--- don't recv
+ * @retval
+ */
+static inline void wm_sc_parity_recv(bool bl)
+{
+	tls_bitband_write(HR_UART2_LINE_CTRL, 9, bl);
+}
+
+/**
+ * @brief
+ *	select the model in 7816 or uart function 
+ * @param[in] bl :	1---7816 mode 
+ *					0---uart mode
+ * @retval
+ */
+static inline void wm_sc_7816_mode(bool bl)
+{
+	tls_bitband_write(HR_UART2_LINE_CTRL, 24, bl);	
+}
+
+/**
+ * @brief
+ *	This function is used to config the guard time param
+ * @param[in] bwt : the value of the guard time will be set
+ * @retval
+ */
+static inline void wm_sc_set_guardtime(uint8_t gt)
+{
+	tls_reg_write32(HR_UART2_GUARD_TIME, gt);
+}
+
+/**
+ * @brief
+ *	This function is used to config the CWT or BWT param
+ * @param[in] bwt : the value of CWT or BWT will be set
+ * @retval
+ */
+static inline void wm_sc_set_bcwt(uint32_t bwt)
+{
+	bwt = (bwt > 0xFFFFFF) ? 0xFFFFFF : bwt;
+	tls_reg_write32(HR_UART2_WAIT_TIME, bwt);	
+}
+
+/**
+ * @brief
+ *	module errsignal int enable or disable 
+ * @param[in] bl :	1---enable 
+ *					0---disable
+ * @retval
+ */
+static inline void wm_sc_tx_errsignal_mask(bool bl)
+{
+	tls_bitband_write(HR_UART2_INT_MASK, 9, bl);
+}
+
+/**
+ * @brief
+ *	config the module protol 
+ * @param[in] bl :	1--- T1 protocol
+ *					0--- T0 protocol
+ * @retval
+ */
+static inline void wm_sc_set_protocol(bool bl)
+{
+	tls_bitband_write(HR_UART2_LINE_CTRL, 8, bl);	
+}
+
+/**
+ * @brief
+ *	get the module protol 
+ * @retval
+ *		1--- T1 protocol
+ *		0--- T0 protocol
+ */
+static inline uint8_t wm_sc_get_protocol()
+{
+	return tls_bitband_read(HR_UART2_LINE_CTRL, 8);
+}
+
+/**
+ * @brief
+ *	smart card clock output enable or disable
+ * @param[in] bl : 0---enable;
+ *				   1---disable;
+ * @retval
+ */
+static inline void wm_sc_clk_enable(bool bl)
+{
+	tls_bitband_write(HR_UART2_LINE_CTRL, 10, bl);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 318 - 0
include/driver/wm_adc.h

@@ -0,0 +1,318 @@
+/***************************************************************************** 
+* 
+* File Name : wm_adc.h 
+* 
+* Description: adc Driver Module 
+* 
+* Copyright (c) 2014 Winner Microelectronics Co., Ltd. 
+* All rights reserved. 
+* 
+* Author : dave
+* 
+* Date : 2014-8-15
+*****************************************************************************/ 
+
+#ifndef WM_ADC_H
+#define WM_ADC_H
+
+#include "wm_type_def.h"
+
+#define ADC_DEST_BUFFER_SIZE			16383//以字为单位	
+
+
+/*ADC Result*/
+#define ADC_RESULT_MASK					(0x3FFFC)
+#define ADC_RESULT_VAL(n)				((n)&ADC_RESULT_MASK)
+
+/*ADC_ANALOG_CTRL*/
+#define CONFIG_ADC_CHL_SEL_MASK 		(0xF<<8)
+#define CONFIG_ADC_CHL_SEL(n)	 		((n)<<8)
+
+#define CONFIG_PD_ADC_MASK             	(0x1<<2)
+#define CONFIG_PD_ADC_VAL(n)           	((n)<<2)	/*1:pd adc, 0: normal work*/
+
+#define CONFIG_RSTN_ADC_MASK           	(0x1<<1)
+#define CONFIG_RSTN_ADC_VAL(n)          ((n)<<1)   /*1:normal work, 0:adc reset*/
+
+#define CONFIG_EN_LDO_ADC_MASK         	(0x1<<0)
+#define CONFIG_EN_LDO_ADC_VAL(n)       	((n)<<0)	/*1:ldo work, 0: ldo shutdown*/
+
+/*PGA_CTRL*/
+#define CLK_CHOP_SEL_PGA_MASK			(0x7<<4)
+#define CLK_CHOP_SEL_PGA_VAL(n)			((n)<<4)
+
+
+#define GAIN_CTRL_PGA_MASK				(0x3<<7)
+#define GAIN_CTRL_PGA_VAL(n)			((n)<<7)
+
+
+#define PGA_BYPASS_MASK					(0x1<<3)
+#define PGA_BYPASS_VAL(n)				((n)<<3)   /*1:bypass pga, 0:use pga*/
+
+#define BYPASS_INNER_REF_SEL			(0x1<<2)   /*Internal or external reference select*/
+
+#define PGA_CHOP_ENP_MASK				(0x1<<1)
+#define PGA_CHOP_ENP_VAL(n)				((n)<<1)   /*1: enable chop, 0: disable chop*/
+
+#define PGA_EN_MASK						(0x1<<0)
+#define PGA_EN_VAL(n)					((n)<<0)   /*1: enable pga, 0: disable pga*/
+
+
+/*Temperature Control*/
+#define TEMP_GAIN_MASK					(0x3<<4)
+#define TEMP_GAIN_VAL(n)				((n)<<4)
+
+#define TEMP_CAL_OFFSET_MASK			(0x1<<1)
+
+#define TEMP_EN_MASK					(0x1<<0)
+#define TEMP_EN_VAL(n)					((n)<<0)  /*1: enable temperature, 0: disable temperature*/
+
+
+/*ADC CTRL*/
+#define ANALOG_SWITCH_TIME_MASK			(0x3FF<<20)
+#define ANALOG_SWITCH_TIME_VAL(n)		(((n)&0x3FF)<<20)
+
+#define ANALOG_INIT_TIME_MASK			(0x3FF<<8)
+#define ANALOG_INIT_TIME_VAL(n)			(((n)&0x3FF)<<8)
+
+#define CMP_POLAR_MASK                  (0x1<<6)
+
+#define CMP_IRQ_EN_MASK                 (0x1<<5)
+#define CMP_IRQ_EN_VAL(n)				((n)<<5)  /*1: enable cmp irq, 0: disable cmp irq*/
+
+
+#define CMP_EN_MASK                 	(0x1<<4)
+#define CMP_EN_VAL(n)					((n)<<4) /*1: enable cmp function, 0: disable cmp function*/
+
+#define ADC_IRQ_EN_MASK                 (0x1<<1)
+#define ADC_IRQ_EN_VAL(n)				((n)<<1)   /*1:enable adc transfer irq, 0: disable*/
+
+#define ADC_DMA_EN_MASK                 (0x1<<0)
+#define ADC_DMA_EN_VAL(n)				((n)<<0)   /*1:enable adc dma, 0: disable*/
+
+
+/*ADC IRQ Status*/
+#define CMP_INT_MASK					(0x1<<1)
+
+#define ADC_INT_MASK					(0x1<<0)
+
+/*CMP Value*/
+#define CONFIG_ADC_INPUT_CMP_VAL(n)		((n)&0x3FFFF)
+
+
+/*ADC Channel*/
+#define CONFIG_ADC_CHL_OFFSET			(0x0E)
+#define CONFIG_ADC_CHL_VOLT				(0x0D)
+#define CONFIG_ADC_CHL_TEMP				(0x0C)
+
+
+
+#define ADC_INT_TYPE_ADC				0
+#define ADC_INT_TYPE_DMA				1
+#define ADC_INT_TYPE_ADC_COMP 			2
+
+#define ADC_REFERENCE_EXTERNAL  		0       //外部参考
+#define ADC_REFERENCE_INTERNAL  		1       //内部参考
+
+typedef struct adc_st{
+	u8 dmachannel;
+	void (*adc_cb)(int *buf, u16 len);
+	void (*adc_bigger_cb)(int *buf, u16 len);
+	void (*adc_dma_cb)(int *buf,u16 len);
+	u16 valuelen;		/*dma 采样数据长度*/
+	u16 offset;
+}ST_ADC;
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup ADC_Driver_APIs ADC Driver APIs
+ * @brief ADC driver APIs
+ */
+
+/**
+ * @addtogroup ADC_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to init adc.
+ *
+ * @param[in]      ifusedma    if use dma
+ * @param[in]      dmachannel  dma channel
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_adc_init(u8 ifusedma,u8 dmachannel);
+
+/**
+ * @brief          This function is used to register interrupt callback function.
+ *
+ * @param[in]      inttype    interrupt type:
+ *                 ADC_INT_TYPE_ADC		adc interrupt,user get adc result from the callback function.
+ *				   ADC_INT_TYPE_DMA		dma interrupt,dma transfer the adc result to the user's buffer.
+ * @param[in]      callback   interrupt callback function.
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_adc_irq_register(int inttype, void (*callback)(int *buf, u16 len));
+
+/**
+ * @brief          This function is used to clear the interrupt source.
+ *
+ * @param[in]      inttype    interrupt type:
+ *                 ADC_INT_TYPE_ADC		adc interrupt,user get adc result from the callback function.
+ *				   ADC_INT_TYPE_DMA		dma interrupt,dma transfer the adc result to the user's buffer.
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_adc_clear_irq(int inttype);
+
+/**
+ * @brief          This function is used to register interrupt callback function.
+ *
+ * @param[in]      Channel    adc channel,from 0 to 3 is single input;4 and 5 is differential input.
+ * @param[in]      Length     byte data length,is an integer multiple of half word,need <= 0x500
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_adc_start_with_dma(int Channel, int Length);
+
+/**
+ * @brief          This function is used to start adc.
+ *
+ * @param[in]      Channel    adc channel,from 0 to 3 is single input;4 and 5 is differential input.
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_adc_start_with_cpu(int Channel);
+
+/**
+ * @brief           This function is used to read adc result.
+ *
+ * @param[in]      	None
+ *
+ * @retval          adc result
+ *
+ * @note            None
+ */
+u32 tls_read_adc_result(void);
+
+/**
+ * @brief           This function is used to stop the adc.
+ *
+ * @param[in]      	ifusedma    if use dma
+ *
+ * @return          None
+ *
+ * @note            None
+ */
+void tls_adc_stop(int ifusedma);
+
+/**
+ * @brief           This function is used to config adc bigger register.
+ *
+ * @param[in]      	cmp_data    compare data
+ * @param[in]      	cmp_pol     compare pol
+ *
+ * @return          None
+ *
+ * @note            None
+ */
+void tls_adc_config_cmp_reg(int cmp_data, int cmp_pol);
+
+/**
+ * @brief           This function is used to set adc reference source.
+ *
+ * @param[in]      	ref     ADC_REFERENCE_EXTERNAL,ADC_REFERENCE_INTERNAL
+ *
+ * @return          None
+ *
+ * @note            None
+ */
+void tls_adc_reference_sel(int ref);
+
+/**
+ * @brief           This function is used to read internal temperature.
+ *
+ * @param[in]      	None
+ *
+ * @retval          temperature
+ *
+ * @note            None
+ */
+int adc_get_interTemp(void);
+
+/**
+ * @brief           This function is used to read input voltage.
+ *
+ * @param[in]      	channel    adc channel,from 0 to 3 is single input;8 and 9 is differential input.
+ *
+ * @retval          voltage    unit:mV
+ *
+ * @note            None
+ */
+int adc_get_inputVolt(u8 channel);
+
+int adc_get_inputVolt2(u8 channel, int* origin);
+
+/**
+ * @brief           This function is used to read internal voltage.
+ *
+ * @param[in]      	None
+ *
+ * @retval          voltage (mV)
+ *
+ * @note            None
+ */
+u32 adc_get_interVolt(void);
+
+/**
+ * @brief           This function is used to read temperature.
+ *
+ * @param[in]      	None
+ *
+ * @retval          temperature
+ *
+ * @note            None
+ */
+int adc_temp(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+void tls_adc_enable_calibration_buffer_offset(void);
+void tls_adc_voltage_start_with_cpu(void);
+void tls_adc_temp_offset_with_cpu(u8 calTemp12);
+void tls_adc_voltage_start_with_dma(int Length);
+void tls_adc_set_clk(int div);
+void signedToUnsignedData(int *adcValue);
+void tls_adc_buffer_bypass_set(u8 isset);
+void tls_adc_cmp_start(int Channel, int cmp_data, int cmp_pol);
+u32  adc_get_offset(void);
+
+#endif
+

+ 101 - 0
include/driver/wm_cpu.h

@@ -0,0 +1,101 @@
+/**
+ * @file    wm_cpu.h
+ *
+ * @brief   cpu driver module
+ *
+ * @author  dave
+ *
+ * @copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_CPU_H
+#define WM_CPU_H
+
+#include <stdint.h>
+
+/**XT806 BASE PLL CLOCK*/
+#define XT806_PLL_CLK_MHZ  		(480)
+
+enum CPU_CLK{
+	CPU_CLK_240M = 2,
+	CPU_CLK_160M = 3,
+	CPU_CLK_80M  = 6,
+	CPU_CLK_40M  = 12,
+	CPU_CLK_2M  = 240,		
+};
+
+typedef union {
+    struct {
+        uint32_t CPU: 8;                     /*!< bit:  0.. 7  cpu clock divider */
+        uint32_t WLAN: 8;                    /*!< bit:  8.. 15 Wlan clock divider */
+        uint32_t BUS2: 8;                    /*!< bit:  16.. 23 clock dividing ratio of bus2 & bus1 */
+        uint32_t PD: 4;                      /*!< bit:  24.. 27  peripheral divider */
+        uint32_t RSV: 3;                     /*!< bit:  28.. 30  Reserved */
+        uint32_t DIV_EN: 1;                  /*!< bit:  31     divide frequency enable */
+    } b;
+    uint32_t w;
+} clk_div_reg;
+
+#define UNIT_MHZ		(1000000)
+
+
+typedef struct{
+	u32 apbclk;
+	u32 cpuclk;
+	u32 wlanclk;
+}tls_sys_clk;
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup CPUCLK_Driver_APIs CPU CLOCK Driver APIs
+ * @brief CPU CLOCK driver APIs
+ */
+
+/**
+ * @addtogroup CPUCLK_Driver_APIs
+ * @{
+ */
+
+
+/**
+ * @brief          This function is used to set cpu clock
+ *
+ * @param[in]      	clk    select cpu clock
+ *                        	clk == CPU_CLK_80M	80M
+ *				clk == CPU_CLK_40M	40M
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_sys_clk_set(u32 clk);
+
+
+/**
+ * @brief          	This function is used to get cpu clock
+ *
+ * @param[out]     *sysclk	point to the addr for system clk output
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_sys_clk_get(tls_sys_clk *sysclk);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_CPU_H */

+ 233 - 0
include/driver/wm_dma.h

@@ -0,0 +1,233 @@
+/**
+ * @file    wm_dma.h
+ *
+ * @brief   DMA Driver Module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef __WM_DMA_H_
+#define __WM_DMA_H_
+
+#define TLS_DMA_SEL_UART_RX       0
+#define TLS_DMA_SEL_UART_TX       1
+#define TLS_DMA_SEL_PWM_CAP0       2
+#define TLS_DMA_SEL_PWM_CAP1       3
+#define TLS_DMA_SEL_LSSPI_RX       4
+#define TLS_DMA_SEL_LSSPI_TX       5
+#define TLS_DMA_SEL_SDADC_CH0      6
+#define TLS_DMA_SEL_SDADC_CH1      7
+#define TLS_DMA_SEL_SDADC_CH2      8
+#define TLS_DMA_SEL_SDADC_CH3      9
+#define TLS_DMA_SEL_I2S_RX         10
+#define TLS_DMA_SEL_I2S_TX         11
+#define TLS_DMA_SEL_SDIO_HOST      12
+
+#define TLS_DMA_FLAGS_HARD_MODE                 (1   << 0)
+#define TLS_DMA_FLAGS_CHAIN_MODE                (1   << 1)
+#define TLS_DMA_FLAGS_CHANNEL_SEL(n)            ((n) << 2)
+#define TLS_DMA_FLAGS_CHAIN_LINK_EN             (1   << 6)
+#define TLS_DMA_FLAGS_CHANNEL_VALID             (1   << 7)
+
+
+#define TLS_DMA_DESC_VALID                      (1U  << 31)
+#define TLS_DMA_DESC_CTRL_SRC_ADD_INC           (1   << 0)
+#define TLS_DMA_DESC_CTRL_DEST_ADD_INC          (1   << 2)
+#define TLS_DMA_DESC_CTRL_DATA_SIZE_BYTE        (0   << 4)
+#define TLS_DMA_DESC_CTRL_DATA_SIZE_SHORT       (1   << 4)
+#define TLS_DMA_DESC_CTRL_DATA_SIZE_WORD        (2   << 4)
+#define TLS_DMA_DESC_CTRL_BURST_SIZE1           (0   << 6)
+#define TLS_DMA_DESC_CTRL_BURST_SIZE4           (1   << 6)
+#define TLS_DMA_DESC_CTRL_TOTAL_BYTES(n)        ((n) << 7)
+
+
+/* dma interrupt flags */
+#define TLS_DMA_IRQ_BURST_DONE                  (1 << 0)
+#define TLS_DMA_IRQ_TRANSFER_DONE               (1 << 1)
+#define TLS_DMA_IRQ_BOTH_DONE                   (TLS_DMA_IRQ_BURST_DONE | TLS_DMA_IRQ_TRANSFER_DONE)
+
+struct tls_dma_descriptor {
+	unsigned int valid;
+	unsigned int dma_ctrl;
+	unsigned int src_addr;
+	unsigned int dest_addr;
+	struct tls_dma_descriptor *next;    /**< next dms descriptor */
+};
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup DMA_Driver_APIs DMA Driver APIs
+ * @brief DMA driver APIs
+ */
+
+/**
+ * @addtogroup DMA_Driver_APIs
+ * @{
+ */
+
+
+/**
+ * @brief          	This function is used to clear dma interrupt flag.
+ *
+ * @param[in]     	ch		Channel no.[0~7]
+ * @param[in]     	flags		Flags setted to TLS_DMA_IRQ_BURST_DONE, TLS_DMA_IRQ_TRANSFER_DONE, TLS_DMA_IRQ_BOTH_DONE.
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_dma_irq_clr(unsigned char ch, unsigned char flags);
+
+
+/**
+ * @brief          	This function is used to register dma interrupt callback function.
+ *
+ * @param[in]     	ch		Channel no.[0~7]
+ * @param[in]     	callback	is the dma interrupt call back function.
+ * @param[in]     	arg	the param of the callback function.
+ * @param[in]     	flags		Flags setted to TLS_DMA_IRQ_BURST_DONE, TLS_DMA_IRQ_TRANSFER_DONE, TLS_DMA_IRQ_BOTH_DONE.
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_dma_irq_register(unsigned char ch, void (*callback)(void *p), void *arg, unsigned char flags);
+
+
+/**
+ * @brief          This function is used to register dma interrupt
+ *
+ * @param[in]     	ch		DMA channel no.[0~7]
+ *
+ * @return         None
+ *
+ * @note           	None
+ */
+int tls_dma_wait_complt(unsigned char ch);
+
+
+/**
+ * @brief          This function is used to Start the DMA controller by Wrap
+ *
+ * @param[in]     	 autoReload 	Does restart when current transfer complete?	
+ * @param[in]     	 ch            	Channel no.[0~7]
+ * @param[in]     	 pDmaDesc    	Pointer to DMA channel descriptor structure.
+ *
+ * @retval         	Always STATUS_SUCCESS.	
+ *
+ * @note
+ *                  DMA Descriptor:
+ *            		+--------------------------------------------------------------+
+ *            		|Vld[31] |                    RSV                              |
+ *            	 	+--------------------------------------------------------------+
+ *            	 	|                  RSV           |         Dma_Ctrl[16:0]      |
+ *            	 	+--------------------------------------------------------------+
+ *            	 	|                         Src_Addr[31:0]                       |
+ *            	 	+--------------------------------------------------------------+
+ *            	 	|                         Dest_Addr[31:0]                      |
+ *            	 	+--------------------------------------------------------------+
+ *            	 	|                       Next_Desc_Add[31:0]                    |
+ *            	 	+--------------------------------------------------------------+
+ */
+unsigned char tls_dma_start_by_wrap(unsigned char ch, struct tls_dma_descriptor *dma_desc,
+                                    unsigned char auto_reload, unsigned short src_zize,
+                                    unsigned short dest_zize);
+
+
+/**
+ * @brief          This function is used to Wait until DMA operation completes
+ *
+ * @param[in]     	 autoReload 	Does restart when current transfer complete?	
+ * @param[in]     	 ch            	Channel no.[0~7]
+ * @param[in]     	 pDmaDesc    	Pointer to DMA channel descriptor structure.
+ *
+ * @retval         	 Always STATUS_SUCCESS.
+ *
+ * @note
+ *                  DMA Descriptor:
+ *            		+--------------------------------------------------------------+
+ *            		|Vld[31] |                    RSV                              |
+ *            	 	+--------------------------------------------------------------+
+ *            	 	|                  RSV           |         Dma_Ctrl[16:0]      |
+ *            	 	+--------------------------------------------------------------+
+ *            	 	|                         Src_Addr[31:0]                       |
+ *            	 	+--------------------------------------------------------------+
+ *            	 	|                         Dest_Addr[31:0]                      |
+ *            	 	+--------------------------------------------------------------+
+ *            	 	|                       Next_Desc_Add[31:0]                    |
+ *            	 	+--------------------------------------------------------------+
+ */
+unsigned char tls_dma_start(unsigned char ch, struct tls_dma_descriptor *dma_desc,
+                            unsigned char auto_reload);
+
+/**
+ * @brief          This function is used to To stop current DMA channel transfer
+ *
+ * @param[in]      ch    channel no. to be stopped
+ *
+ * @retval         	Always STATUS_SUCCESS
+ *
+ * @note           	If channel stop, DMA_CHNL_CTRL_CHNL_ON bit in DMA_CHNLCTRL_REG is cleared.
+ */
+unsigned char tls_dma_stop(unsigned char ch);
+
+
+ /**
+ * @brief        This function is used to Request a free dma channel
+ *				If ch is out of range [0,7] or valid but used, the function will select another free channel.
+ *		         else return the selected channel no.
+ * @param[in]    ch       specified channel when ch is valid and not used.
+ * @param[in]    flags    flags setted to selected channel
+ *
+ * @return       Real DMA Channel No: if there is free dma channel.
+ *               0xFF: when DMA channels are all used. 
+ *
+ * @note         If ch is invalid or valid but used, the function will select another free channel.
+ *               else return the selected channel no.
+ */
+unsigned char tls_dma_request(unsigned char ch, unsigned char flags);
+
+
+/**
+ * @brief          This function is used to Free the DMA channel when not use
+ *
+ * @param[in]      ch    channel no. that is ready to free
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_dma_free(unsigned char ch);
+
+
+/**
+ * @brief          This function is used to Initialize DMA Control
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_dma_init(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* __TLS_DMA_H_151606__ */
+

+ 282 - 0
include/driver/wm_efuse.h

@@ -0,0 +1,282 @@
+/**
+ * @file    wm_efuse.h
+ *
+ * @brief   virtual efuse Driver Module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_EFUSE_H
+#define WM_EFUSE_H
+
+#define TLS_EFUSE_STATUS_OK      (0)
+#define TLS_EFUSE_STATUS_EINVALID      (1)
+#define TLS_EFUSE_STATUS_EIO      (2)
+
+enum {
+	CMD_WIFI_MAC = 0x01,
+	CMD_BT_MAC,		
+	CMD_TX_DC,
+	CMD_RX_DC,
+	CMD_TX_IQ_GAIN,
+	CMD_RX_IQ_GAIN,
+	CMD_TX_IQ_PHASE,
+	CMD_RX_IQ_PHASE,
+	CMD_TX_GAIN,
+	CMD_ALL,
+};
+
+#define VCG_ADDR  (FT_MAGICNUM_ADDR + sizeof(FT_PARAM_ST)+4)
+#define VCG_LEN    (4)
+//#define TX_GAIN_NEW_ADDR (VCG_ADDR+VCG_LEN)
+#define TX_GAIN_LEN   (28*3)
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup EFUSE_Driver_APIs EFUSE Driver APIs
+ * @brief EFUSE driver APIs
+ */
+
+/**
+ * @addtogroup EFUSE_Driver_APIs
+ * @{
+ */
+
+/**
+* @brief 	This function is used to init ft param.
+*
+* @param[in]	None
+*
+* @retval	 	TRUE			init success
+* @retval		FALSE			init failed
+*/
+int tls_ft_param_init(void);
+
+
+/**
+* @brief 	This function is used to write ft_param.
+*
+* @param[in]	opnum  ft cmd
+* @param[in]	data   data pointer
+* @param[in]	len  len to write data
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			set success
+* @retval		TLS_EFUSE_STATUS_EIO			set failed
+*/
+int tls_ft_param_set(unsigned int opnum, void *data, unsigned int len);
+
+/**
+* @brief 	This function is used to read ft_param.
+*
+* @param[in]	opnum  ft cmd
+* @param[in]	data   data pointer
+* @param[in]	len  len to read data
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO			get failed
+*/
+int tls_ft_param_get(unsigned int opnum, void *data, unsigned int rdlen);
+
+
+/**
+* @brief 	This function is used to get mac addr
+*
+* @param[in]	mac		mac addr,6 byte
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO			get failed
+*/
+int tls_get_mac_addr(u8 *mac);
+
+/**
+* @brief 	This function is used to set mac addr
+*
+* @param[in]	mac		mac addr,6 byte
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			set success
+* @retval		TLS_EFUSE_STATUS_EIO			set failed
+*/
+int tls_set_mac_addr(u8 *mac);
+/**
+* @brief 	This function is used to get bluetooth mac addr
+*
+* @param[in]	mac		mac addr,6 byte
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO			get failed
+*/
+int tls_get_bt_mac_addr(u8 *mac);
+
+/**
+* @brief 	This function is used to set bluetooth mac addr
+*
+* @param[in]	mac		mac addr,6 byte
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			set success
+* @retval		TLS_EFUSE_STATUS_EIO			set failed
+*/
+int tls_set_bt_mac_addr(u8 *mac);
+
+
+/**
+* @brief 	This function is used to get tx gain
+*
+* @param[in]	txgain		tx gain,12 byte
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO		get failed
+*/
+int tls_get_tx_gain(u8 *txgain);
+
+/**
+* @brief 	This function is used to set tx gain
+*
+* @param[in]	txgain		tx gain,12 byte
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			set success
+* @retval		TLS_EFUSE_STATUS_EIO		set failed
+*/
+int tls_set_tx_gain(u8 *txgain);
+
+/**
+* @brief 	This function is used to get tx lod
+*
+* @param[in]	txlo		tx lod
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO		get failed
+*/
+int tls_get_tx_lo(u8 *txlo);
+
+/**
+* @brief 	This function is used to set tx lod
+*
+* @param[in]	txlo		tx lod
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			set success
+* @retval		TLS_EFUSE_STATUS_EIO		set failed
+*/
+
+int tls_set_tx_lo(u8 *txlo);
+
+/**
+* @brief 	This function is used to get tx iq gain
+*
+* @param[in]	txGain		
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO		get failed
+*/
+int tls_get_tx_iq_gain(u8 *txGain);
+
+/**
+* @brief 	This function is used to set tx iq gain
+*
+* @param[in]	txGain		
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			set success
+* @retval		TLS_EFUSE_STATUS_EIO		set failed
+*/
+int tls_set_tx_iq_gain(u8 *txGain);
+
+/**
+* @brief 	This function is used to get rx iq gain
+*
+* @param[in]	rxGain		
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO		get failed
+*/
+int tls_get_rx_iq_gain(u8 *rxGain);
+
+/**
+* @brief 	This function is used to get rx iq gain
+*
+* @param[in]	rxGain		
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			set success
+* @retval		TLS_EFUSE_STATUS_EIO		set failed
+*/
+int tls_set_rx_iq_gain(u8 *rxGain);
+
+/**
+* @brief 	This function is used to get tx iq phase
+*
+* @param[in]	txPhase		
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO		get failed
+*/
+int tls_get_tx_iq_phase(u8 *txPhase);
+
+/**
+* @brief 	This function is used to set tx iq phase
+*
+* @param[in]	txPhase		
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			set success
+* @retval		TLS_EFUSE_STATUS_EIO		set failed
+*/
+int tls_set_tx_iq_phase(u8 *txPhase);
+
+/**
+* @brief 	This function is used to get rx iq phase
+*
+* @param[in]	rxPhase		
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO		get failed
+*/
+int tls_get_rx_iq_phase(u8 *rxPhase);
+
+/**
+* @brief 	This function is used to set rx iq phase
+*
+* @param[in]	rxPhase		
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			set success
+* @retval		TLS_EFUSE_STATUS_EIO		set failed
+*/
+int tls_set_rx_iq_phase(u8 *rxPhase);
+
+/**
+* @brief 	This function is used to set/get freq err
+*
+* @param[in]	freqerr	
+* @param[in]    flag  1-set  0-get
+* @retval	 	TLS_EFUSE_STATUS_OK			set/get success
+* @retval		TLS_EFUSE_STATUS_EIO		set/get failed
+*/
+int tls_freq_err_op(u8 *freqerr, u8 flag);
+
+/**
+* @brief 	This function is used to set/get vcg ctrl
+*
+* @param[in]	vcg	
+* @param[in]    flag  1-set  0-get
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			set/get success
+* @retval		TLS_EFUSE_STATUS_EIO		set/get failed
+*/
+int tls_rf_vcg_ctrl_op(u8 *vcg, u8 flag);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_EFUSE_H */
+

+ 159 - 0
include/driver/wm_flash.h

@@ -0,0 +1,159 @@
+/**
+ * @file    wm_flash.h
+ *
+ * @brief   flash Driver module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_FLASH_H
+#define WM_FLASH_H
+
+#include "wm_type_def.h"
+#include "wm_osal.h"
+
+#define TLS_FLS_STATUS_OK      (0)
+#define TLS_FLS_STATUS_EINVAL      (1)
+#define TLS_FLS_STATUS_EBUSY      (2)
+#define TLS_FLS_STATUS_EPERM      (3)
+#define TLS_FLS_STATUS_ENOSUPPORT      (4)
+#define TLS_FLS_STATUS_EEXIST      (5)
+#define TLS_FLS_STATUS_ENOMEM      (6)
+#define TLS_FLS_STATUS_EOVERFLOW      (7)
+#define TLS_FLS_STATUS_ENODEV      (8)
+#define TLS_FLS_STATUS_EDEV      (9)
+#define TLS_FLS_STATUS_EIO      (10)
+#define TLS_FLS_STATUS_ENODRV      (11)
+
+#define TLS_FLS_PARAM_TYPE_ID      (0)
+#define TLS_FLS_PARAM_TYPE_SIZE      (1)
+#define TLS_FLS_PARAM_TYPE_PAGE_SIZE      (2)
+#define TLS_FLS_PARAM_TYPE_PROG_SIZE      (3)
+#define TLS_FLS_PARAM_TYPE_SECTOR_SIZE      (4)
+
+#define TLS_FLS_FLAG_UNDER_PROTECT      (1<<0)
+#define TLS_FLS_FLAG_FAST_READ      (1<<1)
+#define TLS_FLS_FLAG_AAAI      (1<<2)
+
+#define FLS_CMD_READ_DEV_ID     (0x9F)  // read device id //(0x9f)
+
+/**
+ * @struct fls_list     list
+ */
+struct fls_list
+{
+    struct fls_list *next;
+    struct fls_list *prev;
+};
+
+
+/**
+ * @struct tls_fls_drv     flash driver
+ */
+struct tls_fls_drv
+{
+    struct fls_list drv_list;
+    u32 id;
+    u32 total_size;
+    u32 page_size;
+    u32 program_size;
+    u32 sector_size;
+    u32 clock;
+    u8 mode;
+    u8 cs_active;
+    u8 flags;
+    int (*read) (u32, u8 *, u32);
+    int (*fast_read) (u32, u8 *, u32);
+    int (*page_write) (u32, u8 *);
+    int (*erase) (u32);
+    int (*chip_erase) (void);
+    int (*probe)(u32 id);
+    void (*remove) (void);
+};
+
+/**
+ * @struct tls_fls     flash
+ */
+struct tls_fls
+{
+    struct fls_list fls_drvs;
+    struct tls_fls_drv *current_drv;
+    tls_os_sem_t *fls_lock;
+};
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup SPIFLASH_Driver_APIs SPI FLASH Driver APIs
+ * @brief SPI FLASH driver APIs
+ */
+
+/**
+ * @addtogroup SPIFLASH_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to initial flash module structer.
+ *
+ * @param[in]      None
+ *
+ * @retval         TLS_FLS_STATUS_OK	                if init sucsess
+ * @retval         TLS_FLS_STATUS_EBUSY            already inited
+ * @retval         TLS_FLS_STATUS_ENOMEM         memory error
+ *
+ * @note           None
+ */
+int tls_spifls_init(void);
+
+
+/**
+ * @brief          This function is used to read data from the flash.
+ *
+ * @param[in]      addr                  Specifies the starting address to read from
+ * @param[in]      buf                   Pointer to a byte array that is to be written.
+ * @param[in]      len                   length to read.
+ *
+ * @retval         TLS_FLS_STATUS_OK	    if read sucsess
+ * @retval         TLS_FLS_STATUS_EIO	    if read fail
+ *
+ * @note           None
+ */
+int tls_spifls_read(u32 addr, u8 * buf, u32 len);
+
+
+/**
+ * @brief          This function is used to write data into the flash.
+ *
+ * @param[in]      addr      Specifies the starting address to write to.
+ * @param[in]      buf       Pointer to a byte array that holds the data to be written.
+ * @param[in]      len       length to write.
+ *
+ * @retval         TLS_FLS_STATUS_OK	           if write flash success
+ * @retval         TLS_FLS_STATUS_EPERM	    if flash struct point is null
+ * @retval         TLS_FLS_STATUS_ENODRV	    if flash driver is not installed
+ * @retval         TLS_FLS_STATUS_EINVAL	    if argument is invalid
+ * @retval         TLS_FLS_STATUS_EIO           if io error
+ *
+ * @note           None
+ */
+int tls_spifls_write(u32 addr, u8 * buf, u32 len);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_FLASH_H */

+ 41 - 0
include/driver/wm_flash_map.h

@@ -0,0 +1,41 @@
+/**
+ * @file    wm_flash_map.h
+ *
+ * @brief   flash zone map
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef __WM_FLASH_MAP_H__
+#define __WM_FLASH_MAP_H__
+
+/**FLASH MAP**/
+
+/**Flash Base Address */
+#define FLASH_BASE_ADDR						(0x8000000UL)
+
+/**Upgrade image area*/
+#define CODE_UPD_START_ADDR					(0x8010000UL)
+
+/**Run-time image header area*/
+#define CODE_RUN_START_ADDR                 (0x80D0000UL)
+// #define CODE_RUN_START_ADDR                 (0x8010000UL)
+
+/**Area can be used by User*/
+#define USER_ADDR_START						(0x81E0000UL)
+// #define USER_ADDR_START						(0x81C0000UL)
+
+
+/**System parameter defined in wm_internal_fls.c*/
+extern unsigned int TLS_FLASH_PARAM_DEFAULT;
+extern unsigned int TLS_FLASH_PARAM1_ADDR;
+extern unsigned int TLS_FLASH_PARAM2_ADDR;
+extern unsigned int TLS_FLASH_PARAM_RESTORE_ADDR;
+extern unsigned int TLS_FLASH_OTA_FLAG_ADDR;
+extern unsigned int TLS_FLASH_END_ADDR;
+
+#define SIGNATURE_WORD      				(0xA0FFFF9FUL)
+#define IMAGE_START_ADDR_MSK			    (0x400)
+#endif /*__WM_CONFIG_H__*/
+

+ 60 - 0
include/driver/wm_fls_gd25qxx.h

@@ -0,0 +1,60 @@
+/**
+ * @file    wm_fls_gd25qxx.h
+ *
+ * @brief  wm gd25qxx flash driver
+ *
+ * @author  dave
+ *
+ * @copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef TLS_EXSPIFLS_H
+#define TLS_EXSPIFLS_H
+
+#define SPI_SCLK							(10000000)  /** 10MHz. */
+#define FLASH_TOTAL_SIZE            (1024*1024)
+#define PAGE_SIZE						256
+#define PROGRAM_SIZE					256
+#define PAGE_ADDR_OFFSET				8
+#define SECTOR_SIZE						4096
+
+
+/**
+ *  command code define.
+ */
+#define EXSPIFLASH_WRITE_ENABLE      (0x06)    /** Global write enable */
+#define EXSPIFLASH_WRITE_DISABLE      (0x04)   /** Global write disable */
+#define EXSPIFLASH_READ_SR1      (0x05)    /** Read flash status register s0~s7 */
+#define EXSPIFLASH_READ_SR2      (0x35)    /** Read flash status register s8~s15 */
+#define EXSPIFLASH_WRITE_SR      (0x01)    /** Write flash status register s0~s15 */
+#define EXSPIFLASH_PAGE_PROGRAM      (0x02)    /** program one page */
+#define EXSPIFLASH_DATA_READ      (0x03)   /** read data from specified address */
+#define EXSPIFLASH_DATA_FAST_READ      (0x0b)  /** fast read data from specified address */
+#define EXSPIFLASH_SECTOR_ERASE      (0x20)    /** Sector erase */
+#define EXSPIFLASH_BLOCK32_ERASE      (0x52)   /** 32KB Block erase(128 pages) */
+#define EXSPIFLASH_BLOCK64_ERASE      (0xd8)   /** 64kb Block erase(256 pages) */
+#define EXSPIFLASH_CHIP_ERASE      (0xc7)  /** Chip erase */
+#define EXSPIFLASH_FLASH_DEVICEID      (0x90)  /** Read flash manufacturer/device ID */
+#define EXSPIFLASH_FLASH_ID      (0x9f)    /** Read flash ID */
+
+
+#define FLASH_STATUS_BUSY      (1 << 0)
+#define FLASH_STATUS_WEL      (1 << 1)
+
+/**
+ * @brief          This function is used to install gd25qxx driver.
+ *
+ * @param[in]      None
+ *
+ * @retval         TLS_FLS_STATUS_OK	         if write flash success
+ * @retval         TLS_FLS_STATUS_EPERM     if flash struct point is null
+ * @retval         TLS_FLS_STATUS_ENODRV	  if flash driver is not installed
+ * @retval         TLS_FLS_STATUS_EINVAL	  if argument is invalid
+ * @retval         TLS_FLS_STATUS_EIO	         if io error
+ * @retval         TLS_FLS_STATUS_EEXIST	  if driver is already existed
+ *
+ * @note           None
+ */
+int tls_spifls_drv_install(void);
+
+#endif /* TLS_FLS_GD25QXX_H */

+ 181 - 0
include/driver/wm_gpio.h

@@ -0,0 +1,181 @@
+/**
+ * @file wm_gpio.h
+ *
+ * @brief GPIO Driver Module
+ *
+ * @author dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_GPIO_H
+#define WM_GPIO_H
+
+#include "wm_type_def.h"
+#include "wm_io.h"
+
+/** gpio interrupte callback function */
+typedef void (*tls_gpio_irq_callback)(void *arg);
+
+/** Indicating gpio direction */
+enum tls_gpio_dir {
+    WM_GPIO_DIR_OUTPUT,    /**< output */
+    WM_GPIO_DIR_INPUT      /**< input */
+};
+
+/** Indicating gpio attribute */
+enum tls_gpio_attr {
+    WM_GPIO_ATTR_FLOATING,    /**< floating status */
+    WM_GPIO_ATTR_PULLHIGH,    /**< pull high */
+    WM_GPIO_ATTR_PULLLOW      /**< pull low */
+};
+
+/** Indicating gpio interrupt trigger type */
+enum tls_gpio_irq_trig {
+    WM_GPIO_IRQ_TRIG_RISING_EDGE,    /**< rising edge arises the interrupt */
+    WM_GPIO_IRQ_TRIG_FALLING_EDGE,   /**< falling edge arises the interrupt */
+    WM_GPIO_IRQ_TRIG_DOUBLE_EDGE,    /**< both rising edge and falling edge arise the interrupt */
+    WM_GPIO_IRQ_TRIG_HIGH_LEVEL,     /**< high power level arises the interrupt */
+    WM_GPIO_IRQ_TRIG_LOW_LEVEL       /**< low power level arises the interrupt */
+};
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup GPIO_Driver_APIs GPIO Driver APIs
+ * @brief GPIO driver APIs
+ */
+
+/**
+ * @addtogroup GPIO_Driver_APIs
+ * @{
+ */
+
+
+/**
+ * @brief          	This function is used to config gpio function
+ *
+ * @param[in]      	gpio_pin    	gpio pin num
+ * @param[in]      	dir         		gpio direction
+ * @param[in]      	attr        		gpio attribute
+ *
+ * @return         None
+ *
+ * @note			None	
+ */
+void tls_gpio_cfg(enum tls_io_name gpio_pin, enum tls_gpio_dir dir, enum tls_gpio_attr attr);
+
+
+/**
+ * @brief          This function is used to read gpio status
+ *
+ * @param[in]      gpio_pin    gpio pin num
+ *
+ * @retval         0     power level is low
+ * @retval         1     power level is high
+ *
+ * @note           None
+ */
+u8 tls_gpio_read(enum tls_io_name gpio_pin);
+
+
+/**
+ * @brief          	This function is used to modify gpio status
+ *
+ * @param[in]      	gpio_pin    	gpio pin num
+ * @param[in]      	value       	power level
+ *                        	0: 			low  power level
+ * 				1: 			high power level
+ *
+ * @return         	None
+ *
+ * @note           None
+ */
+void tls_gpio_write(enum tls_io_name gpio_pin, u8 value);
+
+
+/**
+ * @brief          This function is used to config gpio interrupt
+ *
+ * @param[in]      gpio_pin    gpio pin num
+ * @param[in]      mode        interrupt trigger type
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_gpio_irq_enable(enum tls_io_name gpio_pin, enum tls_gpio_irq_trig mode);
+
+
+/**
+ * @brief          This function is used to disable gpio interrupt
+ *
+ * @param[in]      gpio_pin    gpio pin num
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_gpio_irq_disable(enum tls_io_name gpio_pin);
+
+
+/**
+ * @brief          This function is used to get gpio interrupt status
+ *
+ * @param[in]      gpio_pin    gpio pin num
+ *
+ * @retval         0     no interrupt happened
+ * @retval         1     interrupt happened
+ *
+ * @note           None
+ */
+u8 tls_get_gpio_irq_status(enum tls_io_name gpio_pin);
+
+
+/**
+ * @brief          This function is used to clear gpio interrupt flag
+ *
+ * @param[in]      gpio_pin    gpio pin num
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_clr_gpio_irq_status(enum tls_io_name gpio_pin);
+
+
+/**
+ * @brief          This function is used to register gpio interrupt
+ *
+ * @param[in]      gpio_pin    gpio pin num
+ * @param[in]      callback    the gpio interrupt call back function
+ * @param[in]      arg         parammeter for the callback
+ *
+ * @return         None
+ *
+ * @note
+ * gpio callback function is called in interrupt,
+ * so can not operate the critical data in the callback fuuction,
+ * recommendation to send messages to other tasks to operate it.
+ */
+void tls_gpio_isr_register(enum tls_io_name gpio_pin,
+                           tls_gpio_irq_callback callback,
+                           void *arg);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#endif /* end of WM_GPIO_H */
+

+ 589 - 0
include/driver/wm_gpio_afsel.h

@@ -0,0 +1,589 @@
+/**
+ * @file wm_gpio_afsel.h
+ *
+ * @brief GPIO Driver Module
+ *
+ * @author dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_GPIO_AFSEL_H
+#define WM_GPIO_AFSEL_H
+
+#include "wm_gpio.h"
+#include "wm_regs.h"
+#include "wm_irq.h"
+#include "wm_osal.h"
+#include "tls_common.h"
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup IOMUX_Driver_APIs IOMUX Driver APIs
+ * @brief IO Multiplex driver APIs
+ */
+
+/**
+ * @addtogroup IOMUX_Driver_APIs
+ * @{
+ */
+
+
+/**
+ * @brief  config the pins used for highspeed spi
+ * @param  numsel: config highspeed spi pins multiplex relation,valid para 0,1
+ *			 0: hspi0 		  1: hspi1 only for 56pin
+ *			    hspi_ck  PB06      hspi_ck  PB12
+ *			    hspi_int PB07      hspi_int PB13
+ *			    hspi_cs  PB09      hspi_cs  PB14
+ *			    hspi_di  PB10      hspi_di  PB15
+ *			    hspi_do	PB11      hspi_do	 PB16
+ * @return None
+ */
+void wm_hspi_gpio_config(uint8_t numsel);
+
+/**
+ * @brief  config the pins used for spi ck
+ * @param  io_name: config spi ck pins name
+ *			WM_IO_PB_01
+ *			WM_IO_PB_02
+ *			WM_IO_PB_15 only for 56pin
+ *			WM_IO_PB_24 only for 56pin
+ *				
+ * @return None
+ */
+void wm_spi_ck_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for spi cs
+ * @param  io_name: config spi cs pins name
+ *			WM_IO_PA_00
+ *			WM_IO_PB_04
+ *			WM_IO_PB_14 only for 56pin
+ *			WM_IO_PB_23 only for 56pin 
+ *				
+ * @return None
+ */
+void wm_spi_cs_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for spi di
+ * @param  io_name: config spi di pins name
+ *			WM_IO_PB_00
+ *			WM_IO_PB_03
+ *			WM_IO_PB_16 only for 56pin
+ *			WM_IO_PB_25 only for 56pin  
+ *				
+ * @return None
+ */
+void wm_spi_di_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for spi do
+ * @param  io_name: config spi do pins name
+ *			WM_IO_PA_07
+ *			WM_IO_PB_05
+ *			WM_IO_PB_17 only for 56pin
+ *			WM_IO_PB_26 only for 56pin  
+ *				
+ * @return None
+ */
+void wm_spi_do_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for sdio host ck dat0 dat1 dat2 dat3
+ * @param  numsel: config sdio ck cmd dat0 dat1 dat2 dat3 pins multiplex relation,valid para 0,1
+ *			0:                 1: only for 56pin
+ *			  sdio_ck   PB06     sdio_ck   PA09
+ *			  sdio_cmd  PB07     sdio_cmd  PA10
+ *			  sdio_dat0 PB08     sdio_dat0 PA11
+ *			  sdio_dat1 PB09     sdio_dat1 PA12
+ *			  sdio_dat2 PB10     sdio_dat2 PA13
+ *			  sdio_dat3 PB11     sdio_dat3 PA14
+ *				
+ * @return None
+ */
+void wm_sdio_host_config(uint8_t numsel);
+
+/**
+ * @brief  config the pins used for sdio slave ck dat0 dat1 dat2 dat3
+ * @param  numsel: config sdio ck cmd dat0 dat1 dat2 dat3 pins multiplex relation,valid para 0
+ *			0: 
+ *			  sdio_ck   PB06
+ *            sdio_cmd  PB07
+ *			  sdio_dat0 PB08
+ *			  sdio_dat1 PB09
+ *			  sdio_dat2 PB10
+ *			  sdio_dat3 PB11
+ *				
+ * @return None
+ */
+void wm_sdio_slave_config(uint8_t numsel);
+
+/**
+ * @brief  config the pins used for psram ck cs dat0 dat1 dat2 dat3
+ * @param  numsel: config psram ck cs dat0 dat1 dat2 dat3 pins multiplex relation,valid para 0,1
+ *			0:                 1: only for 56pin
+ *			  psram_ck   PB00    psram_ck   PA15
+ *			  psram_cs   PB01    psram_cs   PB27
+ *			  psram_dat0 PB02    psram_dat0 PB02
+ *			  psram_dat1 PB03    psram_dat1 PB03
+ *			  psram_dat2 PB04    psram_dat2 PB04
+ *			  psram_dat3 PB05    psram_dat3 PB05
+
+ * @return None
+ */
+void wm_psram_config(uint8_t numsel);
+
+/**
+ * @brief  config the pins used for uart0 tx
+ * @param  io_name: config uart0 tx pins name
+ *			WM_IO_PB_19
+ *			WM_IO_PB_27 only for 56pin
+ *				
+ * @return None
+ */
+void wm_uart0_tx_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart0 rx
+ * @param  io_name: config uart0 rx pins name
+ *			WM_IO_PB_20
+ *				
+ * @return None
+ */
+void wm_uart0_rx_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart1 tx
+ * @param  io_name: config uart1 tx pins name
+ *			WM_IO_PB_06
+ *				
+ * @return None
+ */
+void wm_uart1_tx_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart1 rx
+ * @param  io_name: config uart1 rx pins name
+ *			WM_IO_PB_07
+ *			WM_IO_PB_16 only for 56pin
+ *				
+ * @return None
+ */
+void wm_uart1_rx_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart1 rts
+ * @param  io_name: config uart1 rts pins name
+ *			WM_IO_PB_19
+ *			WM_IO_PA_02 only for 56pin 
+ *				
+ * @return None
+ */
+void wm_uart1_rts_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart1 cts
+ * @param  io_name: config uart1 cts pins name
+ *			WM_IO_PB_20
+ *			WM_IO_PA_03 only for 56pin
+ *				
+ * @return None
+ */
+void wm_uart1_cts_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart2 tx or 7816-io
+ * @param  io_name: config uart2 tx or 7816-io pins name
+ *			WM_IO_PB_02
+ *			WM_IO_PA_02 only for 56pin  
+ *				
+ * @return None
+ */
+void wm_uart2_tx_scio_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart2 rx
+ * @param  io_name: config uart2 rx pins name
+ *			WM_IO_PB_03
+ *			WM_IO_PA_03 only for 56pin  
+ *				
+ * @return None
+ */
+void wm_uart2_rx_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart2 rts or 7816-clk
+ * @param  io_name: config uart2 rts or 7816-clk pins name
+ *			WM_IO_PB_04
+ *			WM_IO_PA_05 only for 56pin  
+ *				
+ * @return None
+ */
+void wm_uart2_rts_scclk_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart2 cts
+ * @param  io_name: config uart2 cts pins name
+ *			WM_IO_PB_05
+ *			WM_IO_PA_06 only for 56pin  
+ *				
+ * @return None
+ */
+void wm_uart2_cts_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart3 tx
+ * @param  io_name: config uart1 tx pins name
+ *			WM_IO_PB_00
+ *			WM_IO_PA_05 only for 56pin  
+ *				
+ * @return None
+ */
+void wm_uart3_tx_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart3 rx
+ * @param  io_name: config uart1 rx pins name
+ *			WM_IO_PB_01
+ *			WM_IO_PA_06 only for 56pin  
+ *				
+ * @return None
+ */
+void wm_uart3_rx_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart3 rts
+ * @param  io_name: config uart3 rts pins name
+ *			WM_IO_PA_02
+ *				
+ * @return None
+ */
+void wm_uart3_rts_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart3 cts
+ * @param  io_name: config uart3 cts pins name
+ *			WM_IO_PA_03
+ *				
+ * @return None
+ */
+ void wm_uart3_cts_config(enum tls_io_name io_name);
+
+
+/**
+ * @brief  config the pins used for uart4 tx
+ * @param  io_name: config uart1 tx pins name
+ *			WM_IO_PB_04
+ *			WM_IO_PA_08 only for 56pin 
+ *				
+ * @return None
+ */
+void wm_uart4_tx_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart4 rx
+ * @param  io_name: config uart1 rx pins name
+ *			WM_IO_PB_05
+ *			WM_IO_PA_09 only for 56pin  
+ *				
+ * @return None
+ */
+void wm_uart4_rx_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart4 rts
+ * @param  io_name: config uart4 rts pins name
+ *			WM_IO_PA_05 only for 56pin 
+ *			WM_IO_PA_10 only for 56pin 
+ *				
+ * @return None
+ */
+void wm_uart4_rts_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart4 cts
+ * @param  io_name: config uart4 cts pins name
+ *			WM_IO_PA_06 only for 56pin 
+ *			WM_IO_PA_11 only for 56pin 
+ *				
+ * @return None
+ */
+ void wm_uart4_cts_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart4 tx
+ * @param  io_name: config uart1 tx pins name
+ *			WM_IO_PA_08 only for 56pin 
+ *			WM_IO_PA_12 only for 56pin 
+ *			WM_IO_PB_18 only for 56pin 
+ *				
+ * @return None
+ */
+void wm_uart5_tx_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart4 rx
+ * @param  io_name: config uart1 rx pins name
+ *			WM_IO_PA_09 only for 56pin 
+ *			WM_IO_PA_13 only for 56pin 
+ *			WM_IO_PB_17 only for 56pin 
+ *				
+ * @return None
+ */
+void wm_uart5_rx_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart4 rts
+ * @param  io_name: config uart4 rts pins name
+ *			WM_IO_PA_14 only for 56pin 
+ *			WM_IO_PB_12 only for 56pin 
+ *				
+ * @return None
+ */
+void wm_uart5_rts_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for uart4 cts
+ * @param  io_name: config uart4 cts pins name
+ *			WM_IO_PA_15 only for 56pin 
+ *			WM_IO_PB_13 only for 56pin 
+ *				
+ * @return None
+ */
+ void wm_uart5_cts_config(enum tls_io_name io_name);
+
+
+
+/**
+ * @brief  config the pins used for i2s ck
+ * @param  io_name: config i2s master ck pins name
+ *			WM_IO_PA_04	 
+ *			WM_IO_PB_08
+ *			WM_IO_PA_08 only for 56pin 
+ *			WM_IO_PB_12 only for 56pin 
+ *				
+ * @return None
+ */
+void wm_i2s_ck_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for i2s ws
+ * @param  io_name: config i2s master ws pins name
+ *			WM_IO_PA_01
+ *			WM_IO_PB_09
+ *			WM_IO_PA_09 only for 56pin 
+ *			WM_IO_PB_13 only for 56pin  
+ *				
+ * @return None
+ */
+void wm_i2s_ws_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for i2s do
+ * @param  io_name: config i2s master do pins name
+ *			WM_IO_PA_00
+ *			WM_IO_PB_11
+ *			WM_IO_PA_10 only for 56pin 
+ *			WM_IO_PB_14 only for 56pin   
+ *				
+ * @return None
+ */
+void wm_i2s_do_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for i2s di
+ * @param  io_name: config i2s slave di pins name
+ *			WM_IO_PA_07
+ *			WM_IO_PB_10
+ *			WM_IO_PA_11 only for 56pin 
+ *			WM_IO_PB_15 only for 56pin   
+ *				
+ * @return None
+ */
+void wm_i2s_di_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for i2s mclk
+ * @param  io_name: config i2s mclk pins name
+ *			WM_IO_PA_00
+ *				
+ * @return None
+ */
+void wm_i2s_mclk_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for i2s extclk
+ * @param  io_name: config i2s extclk pins name
+ *			WM_IO_PA_07
+ *				
+ * @return None
+ */
+void wm_i2s_extclk_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for i2c scl
+ * @param  io_name: config i2c scl pins name
+ *			WM_IO_PA_01
+ *			WM_IO_PB_20
+ *				
+ * @return None
+ */
+void wm_i2c_scl_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for i2c sda
+ * @param  io_name: config i2c sda pins name
+ *			WM_IO_PA_04
+ *			WM_IO_PB_19
+ *				
+ * @return None
+ */
+void wm_i2c_sda_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for pwm0
+ * @param  io_name: config pwm1 pins name
+ *			WM_IO_PB_00
+ *			WM_IO_PB_19
+ *			WM_IO_PA_02 only for 56pin 
+ *			WM_IO_PA_10 only for 56pin   
+ *			WM_IO_PB_12 only for 56pin   
+ *				
+ * @return None
+ */
+void wm_pwm0_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for pwm1
+ * @param  io_name: config pwm1 pins name
+ *			WM_IO_PB_01
+ *			WM_IO_PB_20
+ *			WM_IO_PA_03 only for 56pin 
+ *			WM_IO_PA_11 only for 56pin   
+ *			WM_IO_PB_13 only for 56pin    
+ *				
+ * @return None
+ */
+void wm_pwm1_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for pwm2
+ * @param  io_name: config pwm3 pins name
+ *			WM_IO_PA_00
+ *			WM_IO_PB_02 
+ *			WM_IO_PA_12 only for 56pin 
+ *			WM_IO_PB_14 only for 56pin   
+ *			WM_IO_PB_24 only for 56pin    
+ *				
+ * @return None
+ */
+void wm_pwm2_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for pwm3
+ * @param  io_name: config pwm4 pins name
+ *			WM_IO_PA_01
+ *			WM_IO_PB_03
+ *			WM_IO_PA_13 only for 56pin 
+ *			WM_IO_PB_15 only for 56pin   
+ *			WM_IO_PB_25 only for 56pin     
+ *				
+ * @return None
+ */
+void wm_pwm3_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for pwm4
+ * @param  io_name: config pwm5 pins name
+ *			WM_IO_PA_04
+ *			WM_IO_PA_07 
+ *			WM_IO_PA_14 only for 56pin 
+ *			WM_IO_PB_16 only for 56pin   
+ *			WM_IO_PB_26 only for 56pin     
+ *				
+ * @return None
+ */
+void wm_pwm4_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for pwm break
+ * @param  io_name: config pwm break pins name
+ *			WM_IO_PB_08
+ *			WM_IO_PA_05 only for 56pin 
+ *			WM_IO_PA_08 only for 56pin   
+ *			WM_IO_PA_15 only for 56pin 
+ *			WM_IO_PB_17 only for 56pin     
+ *				
+ * @return None
+ */
+void wm_pwmbrk_config(enum tls_io_name io_name);
+
+/**
+ * @brief  config the pins used for swd
+ * @param  enable: enable or disable chip swd function
+ *			1: enable
+ *			0: disable
+ *				
+ * @return None
+ */
+void wm_swd_config(bool enable);
+
+/**
+ * @brief  config the pins used for adc
+ * @param  Channel: the channel that shall be used
+ *			0~1: single-ended input
+ *			2~3: single-ended input only for 56pin
+ *			0 and 1 can be used differential input
+ *			2 and 3 can be used differential input only for 56pin
+ *				
+ * @return None
+ */
+void wm_adc_config(u8 Channel);
+
+/**
+ * @brief  config the pins used for touch sensor
+ * @param  io_name: config touch sensor pins name
+ *			WM_IO_PA_07
+ *			WM_IO_PB_00
+ *			WM_IO_PB_01
+ *			WM_IO_PB_02
+ *			WM_IO_PB_03
+ *			WM_IO_PB_04
+ *			WM_IO_PB_05
+ *			WM_IO_PB_06
+ *			WM_IO_PB_07
+ *			WM_IO_PB_08
+ *			WM_IO_PB_09
+ *			WM_IO_PA_09 only for 56pin
+ *			WM_IO_PA_10 only for 56pin
+ *			WM_IO_PA_12 only for 56pin
+ *			WM_IO_PA_14 only for 56pin
+ *				
+ * @return None
+ * @note  If user use touch sensor function, firstly consider using WM_IO_PA_07 as TOUCH SENSOR pin.
+ */
+ void wm_touch_sensor_config(enum tls_io_name io_name);
+
+/**
+ * @brief  disable all the gpio af
+ *				
+ * @return None
+ *
+ * @note  This function must call before any others for configure 
+ * 		  gpio Alternate functions
+ */
+void wm_gpio_af_disable(void);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* end of WM_GPIO_AFSEL_H */
+

+ 289 - 0
include/driver/wm_hostspi.h

@@ -0,0 +1,289 @@
+/**
+ * @file    wm_hostspi.h
+ *
+ * @brief   host spi Driver Module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_HOST_SPI_H
+#define WM_HOST_SPI_H
+
+#include "wm_type_def.h"
+#include "list.h"
+#include "wm_osal.h"
+#include "wm_ram_config.h"
+
+
+#define SPI_USE_DMA
+
+#define SPI_DMA_CMD_MAX_SIZE    (0x20)
+#define SPI_DMA_BUF_MAX_SIZE	(8160)
+#define SPI_DMA_MAX_TRANS_SIZE	(4092)
+
+/**
+ *  error code.
+ */
+#define TLS_SPI_STATUS_OK		    (0)
+#define TLS_SPI_STATUS_EINVAL		(-1)
+#define TLS_SPI_STATUS_ENOMEM		(-2)
+#define TLS_SPI_STATUS_EBUSY		(-3)
+#define TLS_SPI_STATUS_ESHUTDOWN	(-4)
+#define TLS_SPI_STATUS_EPERM		(-5)
+#define TLS_SPI_STATUS_ECLKNOSUPPORT	(-6)
+#define TLS_SPI_STATUS_EMODENOSUPPORT	(-7)
+
+#define SPI_MASTER_FIFO_SIZE		(32)
+
+/**
+ *  the SPI master controller's configuration data.
+ */
+ /**    configuration data.    */
+#define SPI_CPHA			(0x01)  /** clock phase. */
+#define SPI_CPOL			(0x02)  /** clock polarity. */
+#define TLS_SPI_MODE_0			(0|0)   /** motorola mode. */
+#define TLS_SPI_MODE_1			(0|SPI_CPHA)
+#define TLS_SPI_MODE_2			(SPI_CPOL|0)
+#define TLS_SPI_MODE_3      (SPI_CPOL|SPI_CPHA)
+#define TLS_SPI_CS_LOW      0x00    /** chipselect active low. */
+#define TLS_SPI_CS_HIGH      0x01   /** chipselect active high. */
+#define TLS_SPI_FCLK_MIN      (1000)    /** minimum work clock rate(Hz). */
+#define TLS_SPI_FCLK_MAX      (APB_CLK/2)   /** maximum work clock rate(Hz). */
+
+
+/**    default configuration data.    */
+#define SPI_DEFAULT_SPEED      (2000000)    /** default clock rate is 2MHz. */
+#define SPI_DEFAULT_MODE      (TLS_SPI_MODE_0)  /** default mode MODE_0. */
+#define SPI_CS_ACTIVE_MODE      (TLS_SPI_CS_LOW)    /** default chipselect mode is active low. */
+#define SPI_CS_INACTIVE_MODE      (TLS_SPI_CS_HIGH)
+
+/** SPI transaction message status. */
+#define SPI_MESSAGE_STATUS_IDLE      (0)
+#define SPI_MESSAGE_STATUS_INPROGRESS      (1)
+#define SPI_MESSAGE_STATUS_DONE      (2)
+
+/**slave type*/
+#define SPI_SLAVE_FLASH		0   /**flash */
+#define SPI_SLAVE_CARD		1   /** SD card */
+#define SPI_SLAVE_CONTROL_PIN		0
+/**transfer type*/
+#define SPI_BYTE_TRANSFER			0   /**byte transfer*/
+#define SPI_WORD_TRANSFER			1   /**word transfer*/
+#define SPI_DMA_TRANSFER			2   /** DMA transfer */
+
+/**
+ *  a read/write buffer pair
+ *
+ *  SPI transfers always write the same number of bytes as they read.
+ *  If the transmit buffer is null, zeroes will be shifted out while
+ *  filling rx_buf. If the receive buffer is null, the data shifted in
+ *  will be discarded.
+ */
+struct tls_spi_transfer
+{
+    struct dl_list transfer_list;    /**< transfers are sequenced through
+                                          tls_spi_message.transfers. */
+
+    const void *tx_buf;    /**< data to be written, or NULL. */
+    void *rx_buf;              /**< data to be read, or NULL. */
+    u32 len;                    /**< size of rx and tx buffers (in bytes). */
+    u32 delay_usecs;       /**< microseconds to delay after this transfer. */
+};
+
+
+/**
+ *  one multi-segment SPI transaction
+ *
+ *  A struct tls_spi_message is used to execute an atomic sequence of data
+ *  transfers, each represented by a struct tls_spi_transfer.  The sequence
+ *  is "atomic" in the sense that no other spi_message may use that SPI bus
+ *  until that sequence completes.
+  */
+struct tls_spi_message
+{
+    struct dl_list queue;       /**< transaction messages are sequenced through
+                                     tls_spi_port.wait_queue. */
+
+    struct dl_list transfers;   /**< list of transfer segments in this transaction. */
+    void (*complete) (void *);  /**< called to report transaction completions. */
+    void *context;              /**< the argument to complete() when it's called. */
+    u32 status;                 /**< transaction message status. */
+};
+
+/**
+ *  driver structure to SPI master controller
+ *
+ *  This data structure presents the SPI master controller's configuration
+ *  data. The device attached to this SPI master controller share the same
+ *  transfer mode, chipselect mode and clock rate. And this structure maintains
+ *  a queue of tls_spi_message transactions and uses this tls_spi_message transaction
+ *  to access to the SPI device. For each such message it queues, it calls the message's
+ *  completion function when the transaction completes.
+ */
+struct tls_spi_port
+{
+    u32 speed_hz;               /**< clock rate to be used. */
+    u8 cs_active;               /**< chipselect mode, maybe active low or active
+                                   high. */
+    u8 mode;                    /**< SPI transfer mode: mode_0(CPHA=0, CHOL=0),
+                                   mode_1(CPHA=0, CHOL=1), mode_2(CPHA=1,
+                                   CHOL=0), mode_3(CPHA=1, CHOL=1). */
+    u8 reconfig;
+
+    struct dl_list wait_queue;  /**< wait list of transaction messages. */
+    tls_os_queue_t *lock;
+
+    tls_os_queue_t *msg_queue;  /**< notify the schedule thread that there's
+                                   transaction message queued. */
+    struct tls_spi_message *current_message;    /**< current transaction message
+                                                   in-progressing. */
+    u32 current_remaining_transfer; /**< remaining transfer segments count in
+                                       current transaction message. */
+
+    struct tls_spi_transfer *current_transfer;  /**< current transfer segment
+                                                   in-progressing. */
+    u32 current_remaining_bytes;    /**< remaining data length in current
+                                       transfer segment. */
+
+    u8 transtype;               /**< transfer type  */
+};
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup MASTERSPI_Driver_APIs MASTER SPI Driver APIs
+ * @brief MASTERSPI driver APIs
+ */
+
+/**
+ * @addtogroup MASTERSPI_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to initialize the SPI master driver.
+ *
+ * @param[in]      None
+ *
+ * @retval         TLS_SPI_STATUS_OK			if initialize success
+ * @retval         TLS_SPI_STATUS_EBUSY		if SPI is already initialized
+ * @retval         TLS_SPI_STATUS_ENOMEM		if malloc SPI memory fail
+ *
+ * @note           None
+ */
+int tls_spi_init(void);
+
+
+/**
+ * @brief          This function is used to setup the spi controller.
+ *
+ * @param[in]      mode         is CPOL and CPHA type defined in TLS_SPI_MODE_0 to TLS_SPI_MODE_3
+ * @param[in]      cs_active    is cs mode, defined as TLS_SPI_CS_LOW or TLS_SPI_CS_HIGH
+ * @param[in]      fclk            is spi clock,the unit is HZ.
+ *
+ * @retval         TLS_SPI_STATUS_OK			if setup success
+ * @retval         TLS_SPI_STATUS_EMODENOSUPPORT	if mode is not support
+ * @retval         TLS_SPI_STATUS_EINVAL			if cs_active is not support
+ * @retval         TLS_SPI_STATUS_ECLKNOSUPPORT	if fclk is not support
+ *
+ * @note           None
+ */
+int tls_spi_setup(u8 mode, u8 cs_active, u32 fclk);
+
+/**
+ * @brief          This function is used to synchronous write data by SPI.
+ *
+ * @param[in]      buf          data to be sent.
+ * @param[in]      len          data length.
+ *
+ * @retval         TLS_SPI_STATUS_OK			if write success.
+ * @retval         TLS_SPI_STATUS_EINVAL		if argument is invalid.
+ * @retval         TLS_SPI_STATUS_ENOMEM			if there is no enough memory.
+ * @retval         TLS_SPI_STATUS_ESHUTDOWN		if SPI driver does not installed.
+ *
+ * @note           None
+ */
+int tls_spi_write(const u8 * buf, u32 len);
+
+/**
+ * @brief          This function is used to synchronously read data from SPI.
+ *
+ * @param[in]      buf          is the buffer for saving SPI data.
+ * @param[in]      len          is the data length.
+ *
+ * @retval         TLS_SPI_STATUS_OK			if write success.
+ * @retval         TLS_SPI_STATUS_EINVAL		if argument is invalid.
+ * @retval         TLS_SPI_STATUS_ENOMEM			if there is no enough memory.
+ * @retval         TLS_SPI_STATUS_ESHUTDOWN		if SPI driver does not installed.
+ *
+ * @note           None
+ */
+int tls_spi_read(u8 * buf, u32 len);
+
+/**
+ * @brief          This function is used to synchronously write command and then read data from SPI.
+ *
+ * @param[in]      txbuf        is the write data buffer.
+ * @param[in]      n_tx         is the write data length.
+ * @param[in]      rxbuf        is the read data buffer.
+ * @param[in]      n_rx         is the read data length.
+ *
+ * @retval         TLS_SPI_STATUS_OK			if write success.
+ * @retval         TLS_SPI_STATUS_EINVAL		if argument is invalid.
+ * @retval         TLS_SPI_STATUS_ENOMEM		if there is no enough memory.
+ * @retval         TLS_SPI_STATUS_ESHUTDOWN		if SPI driver has not been installed.
+ *
+ * @note           None
+ */
+int tls_spi_read_with_cmd(const u8 * txbuf, u32 n_tx, u8 * rxbuf, u32 n_rx);
+
+/**
+ * @brief          This function is used to synchronous write 32bit command then write data from SPI.
+ *
+ * @param[in]      cmd                    is the command data.
+ * @param[in]      n_cmd                 is the command len,can not bigger than four
+ * @param[in]      txbuf                   is the write data buffer.
+ * @param[in]      n_tx                    is the write data length.
+ *
+ * @retval         TLS_SPI_STATUS_OK			if write success.
+ * @retval         TLS_SPI_STATUS_EINVAL		if argument is invalid.
+ * @retval         TLS_SPI_STATUS_ENOMEM			if there is no enough memory.
+ * @retval         TLS_SPI_STATUS_ESHUTDOWN		if SPI driver does not installed.
+ *
+ * @note           None
+ */
+int tls_spi_write_with_cmd(const u8 * cmd, u32 n_cmd, const u8 * txbuf, u32 n_tx);
+
+/**
+ * @brief          This function is used to set SPI transfer mode.
+ *
+ * @param[in]      type             is the transfer type.
+ *				                SPI_BYTE_TRANSFER ->byte transfer;
+ *	                        	SPI_WORD_TRANSFER ->word transfer;
+ *				                SPI_DMA_TRANSFER ->DMA transfer;
+
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_spi_trans_type(u8 type);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_HOST_SPI_H */

+ 253 - 0
include/driver/wm_hspi.h

@@ -0,0 +1,253 @@
+/**
+ * @file    wm_hspi.h
+ *
+ *
+ * @brief   High speed spi slave Module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef WM_HSPI_H
+#define WM_HSPI_H
+
+#include "wm_type_def.h"
+#include "wm_ram_config.h"
+
+#define HSPI_TX_MEM_MALLOC			0		/** tx mem dynamic malloc*/
+
+
+
+#define HSPI_INTERFACE_SPI			2		/** spi interface*/
+#define HSPI_INTERFACE_SDIO			3		/** sdio interface*/
+
+/**rx message*/
+#define HSPI_RX_CMD_MSG     1
+#define HSPI_RX_DATA_MSG    2
+
+/**spi/sdio buffer*/
+#define HSPI_TXBUF_NUM              2
+#define HSPI_TX_DESC_NUM            HSPI_TXBUF_NUM
+#define HSPI_RXBUF_NUM              3
+#define HSPI_RX_DESC_NUM            HSPI_RXBUF_NUM
+#define HSPI_TXBUF_SIZE             1500
+#define HSPI_RXBUF_SIZE             1500
+
+#define HSPI_TX_DESC_SIZE          sizeof(struct tls_hspi_tx_desc)
+#define HSPI_RX_DESC_SIZE          sizeof(struct tls_hspi_rx_desc)
+
+/*****************************************************************************
+ * sdio/hspi sram partition
+ ******************************************************************************/
+/* HSPI txbuf zone */
+#define HSPI_TXBUF_BASE_ADDR        ((u32)(SLAVE_HSPI_SDIO_ADDR))
+
+#if HSPI_TX_MEM_MALLOC
+#define HSPI_TXBUF_TOTAL_SIZE        0
+#else
+#define HSPI_TXBUF_TOTAL_SIZE        (HSPI_TXBUF_SIZE * HSPI_TXBUF_NUM)
+#endif
+/** HSPI tx desc zone */
+#define HSPI_TX_DESC_BASE_ADDR      ((u32)(HSPI_TXBUF_BASE_ADDR + HSPI_TXBUF_TOTAL_SIZE))
+#define HSPI_TX_DESC_TOTAL_SIZE     (HSPI_TX_DESC_SIZE * HSPI_TX_DESC_NUM)	//28*3=84
+/** HSPI rxbuf zone */
+#define HSPI_RXBUF_BASE_ADDR        ((u32)(HSPI_TX_DESC_BASE_ADDR + HSPI_TX_DESC_TOTAL_SIZE))
+#define HSPI_RXBUF_TOTAL_SIZE       (HSPI_RXBUF_NUM * HSPI_RXBUF_SIZE)	//4500
+/** HSPI rx desc zone */
+#define HSPI_RX_DESC_BASE_ADDR      ((u32)(HSPI_RXBUF_BASE_ADDR + HSPI_RXBUF_TOTAL_SIZE))
+#define HSPI_RX_DESC_TOTAL_SIZE     (HSPI_RX_DESC_SIZE * HSPI_RX_DESC_NUM)	//36
+
+#define SDIO_CIS_SIZE (0x80)
+#define SDIO_CMD_RXBUF_SIZE          256
+
+
+#define SDIO_CIS0_ADDR              (HSPI_RX_DESC_BASE_ADDR + HSPI_RX_DESC_TOTAL_SIZE)	//128
+#define SDIO_CIS1_ADDR              (SDIO_CIS0_ADDR + SDIO_CIS_SIZE)						//128
+#define SDIO_CMD_RXBUF_ADDR          (SDIO_CIS1_ADDR + SDIO_CIS_SIZE)
+
+
+#define CIS_FUN0_ADDR				((u32)SDIO_CIS0_ADDR)
+#define CIS_FUN1_ADDR				((u32)SDIO_CIS1_ADDR)
+
+#define FN0_TPL_FUNCID				(CIS_FUN0_ADDR + 0x00)
+#define FN0_TPL_FUNCE				(CIS_FUN0_ADDR + 0x04)
+#define FN0_TPL_FUNCE_MAXBLK		(CIS_FUN0_ADDR + 0x08)
+#define FN0_TPL_MANFID_MID		    (CIS_FUN0_ADDR + 0x0C)
+#define FN0_TPL_END					(CIS_FUN0_ADDR + 0x10)
+
+#define FN1_TPL_FUNCID				(CIS_FUN1_ADDR + 0x00)
+#define FN1_TPL_FUNCE				(CIS_FUN1_ADDR + 0x04)
+#define FN1_TPL_FUNCE_VER			(CIS_FUN1_ADDR + 0x08)
+#define FN1_TPL_FUNCE_NSN			(CIS_FUN1_ADDR + 0x0C)
+#define FN1_TPL_FUNCE_CSASIZE		(CIS_FUN1_ADDR + 0x10)
+#define FN1_TPL_FUNCE_OCR			(CIS_FUN1_ADDR + 0x14)
+#define FN1_TPL_FUNCE_MINPWR		(CIS_FUN1_ADDR + 0x18)
+#define FN1_TPL_FUNCE_STANDBY		(CIS_FUN1_ADDR + 0x1C)
+#define FN1_TPL_FUNCE_OPTBW		    (CIS_FUN1_ADDR + 0x20)
+#define FN1_TPL_FUNCE_NTIMEOUT	    (CIS_FUN1_ADDR + 0x24)
+#define FN1_TPL_FUNCE_AVGPWR		(CIS_FUN1_ADDR + 0x28)
+#define FN1_TPL_END					(CIS_FUN1_ADDR + 0x30)
+
+
+
+/** SDIO interrupt bit definition */
+#define SDIO_WP_INT_SRC_CMD_DOWN         (1UL<<3)
+#define SDIO_WP_INT_SRC_CMD_UP           (1UL<<2)
+#define SDIO_WP_INT_SRC_DATA_DOWN        (1UL<<1)
+#define SDIO_WP_INT_SRC_DATA_UP          (1UL<<0)
+
+
+/** Definition of send data  descriptor structure */
+struct tls_hspi_tx_desc {
+    volatile u32 valid_ctrl;
+    u32 buf_info;
+    u32 buf_addr[3];
+    u32 next_desc_addr;
+#if HSPI_TX_MEM_MALLOC
+    u32 txbuf_addr;    /**< txbuf addr, pbuf and buf_addr[0] are different */
+#endif
+};
+
+/** Definition of receive data  descriptor structure */
+struct tls_hspi_rx_desc {
+    u32 valid_ctrl;
+    u32 buf_addr;
+    u32 next_desc_addr;
+};
+
+
+/** struct tls_slave_hspi */
+struct tls_slave_hspi {
+    u8 ifusermode;
+
+    s16 (*rx_cmd_callback)(char *buf);
+
+    s16 (*rx_data_callback)(char *buf);
+
+    s16 (*tx_data_callback)(char *buf);
+
+    struct tls_hspi_tx_desc *curr_tx_desc;    /**< Upstream data management */
+
+    struct tls_hspi_rx_desc   *curr_rx_desc;    /**< Downlink data management */
+
+#if HSPI_TX_MEM_MALLOC
+	u8 txdoneflag;		                        /**< tx done falg*/
+#endif
+};
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup HSPI_Driver_APIs HSPI Driver APIs
+ * @brief HSPI driver APIs
+ */
+
+/**
+ * @addtogroup HSPI_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to initial HSPI register.
+ *
+ * @param[in]      None
+ *
+ * @retval         0     success
+ * @retval         other failed
+ *
+ * @note           When the system is initialized, the function has been called, so users can not call this function.
+ */
+int tls_slave_spi_init(void);
+
+/**
+ * @brief          This function is used to enable or disable user mode.
+ *
+ * @param[in]      ifenable     TRUE or FALSE
+ *
+ * @return         None
+ *
+ * @note           If the user enables the user mode, RICM instruction in the system will not be used by SPI.
+ *		        If the user wants to use the SPI interface as other use, need to enable the user mode.
+ *		        This function must be called before the register function.
+ */
+void tls_set_hspi_user_mode(u8 ifenable);
+
+
+/**
+ * @brief          This function is used to set high speed interface type.
+ *
+ * @param[in]      type    is the interface type. HSPI_INTERFACE_SPI or HSPI_INTERFACE_SDIO
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_set_high_speed_interface_type(int type);
+
+
+/**
+ * @brief          This function is used to register hspi rx command interrupt.
+ *
+ * @param[in]      rx_cmd_callback		is the hspi rx interrupt call back function.
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_hspi_rx_cmd_callback_register(s16 (*rx_cmd_callback)(char *buf));
+
+
+/**
+ * @brief          This function is used to register hspi rx data interrupt.
+ *
+ * @param[in]      rx_data_callback		is the hspi rx interrupt call back function.
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_hspi_rx_data_callback_register(s16 (*rx_data_callback)(char *buf));
+
+/**
+ * @brief          This function is used to register hspi tx data interrupt.
+ *
+ * @param[in]      tx_data_callback		is the hspi tx interrupt call back function.
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_hspi_tx_data_callback_register(s16 (*tx_data_callback)(char *buf));
+
+
+/**
+ * @brief          This function is used to transfer data.
+ *
+ * @param[in]      txbuf			is a buf for saving user data.
+ * @param[in]      len                 is the data length.
+ *
+ * @retval         transfer data len     success
+ * @retval         0                          failed
+ *
+ * @note           None
+ */
+int tls_hspi_tx_data(char *txbuf, int len);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_HSPI_H */

+ 140 - 0
include/driver/wm_i2c.h

@@ -0,0 +1,140 @@
+/**************************************************************************//**
+ * @file     wm_i2c.h
+ * @author
+ * @version
+ * @date
+ * @brief
+ * @copyright (c) 2014 Winner Microelectronics Co., Ltd. All rights reserved.
+ *****************************************************************************/
+
+#ifndef __WM_I2C_H
+#define __WM_I2C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "wm_regs.h"
+#include "wm_type_def.h"
+#include "wm_cpu.h"
+#include "wm_irq.h"
+
+typedef struct 
+{	
+	__IO uint32_t PRER_LO;	
+	__IO uint32_t PRER_HI;	
+	__IO uint32_t CTRL;	
+	__O  uint32_t TX_RX;	
+	__O  uint32_t CR_SR;	
+	__I  uint32_t TXR;	
+	__I  uint32_t CR;
+}I2C_T;
+#define I2C		((I2C_T *)(HR_I2C_BASE_ADDR))
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup I2C_Driver_APIs I2C Driver APIs
+ * @brief I2C driver APIs
+ */
+
+/**
+ * @addtogroup I2C_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief	Init the I2C module
+ * @param freq   I2C reference clock frequency in Hz that will be used
+ * @note
+ *   the value must be between 100k and 400k
+ */
+void tls_i2c_init(u32 freq);
+
+/** I2C initialization mask */
+#define  wm_i2c_int_mask(bl)   do { tls_bitband_write(HR_I2C_CTRL, 6, bl);}while(0);
+
+/**
+ * @brief	send stop signal
+ *
+ */
+void tls_i2c_stop(void);
+
+/**
+ * @brief	Waiting for ack signal
+ * @retval
+ *	- \ref WM_FAILED
+ *	- \ref WM_SUCCESS
+ */
+int tls_i2c_wait_ack(void);
+
+/**
+ * @brief	Writes the data to data register of I2C module
+ * when ifstart one the start signal will be sent followed by the data
+ * when ifstart zero only the data will be send
+ * @param[in] data	the data will be write to the data register of I2C module
+ * @param[in] ifstart	when one send start signal, when zero don't
+ * @retval
+ *
+ */
+void tls_i2c_write_byte(u8 data, u8 ifstart);
+
+/**
+ * @brief	Get the data stored in data register of I2C module
+ * @param[in] ifack	when one send ack after reading the data register,when zero don't
+ * @param[in] ifstop	when one send stop signal after read, when zero do not send stop
+ * @retval
+ *	the received data
+ */
+u8 tls_i2c_read_byte(u8 ifack, u8 ifstop);
+
+/**
+ * @brief          This function is used to register i2c transfer done callback function.
+ * @param[in]      done  is the i2c transfer done callback function.
+ * @retval         None
+ * @note           None
+ */
+void wm_i2c_transfer_done_register(void (*done)(void));
+
+/**
+ * @brief	Start writing through int mode
+ * @param[in] devaddr	the device address 
+ * @param[in] wordaddr when one send stop signal after read, when zero do not send stop
+ * @param[in] buf	the address point where data shoule be stored
+ * @param[in] len	the length of data will be received 
+ * @retval	
+ *	- \ref WM_FAILED
+ *	- \ref WM_SUCCESS
+ */
+int wm_i2c_start_write_it(uint8_t devaddr, uint8_t wordaddr, uint8_t * buf, uint16_t len);
+
+/**
+ * @brief	Get the data stored in data register of I2C module
+ * @param[in] ifack	when one send ack after reading the data register,when zero don't
+ * @param[in] ifstop when one send stop signal after read, when zero do not send stop
+ * @retval	the received data 
+ */
+int wm_i2c_start_read_it(uint8_t devaddr, uint8_t wordaddr, uint8_t * buf, uint16_t len);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*** (C) COPYRIGHT 2014 Winner Microelectronics Co., Ltd. ***/

+ 300 - 0
include/driver/wm_i2s.h

@@ -0,0 +1,300 @@
+#ifndef __WM_I2S_H
+#define __WM_I2S_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+	
+#include <stdbool.h>
+//#include "wm_regs_cm3.h"
+#include "wm_regs.h"
+#include "wm_debug.h"
+#include "wm_dma.h"
+
+
+typedef void (*tls_i2s_callback)(uint32_t *data, uint16_t *len);
+
+typedef struct {
+	__IO uint32_t CTRL;
+	__IO uint32_t INT_MASK;
+	__IO uint32_t INT_SRC;
+	__I  uint32_t INT_STATUS;
+	__O  uint32_t TX;
+	__I	 uint32_t RX;
+} I2S_T;
+
+
+typedef struct {
+	uint32_t I2S_Mode_MS; //master or slave mode
+	uint32_t I2S_Mode_SS; //stereo or single channel
+	uint32_t I2S_Mode_LR; //left or right channel
+	uint32_t I2S_Trans_STD;
+	uint32_t I2S_DataFormat;
+	uint32_t I2S_AudioFreq;
+	uint32_t I2S_MclkFreq;
+} I2S_InitDef;
+
+typedef struct _wm_dma_desc
+{
+	unsigned int valid;
+	unsigned int dma_ctrl;
+	unsigned int src_addr;
+	unsigned int dest_addr;
+	struct _wm_dma_desc * next;
+}wm_dma_desc;
+
+typedef struct _dma_handler_type
+{
+	uint8_t channel;
+	void    (* XferCpltCallback)( struct _dma_handler_type * hdma);         /*!< DMA transfer complete callback         */
+	void    (* XferHalfCpltCallback)( struct _dma_handler_type * hdma);     /*!< DMA Half transfer complete callback    */
+}wm_dma_handler_type;
+
+#define I2S			            ((I2S_T *)HR_I2S_REG_BASE)
+
+#define I2S_MODE_MASTER		    ((bool)0x0)
+#define I2S_MODE_SLAVE		    ((bool)0x1)
+
+#define I2S_RIGHT_CHANNEL		((bool)0x0)
+#define I2S_LEFT_CHANNEL		((bool)0x1)
+
+#define I2S_Standard			(0x0UL)
+#define I2S_Standard_MSB		(0x1000000UL)
+#define I2S_Standard_PCMA		(0x2000000UL)
+#define I2S_Standard_PCMB		(0x3000000UL)
+
+#define I2S_DataFormat_8		(8)
+#define I2S_DataFormat_16		(16)
+#define I2S_DataFormat_24		(24)
+#define I2S_DataFormat_32		(32)	
+
+#define I2S_CTRL_CHSEL_MASK		(1UL<<23)
+#define I2S_CTRL_CHSEL_LEFT		(1UL<<23)
+#define I2S_CTRL_MONO			(1UL<<22)
+#define I2S_CTRL_STEREO			(0UL<<22)
+#define I2S_CTRL_RXDMA_EN		(1UL<<21)
+#define I2S_CTRL_TXDMA_EN		(1UL<<20)
+#define I2S_CTRL_RX_CLR			(1UL<<19)
+#define I2S_CTRL_TX_CLR			(1UL<<18)
+#define I2S_CTRL_LZCEN			(1UL<<17)
+#define I2S_CTRL_RZCEN			(1UL<<16)
+#define I2S_CTRL_RXTH(n)		((n-1)<<12)
+#define I2S_CTRL_TXTH(n)		((n)<<9)
+#define I2S_CTRL_SLAVE_SEL		(1UL<<8)
+#define I2S_CTRL_MUTE			(1UL<<3)
+#define I2S_CTRL_RXE			(1UL<<2)
+#define I2S_CTRL_TXE			(1UL<<1)
+#define I2S_CTRL_EN				(1UL<<0)
+
+#define I2S_INT_MASK_LZC		((uint16_t)0x200)
+#define I2S_INT_MASK_RZC		((uint16_t)0x100)
+#define I2S_INT_MASK_TXDONE		((uint16_t)0x080)
+#define I2S_INT_MASK_TXTH		((uint16_t)0x040)
+#define I2S_INT_MASK_TXOV		((uint16_t)0x020)
+#define I2S_INT_MASK_TXUD		((uint16_t)0x010)
+#define I2S_INT_MASK_RXDONE		((uint16_t)0x008)
+#define I2S_INT_MASK_RXTH		((uint16_t)0x004)
+#define I2S_INT_MASK_RXOV		((uint16_t)0x002)
+#define I2S_INT_MASK_RXUD		((uint16_t)0x002)
+
+#define I2S_FLAG_TX					((uint16_t)0x1000)
+#define I2S_FLAG_RX					((uint16_t)0x0800)
+#define I2S_FLAG_I2S				((uint16_t)0x0400)
+#define I2S_FLAG_LZC				((uint16_t)0x0200)
+#define I2S_FLAG_RZC				((uint16_t)0x0100)
+#define I2S_FLAG_TXDONE				((uint16_t)0x0080)
+#define I2S_FLAG_TXTH				((uint16_t)0x0040)
+#define I2S_FLAG_TXOV				((uint16_t)0x0020)
+#define I2S_FLAG_TXUD				((uint16_t)0x0010)
+#define I2S_FLAG_RXDONE				((uint16_t)0x0008)
+#define I2S_FLAG_RXTH				((uint16_t)0x0004)
+#define I2S_FLAG_RXOV				((uint16_t)0x0002)
+#define I2S_FLAG_RXUD				((uint16_t)0x0001)
+
+#define WM_I2S_TX_DMA_CHANNEL       (1)
+#define WM_I2S_RX_DMA_CHANNEL       (5)
+
+
+typedef struct wm_i2s_buf_s {
+	volatile uint32_t *txbuf;
+	volatile uint32_t txlen;
+	volatile uint32_t txtail;
+	volatile uint32_t *rxbuf;
+	volatile uint32_t rxlen;
+	volatile uint32_t int_txlen;
+	volatile uint32_t rxhead;
+	volatile uint8_t rxdata_ready;
+	volatile uint8_t txdata_done;
+
+	/** function pointer for data receiver  */
+    void (*rx_callback)(void);
+    /** function pointer for data transmit  */
+    void (*tx_callback)(uint32_t *data, uint16_t *len);
+} wm_i2s_buf_t;
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup I2S_Driver_APIs I2S Driver APIs
+ * @brief I2S driver APIs
+ */
+
+/**
+ * @addtogroup I2S_Driver_APIs
+ * @{
+ */
+
+/**
+  * @brief Register a callback function
+  * @param  callback pointer to a callback function in which you can prepare the next buffer
+  * @param  callback->data  pointer to data buffer to be prepared
+  * @param  callback->len size of the data buffer to be prepared in 32-bit
+  * @note The registerred callback function will be called as long as the transmission begins
+  * @retval none
+  */
+void wm_i2s_register_callback(tls_i2s_callback callback);
+
+/**
+  * @brief Initializes the I2S according to the specified parameters
+  *         in the I2S_InitDef.
+  * @param  opts pointer to a I2S_InitDef structure that contains
+  *         the configuration information for I2S module
+  * @retval status
+  */
+int wm_i2s_port_init(I2S_InitDef *opts);
+
+/**
+  * @brief stop i2s module
+  * @retval none
+  */
+void wm_i2s_tx_rx_stop(void);
+
+/**
+  * @brief Transmit an amount of data in blocking mode with Interrupt
+  * @param data a 16-bit pointer to data buffer.
+  * @param len number of data sample to be sent:
+  * @param next_data a 16-bit pointer to the next data buffer, same size with data; set to NULL if it's not needed
+  * @note  the len parameter means the number of 16-bit data length.
+  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+  *       between Master and Slave(example: audio streaming).
+  * @note This function will block its task until the transmission is over,so perpare the next data
+  *       buffer at another task during this interval.
+  * @note This function will call the registerred callback function as long as the transmission begins
+  * @retval status
+  */
+int wm_i2s_tx_int(int16_t *data, uint16_t len, int16_t *next_data);
+
+/**
+  * @brief Transmit an amount of data in blocking mode with DMA's normal mode
+  * @param data a 16-bit pointer to data buffer.
+  * @param len number of data sample to be sent:
+  * @param next_data a 16-bit pointer to the next data buffer, same size with data; set to NULL if it's not needed
+  * @note  the len parameter means the number of 32-bit data length.
+  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+  *       between Master and Slave(example: audio streaming).
+  * @note This function will block its task until the transmission is over,so perpare the next data
+  *       buffer at another task during this interval.
+  * @note This function will call the registerred callback function as long as the transmission begins
+  * @retval status
+  */
+int wm_i2s_tx_dma(int16_t *data, uint16_t len, int16_t *next_data);
+
+/**
+  * @brief Transmit an amount of data in blocking mode with DMA's link mode
+  * @param data a 16-bit pointer to data buffer.
+  * @param len number of data sample to be sent:
+  * @param next_data a 16-bit pointer to the next data buffer, same size with data:
+  * @note  the len parameter means the number of 32-bit data length.
+  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+  *       between Master and Slave(example: audio streaming).
+  * @note This function will block its task until the transmission is over,so perpare the next data
+  *       buffer at another task during this interval.Set len to 0xffff will exit this rountine.
+  * @note This function will call the registerred callback function as long as the data or next_data
+  *       is sent out.So prepare it in the callback.
+  * @note See the demo for detail use.
+  * @retval status
+  */
+int wm_i2s_tx_dma_link(int16_t *data, uint16_t len, int16_t *next_data);
+
+/**
+  * @brief Receive an amount of data in blocking mode with Interrupt
+  * @param data a 16-bit pointer to the Receive data buffer.
+  * @param len number of data sample to be received:
+  * @note the len parameter means the number of 16-bit data length.
+  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+  *       between Master and Slave(example: audio streaming).
+  * @note This function will block its task until the transmission is over,so perpare the next data
+  *       buffer at another task during this interval.
+  * @retval status
+  */
+int wm_i2s_rx_int(int16_t *data, uint16_t len);
+
+/**
+  * @brief Receive an amount of data in blocking mode with DMA
+  * @param data a 16-bit pointer to the Receive data buffer.
+  * @param len number of data sample to be received:
+  * @note the len parameter means the number of 16-bit data length.
+  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+  *       between Master and Slave(example: audio streaming).
+  * @note This function will block its task until the transmission is over,so perpare the next data
+  *       buffer at another task during this interval.
+  * @retval status
+  */
+int wm_i2s_rx_dma(int16_t *data, uint16_t len);
+
+/**
+  * @brief Full-Duplex Transmit/Receive data in blocking mode using Interrupt
+  * @param  opts pointer to a I2S_InitDef structure that contains
+  *         the configuration information for I2S module
+  * @param data_tx a 16-bit pointer to the Transmit data buffer.
+  * @param data_rx a 16-bit pointer to the Receive data buffer.
+  * @param len number of data sample to be sent:
+  * @note  the len parameter means the number of 16-bit data length.
+  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+  *       between Master and Slave(example: audio streaming).
+  * @note This function will block its task until the transmission is over,so perpare the next data
+  *       buffer at another task during this interval.
+  * @retval status
+  */
+int wm_i2s_tx_rx_int(I2S_InitDef *opts, int16_t *data_tx, int16_t *data_rx, uint16_t len);
+
+/**
+  * @brief Full-Duplex Transmit/Receive data in blocking mode using DMA
+  * @param  opts pointer to a I2S_InitDef structure that contains
+  *         the configuration information for I2S module
+  * @param data_tx a 16-bit pointer to the Transmit data buffer.
+  * @param data_rx a 16-bit pointer to the Receive data buffer.
+  * @param len number of data sample to be sent:
+  * @note  the len parameter means the number of 16-bit data length.
+  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+  *       between Master and Slave(example: audio streaming).
+  * @note This function will block its task until the transmission is over,so perpare the next data
+  *       buffer at another task during this interval.
+  * @retval status
+  */
+int wm_i2s_tx_rx_dma(I2S_InitDef *opts, int16_t *data_tx, int16_t *data_rx, uint16_t len);
+
+int wm_i2s_transmit_dma(wm_dma_handler_type *hdma, uint16_t *data, uint16_t len);
+int wm_i2s_receive_dma(wm_dma_handler_type *hdma, uint16_t *data, uint16_t len);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus 
+}
+#endif
+
+#endif

+ 328 - 0
include/driver/wm_internal_flash.h

@@ -0,0 +1,328 @@
+/**
+ * @file    wm_internal_flash.h
+ *
+ * @brief  inter flash driver
+ *
+ * @author  dave
+ *
+ * @copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef WM_INTERNAL_FLASH_H
+#define WM_INTERNAL_FLASH_H
+
+#include "wm_type_def.h"
+#include "wm_osal.h"
+
+typedef volatile unsigned char vu8;
+typedef volatile unsigned short vu16;
+typedef volatile unsigned long vu32;
+
+#define M8(adr)		(*((vu8 *) (adr)))
+#define M16(adr)	(*((vu16*) (adr)))
+#define M32(adr)	(*((vu32*) (adr)))
+
+
+#define INSIDE_FLS_SECTOR_SIZE	0x1000
+#define INSIDE_FLS_PAGE_SIZE	256
+
+
+#define INSIDE_FLS_BASE_ADDR		0x8000000UL
+#define INSIDE_FLS_SECBOOT_ADDR 	(INSIDE_FLS_BASE_ADDR  + 0x02000)
+
+
+
+enum TYPE_FLASH_ID{
+	SPIFLASH_MID_GD = 0xC8,
+	SPIFLASH_MID_ESMT = 0x1C,
+	SPIFLASH_MID_PUYA = 0x85,	
+	SPIFLASH_MID_WINBOND = 0xEF,	
+	SPIFLASH_MID_FUDANMICRO = 0xA1,
+	SPIFLASH_MID_BOYA       = 0x68,
+	SPIFLASH_MID_XMC		= 0x20,
+	SPIFLASH_MID_XTX        = 0x0B,
+	SPIFLASH_MID_TSINGTENG    = 0xEB, /*UNIGROUP TSINGTENG*/	
+};
+
+typedef union {
+    struct {
+        uint32_t _reserved0: 1;               /*!< bit:  0  Reserved */
+        uint32_t code_decrypt: 1;             /*!< bit:  1      read code from AHB decrypt flag */
+        uint32_t dbus_decrypt: 1;             /*!< bit:  2  	read data from Flash register controller decrypt flag */
+        uint32_t data_decrypt: 1;             /*!< bit:  3      read data from AHB decrypt flag */
+        uint32_t prikey_sel: 3;               /*!< bit:  4.. 6   private key selection: 0 : first one; 1 : second one; */
+        uint32_t decrypt_start: 1;            /*!< bit:  7   write 1 to start RSA decryption operation */
+        uint32_t _reserved2: 24;              /*!< bit:  8.. 31  Reserved */
+    } b;                                   /*!< Structure    Access by bit */
+    uint32_t w;                            /*!< Type         Access by whole register */
+} FLASH_ENCRYPT_CTRL_Type;
+
+
+/**
+ * @typedef struct    Flash Registers
+ */
+typedef struct
+{
+    vu32 ACR;                   /**< offset 0x000 */
+    vu32 KEYR;                 /**< offset 0x004 */
+    vu32 SR;                     /**< offset 0x008 */
+    vu32 CR;                     /**< offset 0x00C */
+    vu32 AR;                     /**< offset 0x010 */
+} FLASH_TypeDef;
+
+#define FLASH_HS				0x00000001
+
+ /** Flash Keys */
+#define RDPRT_KEY       0x5AA5
+#define FLASH_KEY1      0x57696E6E
+#define FLASH_KEY2      0x65724D69
+#define FLASH_KEY3			0x63726F21
+
+ /** Flash Control Register definitions */
+#define FLASH_PG        0x00000001
+#define FLASH_PER       0x00000002
+#define FLASH_MER       0x00000004
+#define FLASH_STRT			0x00000008
+#define FLASH_LOCK   	  0x00000020
+#define FLASH_ERRIE     0x00000040
+#define FLASH_EOPIE     0x00000080
+
+ /** Flash Status Register definitions */
+#define FLASH_BSY       0x00000001
+#define FLASH_PGERR     0x00000002
+#define FLASH_EOP       0x00000004
+
+
+#define TLS_FLS_STATUS_OK      (0)
+#define TLS_FLS_STATUS_EINVAL      (1)
+#define TLS_FLS_STATUS_EBUSY      (2)
+#define TLS_FLS_STATUS_EPERM      (3)
+#define TLS_FLS_STATUS_ENOSUPPORT      (4)
+#define TLS_FLS_STATUS_EEXIST      (5)
+#define TLS_FLS_STATUS_ENOMEM      (6)
+#define TLS_FLS_STATUS_EOVERFLOW      (7)
+#define TLS_FLS_STATUS_ENODEV      (8)
+#define TLS_FLS_STATUS_EDEV      (9)
+#define TLS_FLS_STATUS_EIO      (10)
+#define TLS_FLS_STATUS_ENODRV      (11)
+
+#define TLS_FLS_PARAM_TYPE_ID      (0)
+#define TLS_FLS_PARAM_TYPE_SIZE      (1)
+#define TLS_FLS_PARAM_TYPE_PAGE_SIZE      (2)
+#define TLS_FLS_PARAM_TYPE_PROG_SIZE      (3)
+#define TLS_FLS_PARAM_TYPE_SECTOR_SIZE      (4)
+
+#define TLS_FLS_FLAG_UNDER_PROTECT      (1<<0)
+#define TLS_FLS_FLAG_FAST_READ      (1<<1)
+#define TLS_FLS_FLAG_AAAI      (1<<2)
+
+#define CMD_START_Pos                         8U                                          /*!< CMD start position */
+#define CMD_START_Msk                         (1UL << CMD_START_Pos)                         /*!< CMD start Mask */
+
+
+typedef struct {
+	uint16_t eraseSize;
+	uint16_t pageSize;
+} FLASH_OTP_WR_PARAM_ST;
+
+/**
+ * @struct tls_inside_fls
+ */
+struct tls_inside_fls
+{
+    tls_os_sem_t *fls_lock;
+	unsigned char flashid;
+	unsigned int density;
+	FLASH_OTP_WR_PARAM_ST OTPWRParam;
+};
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup INNER_FLASH_Driver_APIs INNER FLASH Driver APIs
+ * @brief INNER FLASH driver APIs
+ */
+
+/**
+ * @addtogroup INNER_FLASH_Driver_APIs
+ * @{
+ */
+
+
+/**
+ * @brief          This function is used to unlock flash protect area [0x0~0x2000].
+ *
+ * @param	       None	 
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+int tls_flash_unlock(void);
+
+/**
+ * @brief          This function is used to lock flash protect area [0x0~0x2000].
+ *
+ * @param	       None	 
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+int tls_flash_lock(void);
+
+
+/**
+ * @brief          This function is used to get the flash semaphore.
+ *
+ * @param	       None	 
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_fls_sem_lock(void);
+
+/**
+ * @brief          This function is used to release the flash semaphore.
+ *
+ * @param	       None	 
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_fls_sem_unlock(void);
+
+/**
+ * @brief          This function is used to read the unique id of the internal flash.
+ *
+ * @param[out]      uuid                 Specified the address to save the uuid, the length must be greater than or equals to 18 bytes.
+ *
+ * @retval         TLS_FLS_STATUS_OK	    if read sucsess
+ * @retval         TLS_FLS_STATUS_EIO	    if read fail
+ *
+ * @note           The uuid's length must be greater than or equals to 18 bytes.
+ */
+int tls_fls_read_unique_id(unsigned  char *uuid);
+
+/**
+ * @brief          This function is used to initial flash module structer.
+ *
+ * @param[in]      None
+ *
+ * @retval         TLS_FLS_STATUS_OK	         if init sucsess
+ * @retval         TLS_FLS_STATUS_EBUSY          already inited
+ * @retval         TLS_FLS_STATUS_ENOMEM         memory error
+ *
+ * @note           None
+ */
+int tls_fls_init(void);
+
+/**
+ * @brief          This function is used to read data from the flash.
+ *
+ * @param[in]      addr                 Specifies the starting address to read from.
+ * @param[in]      buf                  Specified the address to save the readback data.
+ * @param[in]      len                  Specifies the length of the data to read.
+ *
+ * @retval         TLS_FLS_STATUS_OK	    if read sucsess
+ * @retval         TLS_FLS_STATUS_EIO	    if read fail
+ *
+ * @note           None
+ */
+int tls_fls_read(u32 addr, u8 * buf, u32 len);
+
+
+/**
+ * @brief          This function is used to write data into the flash.
+ *
+ * @param[in]      addr     Specifies the starting address to write to
+ * @param[in]      buf      Pointer to a byte array that is to be written
+ * @param[in]      len      Specifies the length of the data to be written
+ *
+ * @retval         TLS_FLS_STATUS_OK	        if write flash success
+ * @retval         TLS_FLS_STATUS_EPERM	        if flash struct point is null
+ * @retval         TLS_FLS_STATUS_ENODRV	    if flash driver is not installed
+ * @retval         TLS_FLS_STATUS_EINVAL	    if argument is invalid
+ * @retval         TLS_FLS_STATUS_EIO           if io error
+ *
+ * @note           None
+ */
+int tls_fls_write(u32 addr, u8 * buf, u32 len);
+
+
+/**
+ * @brief          	This function is used to erase the appointed sector
+ *
+ * @param[in]      	sector 	sector num of the flash, 4K bytes every sector	
+ *
+ * @retval         	TLS_FLS_STATUS_OK	    	if read sucsess
+ * @retval         	other	    				if read fail
+ *
+ * @note           	None
+ */
+int tls_fls_erase(u32 sector);
+
+/**
+ * @brief          	This function is used to initialize system parameter postion by flash density
+ *
+ * @param      	None
+ *
+ * @retval         	None
+ *
+ * @note           	must be called before tls_param_init
+ */
+void tls_fls_sys_param_postion_init(void);
+
+/**
+ * @brief          This function is used to read data from the security registers.
+ *
+ * @param[in]      addr                 Specifies the starting address to read from.
+ * @param[in]      buf                  Specified the address to save the readback data.
+ * @param[in]      len                  Specifies the length of the data to read.
+ *
+ * @retval         TLS_FLS_STATUS_OK	    if read sucsess
+ * @retval         TLS_FLS_STATUS_EPERM	        if flash struct point is null
+ *
+ * @note           None
+ */
+int tls_fls_otp_read(u32 addr, u8 *buf, u32 len);
+
+/**
+ * @brief          This function is used to write data into the security registers.
+ *
+ * @param[in]      addr     Specifies the starting address to write to
+ * @param[in]      buf      Pointer to a byte array that is to be written
+ * @param[in]      len      Specifies the length of the data to be written
+ *
+ * @retval         TLS_FLS_STATUS_OK	        if write the security registers success
+ * @retval         TLS_FLS_STATUS_EPERM	        if flash struct point is null
+ * @retval         TLS_FLS_STATUS_ENOSUPPORT	    if flash is not supported
+ * @retval         TLS_FLS_STATUS_EINVAL	    if argument is invalid
+ * @retval         TLS_FLS_STATUS_ENOMEN           if no memory
+ *
+ * @note           None
+ */
+int tls_fls_otp_write(u32 addr, u8 *buf, u32 len);
+
+/**
+ * @brief          This function is used to lock the security registers.
+ *
+ * @param	       None	 
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+int tls_fls_otp_lock(void);
+
+#endif /* WM_INTERNAL_FLASH_H */

+ 204 - 0
include/driver/wm_io.h

@@ -0,0 +1,204 @@
+/**
+ * @file    wm_io.h
+ *
+ * @brief   IO Driver Module
+ *
+ * @author  lilm
+ *
+ * @copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_IO_H
+#define WM_IO_H
+
+
+#define TLS_IO_AB_OFFSET  (0x40011400 - 0x40011200)
+
+/** io name */
+enum tls_io_name {
+    WM_IO_PA_00 = 0,    /**< gpio a0 */
+    WM_IO_PA_01,        /**< gpio a1 */
+    WM_IO_PA_02,        /**< gpio a2 */
+    WM_IO_PA_03,        /**< gpio a3 */
+    WM_IO_PA_04,        /**< gpio a4 */
+    WM_IO_PA_05,        /**< gpio a5 */
+    WM_IO_PA_06,        /**< gpio a6 */
+    WM_IO_PA_07,        /**< gpio a7 */
+    WM_IO_PA_08,        /**< gpio a8 */
+    WM_IO_PA_09,        /**< gpio a9 */
+    WM_IO_PA_10,        /**< gpio a10 */
+    WM_IO_PA_11,        /**< gpio a11 */
+    WM_IO_PA_12,        /**< gpio a12 */
+    WM_IO_PA_13,        /**< gpio a13 */
+    WM_IO_PA_14,        /**< gpio a14 */
+    WM_IO_PA_15,        /**< gpio a15 */
+
+    WM_IO_PB_00,        /**< gpio b0 */
+    WM_IO_PB_01,        /**< gpio b1 */
+    WM_IO_PB_02,        /**< gpio b2 */
+    WM_IO_PB_03,        /**< gpio b3 */
+    WM_IO_PB_04,        /**< gpio b4 */
+    WM_IO_PB_05,        /**< gpio b5 */
+    WM_IO_PB_06,        /**< gpio b6 */
+    WM_IO_PB_07,        /**< gpio b7 */
+    WM_IO_PB_08,        /**< gpio b8 */
+    WM_IO_PB_09,        /**< gpio b9 */
+    WM_IO_PB_10,        /**< gpio b10 */
+    WM_IO_PB_11,        /**< gpio b11 */
+    WM_IO_PB_12,        /**< gpio b12 */
+    WM_IO_PB_13,        /**< gpio b13 */
+    WM_IO_PB_14,        /**< gpio b14 */
+    WM_IO_PB_15,        /**< gpio b15 */
+    WM_IO_PB_16,        /**< gpio b16 */
+    WM_IO_PB_17,        /**< gpio b17 */
+    WM_IO_PB_18,        /**< gpio b18 */
+    WM_IO_PB_19,        /**< gpio b19 */
+    WM_IO_PB_20,        /**< gpio b20 */
+    WM_IO_PB_21,        /**< gpio b21 */
+    WM_IO_PB_22,        /**< gpio b22 */
+    WM_IO_PB_23,        /**< gpio b23 */
+    WM_IO_PB_24,        /**< gpio b24 */
+    WM_IO_PB_25,        /**< gpio b25 */
+    WM_IO_PB_26,        /**< gpio b26 */
+    WM_IO_PB_27,        /**< gpio b27 */
+    WM_IO_PB_28,        /**< gpio b28 */
+    WM_IO_PB_29,        /**< gpio b29 */
+    WM_IO_PB_30,        /**< gpio b30 */
+    WM_IO_PB_31			/**< gpio b31 */
+};
+
+/** option 1 of the io */
+#define WM_IO_OPTION1               1
+/** option 2 of the io */
+#define WM_IO_OPTION2               2
+/** option 3 of the io */
+#define WM_IO_OPTION3               3
+/** option 4 of the io */
+#define WM_IO_OPTION4               4
+/** option 5 of the io */
+#define WM_IO_OPTION5               5
+/** option 6 of the io */
+#define WM_IO_OPTION6               6
+/** option 7 of the io */
+#define WM_IO_OPTION7               7
+
+
+
+
+/* io option1 */
+#define WM_IO_OPT1_I2C_DAT          WM_IO_OPTION1
+#define WM_IO_OPT1_PWM1             WM_IO_OPTION1
+#define WM_IO_OPT1_PWM2             WM_IO_OPTION1
+#define WM_IO_OPT1_PWM3             WM_IO_OPTION1
+#define WM_IO_OPT1_PWM4             WM_IO_OPTION1
+#define WM_IO_OPT1_PWM5             WM_IO_OPTION1
+#define WM_IO_OPT1_UART0_RXD        WM_IO_OPTION1
+#define WM_IO_OPT1_UART0_TXD        WM_IO_OPTION1
+#define WM_IO_OPT1_PWM_BRAKE        WM_IO_OPTION1
+#define WM_IO_OPT1_I2S_M_EXTCLK     WM_IO_OPTION1
+#define WM_IO_OPT1_SPI_M_DO         WM_IO_OPTION1
+#define WM_IO_OPT1_SPI_M_DI         WM_IO_OPTION1
+#define WM_IO_OPT1_SPI_M_CS         WM_IO_OPTION1
+#define WM_IO_OPT1_SPI_M_CK         WM_IO_OPTION1
+#define WM_IO_OPT1_I2S_S_RL         WM_IO_OPTION1
+#define WM_IO_OPT1_I2S_S_SCL        WM_IO_OPTION1
+#define WM_IO_OPT1_I2S_S_SDA        WM_IO_OPTION1
+#define WM_IO_OPT1_I2S_M_RL         WM_IO_OPTION1
+#define WM_IO_OPT1_I2S_M_SCL        WM_IO_OPTION1
+#define WM_IO_OPT1_I2S_M_SDA        WM_IO_OPTION1
+#define WM_IO_OPT1_JTAG_RST         WM_IO_OPTION1
+#define WM_IO_OPT1_JTAG_TDO         WM_IO_OPTION1
+#define WM_IO_OPT1_JTAG_TDI         WM_IO_OPTION1
+#define WM_IO_OPT1_JTAG_TCK_SWDCK   WM_IO_OPTION1
+#define WM_IO_OPT1_JTAG_TMS_SWDAT   WM_IO_OPTION1
+#define WM_IO_OPT1_UART1_RXD        WM_IO_OPTION1
+#define WM_IO_OPT1_UART1_TXD        WM_IO_OPTION1
+#define WM_IO_OPT1_UART1_RTS        WM_IO_OPTION1
+#define WM_IO_OPT1_UART1_CTS        WM_IO_OPTION1
+#define WM_IO_OPT1_SDIO_DAT         WM_IO_OPTION1
+
+/* io option2 */
+#define WM_IO_OPT2_PWM1             WM_IO_OPTION2
+#define WM_IO_OPT2_PWM2             WM_IO_OPTION2
+#define WM_IO_OPT2_PWM3             WM_IO_OPTION2
+#define WM_IO_OPT2_PWM4             WM_IO_OPTION2
+#define WM_IO_OPT2_PWM5             WM_IO_OPTION2
+#define WM_IO_OPT2_SPI_M_DO         WM_IO_OPTION2
+#define WM_IO_OPT2_SPI_M_DI         WM_IO_OPTION2
+#define WM_IO_OPT2_SPI_M_CS         WM_IO_OPTION2
+#define WM_IO_OPT2_SPI_M_CK         WM_IO_OPTION2
+#define WM_IO_OPT2_I2C_SCL          WM_IO_OPTION2
+#define WM_IO_OPT2_I2S_M_EXTCLK     WM_IO_OPTION2
+#define WM_IO_OPT2_UART1_RXD        WM_IO_OPTION2
+#define WM_IO_OPT2_UART1_TXD        WM_IO_OPTION2
+#define WM_IO_OPT2_UART1_RTS        WM_IO_OPTION2
+#define WM_IO_OPT2_UART1_CTS        WM_IO_OPTION2
+#define WM_IO_OPT2_I2C_DAT          WM_IO_OPTION2
+#define WM_IO_OPT2_PWM_BRAKE        WM_IO_OPTION2
+#define WM_IO_OPT2_UART0_RTS        WM_IO_OPTION2
+#define WM_IO_OPT2_UART0_CTS        WM_IO_OPTION2
+#define WM_IO_OPT2_SDIO_DAT         WM_IO_OPTION2
+#define WM_IO_OPT2_HSPI_CK          WM_IO_OPTION2
+#define WM_IO_OPT2_HSPI_INT         WM_IO_OPTION2
+#define WM_IO_OPT2_HSPI_CS          WM_IO_OPTION2
+#define WM_IO_OPT2_HSPI_DI          WM_IO_OPTION2
+#define WM_IO_OPT2_HSPI_DO          WM_IO_OPTION2
+
+/* io option3 */
+#define WM_IO_OPT3_UART0_RXD        WM_IO_OPTION3
+#define WM_IO_OPT3_UART0_TXD        WM_IO_OPTION3
+#define WM_IO_OPT3_UART0_RTS        WM_IO_OPTION3
+#define WM_IO_OPT3_UART0_CTS        WM_IO_OPTION3
+#define WM_IO_OPT3_SPI_M_DO         WM_IO_OPTION3
+#define WM_IO_OPT3_SPI_M_DI         WM_IO_OPTION3
+#define WM_IO_OPT3_SPI_M_CS         WM_IO_OPTION3
+#define WM_IO_OPT3_SDIO_CK          WM_IO_OPTION3
+#define WM_IO_OPT3_SDIO_CMD         WM_IO_OPTION3
+#define WM_IO_OPT3_SDIO_DAT         WM_IO_OPTION3
+
+/* io option4 */
+#define WM_IO_OPT4_I2S_M_MCLK       WM_IO_OPTION4
+#define WM_IO_OPT4_I2S_M_RL         WM_IO_OPTION4
+#define WM_IO_OPT4_I2S_M_SCL        WM_IO_OPTION4
+#define WM_IO_OPT4_I2S_M_SDA        WM_IO_OPTION4
+
+/* io option5 */
+#define WM_IO_OPT5_GPIO             WM_IO_OPTION5
+
+/* io option6 */
+#define WM_IO_OPT6_ADC              WM_IO_OPTION6
+#define WM_IO_OPT6_LCD_COM          WM_IO_OPTION6
+#define WM_IO_OPT6_LCD_SEG          WM_IO_OPTION6
+
+
+/* io option7 */
+#define WM_IO_OPT7_TOUCH_SENSOR     WM_IO_OPTION7
+
+
+
+/**
+ * @brief          	This function is used to config io function
+ *
+ * @param[in]      	name      io name
+ * @param[in]      	option    io function option, value is WM_IO_OPT*_*, also is WM_IO_OPTION1~6
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_io_cfg_set(enum tls_io_name name, u8 option);
+
+
+/**
+ * @brief          	This function is used to get io function config 
+ *
+ * @param[in]      	name      io name
+ *
+ * @retval         	WM_IO_OPTION1~6  Mapping io function
+ *
+ * @note           	None
+ */
+int tls_io_cfg_get(enum tls_io_name name);
+
+
+#endif  /* end of WM_IO_H */
+

+ 118 - 0
include/driver/wm_irq.h

@@ -0,0 +1,118 @@
+/**
+ * @file    wm_irq.h
+ *
+ * @brief   interupt driver module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef WM_IRQ_H
+#define WM_IRQ_H
+
+#include "wm_type_def.h"
+
+typedef void (*intr_handler_func) (void *);
+
+/**
+ * @typedef struct tls_irq_handler
+ */
+typedef struct tls_irq_handler
+{
+    void (*handler) (void *);
+    void *data;
+    u32 counter;
+} tls_irq_handler_t;
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup IRQ_Driver_APIs IRQ Driver APIs
+ * @brief IRQ driver APIs
+ */
+
+/**
+ * @addtogroup IRQ_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to initial system interrupt.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_irq_init(void);
+
+/**
+ * @brief          This function is used to register interrupt handler function.
+ *
+ * @param[in]      vec_no           interrupt NO
+ * @param[in]      handler
+ * @param[in]      *data
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_irq_register_handler(u8 vec_no, intr_handler_func handler, void *data);
+
+
+/**
+ * @brief          This function is used to enable interrupt.
+ *
+ * @param[in]      vec_no       interrupt NO
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_irq_enable(u8 vec_no);
+
+/**
+ * @brief          This function is used to disable interrupt.
+ *
+ * @param[in]      vec_no       interrupt NO
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_irq_disable(u8 vec_no);
+
+
+/**
+ * @brief          This function is used to get the isr count.
+ *
+ * @param[in]      None
+ *
+ * @retval         count
+ *
+ * @note           None
+ */
+u8 tls_get_isr_count(void);
+
+void tls_irq_priority(u8 vec_no, u32 prio);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_IRQ_H */

+ 238 - 0
include/driver/wm_lcd.h

@@ -0,0 +1,238 @@
+/**
+ * @file    wm_lcd.h
+ *
+ * @brief   LCD Driver Module
+ *
+ * @author  dave
+ *
+ * @copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+
+#ifndef __WM_LCD_H
+#define __WM_LCD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "wm_regs.h"
+#include <stdbool.h>
+
+/**
+ * @brief LCD Register Declaration
+ *
+ */
+typedef struct
+{
+	/** Control Register */
+	__IO uint32_t CTRL;
+	/** Refresh Rate Prescaler Register */
+	__IO uint32_t FRAMECNT;
+	__IO uint32_t COM0;
+	__IO uint32_t COM1;
+	__IO uint32_t COM2;
+	__IO uint32_t COM3;
+	__IO uint32_t COM4;
+	__IO uint32_t COM5;
+	__IO uint32_t COM6;
+	__IO uint32_t COM7;
+	/** LCD COM Control Register */
+	__IO uint32_t COM_EN;
+	/** LCD SEG Control Register */
+	__IO uint32_t SEG_EN;
+} LCD_T;
+/** LCD base pointer */
+#define LCD 		((LCD_T *)HR_LCD_REG_BASE)
+
+typedef enum
+{
+	/** Static (2 levels) */
+	BIAS_STATIC		= LCD_BIAS_STATIC,
+	/** 1/2 Bias (3 levels) */
+	BIAS_ONEHALF 		= LCD_BIAS_ONEHALF,
+	/** 1/3 Bias (4 levels) */
+	BIAS_ONETHIRD 		= LCD_BIAS_ONETHIRD,
+	/** 1/4 Bias (4 levels) */
+	BIAS_ONEFOURTH	= LCD_BIAS_ONEFOURTH,
+} LCD_BiasDef;
+
+typedef enum
+{
+	/** VLCD 2.7v */
+	VLCD27		= LCD_VLCD_27,
+	/** VLCD 2.9v */
+	VLCD29		= LCD_VLCD_29,
+	/** VLCD 3.1v */
+	VLCD31		= LCD_VLCD_31,
+	/** VLCD 3.3v */
+	VLCD33		= LCD_VLCD_33,
+} LCD_VlcdDef;
+
+typedef enum
+{
+	/** Static (segments can be multiplexed with LCD_COM[0]) */
+	DUTY_STATIC		= LCD_DUTY_STATIC,
+	/**  1/2 Duty cycle (segments can be multiplexed with LCD_COM[0:1]) */
+	DUTY_ONEHALF		= LCD_DUTY_ONEHALF,
+	/**  1/3 Duty cycle (segments can be multiplexed with LCD_COM[0:2]) */
+	DUTY_ONETHIRD		= LCD_DUTY_ONETHIRD,
+	/**  1/4 Duty cycle (segments can be multiplexed with LCD_COM[0:3]) */
+	DUTY_ONEFOURTH	= LCD_DUTY_ONEFOURTH,
+	/**  1/5 Duty cycle (segments can be multiplexed with LCD_COM[0:4]) */
+	DUTY_ONEFIFTH	  	= LCD_DUTY_ONEFIFTH,
+	/**  1/6 Duty cycle (segments can be multiplexed with LCD_COM[0:5]) */
+	DUTY_ONESIXTH		= LCD_DUTY_ONESIXTH,
+	/**  1/7 Duty cycle (segments can be multiplexed with LCD_COM[0:6]) */
+	DUTY_ONESEVENTH	= LCD_DUTY_ONESEVENTH,
+	/**  1/8 Duty cycle (segments can be multiplexed with LCD_COM[0:7]) */
+	DUTY_ONEEIGHTH	= LCD_DUTY_ONEEIGHTH,
+} LCD_DutyDef;
+
+typedef struct tls_lcd_options
+{
+	/** */
+	bool enable;
+	/** Bias configuration */
+	LCD_BiasDef  bias;
+	/** Duty configuration */
+	LCD_DutyDef  duty;
+	/** Vlcd configuration */
+	LCD_VlcdDef  vlcd;
+	/** com number */
+	uint8_t	com_number;
+	/** Fresh rate configuration */
+	uint16_t fresh_rate;
+} tls_lcd_options_t;
+
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup LCD_Driver_APIs LCD Driver APIs
+ * @brief LCD driver APIs
+ */
+
+/**
+ * @addtogroup LCD_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief   Initialize  LCD Frame Counter
+ * @param[in] com_num   Number of the com
+ * @param[in] freq      LCD reference refresh frequency in Hz that will be used
+ */
+void tls_lcd_fresh_ratio(uint8_t com_num, uint16_t freq);
+
+/**
+ * @brief initialize the LCD module
+ *
+ */
+void tls_lcd_init(tls_lcd_options_t *opts);
+
+/**
+ * @brief   Initialize LCD Frame Counter
+ * @param[in] freq   LCD reference refresh frequency in Hz that will be used
+ *
+ */
+void tls_lcd_fresh_rate(uint16_t freq);
+
+/**
+ * @brief   Turn on or clear a segment
+ * @param[in] com   Which COM line to update
+ * @param[in] bit   Bit index of which field to change
+ * @param[in] enable   When one will set segment, when zero will clear segment
+ * @note   Before this function be called, the module must have been intialized
+ */
+void tls_lcd_seg_set(int com, int bit, int on_off);
+
+/**
+ * @brief   Select the voltage of LCD module
+ * @param[in] vlcd   This parameter can be one of the following values:
+ *     - \ref VLCD27
+ *     - \ref VLCD29
+ *     - \ref VLCD31
+ *     - \ref VLCD33
+ */
+void tls_lcd_vlcd_sel(LCD_VlcdDef vlcd);
+
+/**
+ * @brief   Set the duty of LCD module
+ * @param[in] duty   This parameter can be one of the following values:
+ *     - \ref DUTY_STATIC
+ *     - \ref DUTY_ONEHALF
+ *     - \ref DUTY_ONETHIRD
+ *     - \ref DUTY_ONEFOURTH
+ *     - \ref DUTY_ONEFIFTH
+ *     - \ref DUTY_ONESIXTH
+ *     - \ref DUTY_ONESEVENTH
+ *	   - \ref DUTY_ONEEIGHTH
+ *
+ */
+void tls_lcd_duty_set(LCD_DutyDef duty);
+
+/**
+ * @brief   Set the bias of LCD module
+ * @param[in] duty   This parameter can be one of the following values:
+ *     - \ref BIAS_STATIC
+ *     - \ref BIAS_ONEHALF
+ *     - \ref BIAS_ONETHIRD
+ *     - \ref BIAS_ONEFOURTH
+ *
+ */
+void tls_lcd_bias_set(LCD_BiasDef bias);
+
+/**
+ * @brief   Enable or disable clock of LCD module
+ * @param[in] enable   When one enable the clock of LCD module, when zero disable
+ */
+#define TLS_LCD_CLK_ENABLE(enable) \
+		do { \
+			tls_bitband_write(HR_CLK_BASE_ADDR, HR_CLK_LCD_GATE_Pos, enable); \
+		} while(0)
+
+
+/**
+ * @brief   Enable or disable the LCD module
+ * @param[in] enable   When one enable the LCD module, when zero disable
+ *
+ */
+#define TLS_LCD_ENABLE(enable)	\
+		do { \
+			tls_bitband_write(HR_LCD_CR, LCD_CR_EN_Pos, enable); \
+		} while(0)
+
+/**
+ * @brief   Enable or disable the LCD module
+ * @param[in] enable   When one close LCD module, when zero open the LCD module
+ *
+ */
+#define TLS_LCD_POWERDOWM(enable)	\
+		do { \
+			tls_bitband_write(HR_LCD_CR, LCD_CR_PD_Pos, enable); \
+		} while(0)		
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+/*** (C) COPYRIGHT 2014 Winner Microelectronics Co., Ltd. ***/

+ 254 - 0
include/driver/wm_pmu.h

@@ -0,0 +1,254 @@
+/**
+ * @file    wm_pmu.h
+ *
+ * @brief   pmu driver module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_PMU_H
+#define WM_PMU_H
+
+#include "wm_type_def.h"
+
+/** peripheral type */
+typedef enum {
+    TLS_PERIPHERAL_TYPE_I2C   = (1 << 0), /**< peripheral type : I2C */
+    TLS_PERIPHERAL_TYPE_UART0 = (1 << 1), /**< peripheral type : UART0 */
+    TLS_PERIPHERAL_TYPE_UART1 = (1 << 2), /**< peripheral type : UART1 */
+	TLS_PERIPHERAL_TYPE_UART2 = (1 << 3), /**< peripheral type : UART2 */
+	TLS_PERIPHERAL_TYPE_UART3 = (1 << 4), /**< peripheral type : UART3 */
+    TLS_PERIPHERAL_TYPE_UART4 = (1 << 5), /**< peripheral type : UART4 */
+
+    TLS_PERIPHERAL_TYPE_UART5 = (1 << 6), /**< peripheral type : UART4 */
+
+    TLS_PERIPHERAL_TYPE_LSPI  = (1 << 7), /**< peripheral type : LSPI */
+    TLS_PERIPHERAL_TYPE_DMA   = (1 << 8), /**< peripheral type : DMA */
+
+    TLS_PERIPHERAL_TYPE_TIMER = (1 << 10), /**< peripheral type : TIMER */
+    TLS_PERIPHERAL_TYPE_GPIO  = (1 << 11), /**< peripheral type : GPIO */
+    TLS_PERIPHERAL_TYPE_SDADC = (1 << 12), /**< peripheral type : SDADC */
+    TLS_PERIPHERAL_TYPE_PWM   = (1 << 13), /**< peripheral type : PWM */
+    TLS_PERIPHERAL_TYPE_LCD   = (1 << 14), /**< peripheral type : LCD */
+    TLS_PERIPHERAL_TYPE_I2S   = (1 << 15), /**< peripheral type : I2S */
+    TLS_PERIPHERAL_TYPE_RSA   = (1 << 16), /**< peripheral type : RSA */
+    TLS_PERIPHERAL_TYPE_GPSEC = (1 << 17), /**< peripheral type : GPSEC */
+
+    TLS_PERIPHERAL_TYPE_SDIO_MASTER = (1<<18), /**< peripheral type : SDIO */
+    TLS_PERIPHERAL_TYPE_PSRAM = (1<<19), /**< peripheral type : PSRAM */
+    TLS_PERIPHERAL_TYPE_BT    = (1<<20), /**< peripheral type : BT */
+    TLS_PERIPHERAL_TYPE_TOUCH_SENSOR  = (1 << 21) /**< peripheral type : TOUCH */
+}tls_peripheral_type_s;
+
+/** callback function of PMU interrupt */
+typedef void (*tls_pmu_irq_callback)(void *arg);
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup PMU_Driver_APIs PMU Driver APIs
+ * @brief PMU driver APIs
+ */
+
+/**
+ * @addtogroup PMU_Driver_APIs
+ * @{
+ */
+
+
+/**
+ * @brief          	This function is used to register pmu timer1 interrupt
+ *
+ * @param[in]      	callback    	the pmu timer1 interrupt call back function
+ * @param[in]      	arg         		parameter of call back function
+ *
+ * @return         	None
+ *
+ * @note
+ * user not need clear interrupt flag.
+ * pmu timer1 callback function is called in interrupt,
+ * so can not operate the critical data in the callback fuuction,
+ * recommendation to send messages to other tasks to operate it.
+ */
+void tls_pmu_timer1_isr_register(tls_pmu_irq_callback callback, void *arg);
+
+
+/**
+ * @brief          	This function is used to register pmu timer0 interrupt
+ *
+ * @param[in]      	callback    	the pmu timer0 interrupt call back function
+ * @param[in]      	arg         		parameter of call back function
+ *
+ * @return         	None
+ *
+ * @note
+ * user not need clear interrupt flag.
+ * pmu timer0 callback function is called in interrupt,
+ * so can not operate the critical data in the callback fuuction,
+ * recommendation to send messages to other tasks to operate it.
+ */
+void tls_pmu_timer0_isr_register(tls_pmu_irq_callback callback, void *arg);
+
+
+/**
+ * @brief          	This function is used to register pmu gpio interrupt
+ *
+ * @param[in]      	callback    	the pmu gpio interrupt call back function
+ * @param[in]      	arg         		parameter of call back function
+ *
+ * @return         	None
+ *
+ * @note
+ * user not need clear interrupt flag.
+ * pmu gpio callback function is called in interrupt,
+ * so can not operate the critical data in the callback fuuction,
+ * recommendation to send messages to other tasks to operate it.
+ */
+void tls_pmu_gpio_isr_register(tls_pmu_irq_callback callback, void *arg);
+
+
+/**
+ * @brief          	This function is used to register pmu sdio interrupt
+ *
+ * @param[in]      	callback    	the pmu sdio interrupt call back function
+ * @param[in]      	arg         		parameter of call back function
+ *
+ * @return         	None
+ *
+ * @note
+ * user not need clear interrupt flag.
+ * pmu sdio callback function is called in interrupt,
+ * so can not operate the critical data in the callback fuuction,
+ * recommendation to send messages to other tasks to operate it.
+ */
+void tls_pmu_sdio_isr_register(tls_pmu_irq_callback callback, void *arg);
+
+
+/**
+ * @brief          	This function is used to select pmu clk
+ *
+ * @param[in]      	bypass    pmu clk whether or not use bypass mode
+ *				1   pmu clk use 32K by 40MHZ
+ *				other pmu clk 32K by calibration circuit
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_pmu_clk_select(u8 bypass);
+
+
+/**
+ * @brief          	This function is used to start pmu timer0
+ *
+ * @param[in]      	second  	vlaue of timer0 count[s]
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_pmu_timer0_start(u16 second);
+
+
+/**
+ * @brief          	This function is used to stop pmu timer0
+ *
+ * @param		None
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_pmu_timer0_stop(void);
+
+
+
+/**
+ * @brief          	This function is used to start pmu timer1
+ *
+ * @param[in]      	second  	vlaue of timer1 count[ms]
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_pmu_timer1_start(u16 msec);
+
+
+/**
+ * @brief          	This function is used to stop pmu timer1
+ *
+ * @param		None
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_pmu_timer1_stop(void);
+
+
+
+/**
+ * @brief          	This function is used to start pmu goto standby 
+ *
+ * @param		None
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_pmu_standby_start(void);
+
+
+/**
+ * @brief          	This function is used to start pmu goto sleep 
+ *
+ * @param		None
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_pmu_sleep_start(void);
+
+/**
+ * @brief          	This function is used to close peripheral's clock
+ *
+ * @param[in]      	devices  	peripherals
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_close_peripheral_clock(tls_peripheral_type_s devices);
+
+/**
+ * @brief          	This function is used to open peripheral's clock
+ *
+ * @param[in]      	devices  	peripherals
+ *
+ * @return         	None
+ *
+ * @note           	None
+ */
+void tls_open_peripheral_clock(tls_peripheral_type_s devices);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif
+
+

+ 66 - 0
include/driver/wm_psram.h

@@ -0,0 +1,66 @@
+#ifndef __WM_PSRAM_H__
+#define __WM_PSRAM_H__
+
+#define PSRAM_ADDR_START          0x30000000
+#define PSRAM_SIZE_BYTE           0x00800000
+
+typedef enum{
+	PSRAM_SPI = 0,
+	PSRAM_QPI,
+} psram_mode_t;
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup PSRAM_Driver_APIs PSRAM Driver APIs
+ * @brief PSRAM driver APIs
+ */
+
+/**
+ * @addtogroup PSRAM_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to init the psram .
+ *
+ * @param[in]      mode   is work mode, PSRAM_SPI or PSRAM_QPI
+ *
+ * @retval        none
+ *
+ * @note           None
+ */
+void psram_init(psram_mode_t mode);
+
+/**
+ * @brief          This function is used to Copy block of memory in dma mode .
+ *
+ * @param[in]      src   Pointer to the source of data to be copied
+ * @param[in]      dst   Pointer to the destination array where the content is to be copied
+ * @param[in]      num   Number of bytes to copy
+ *
+ * @retval         num   Number of bytes that's been copied
+ *
+ * @note           None
+ */
+int memcpy_dma(unsigned char *dst, unsigned char *src, int num);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif
+
+
+
+
+

+ 400 - 0
include/driver/wm_pwm.h

@@ -0,0 +1,400 @@
+/**
+ * @file    wm_pwm.h
+ *
+ * @brief   pwm driver module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_PWM_H
+#define WM_PWM_H
+
+#include "wm_type_def.h"
+
+
+/** pwm channel's maximum number */
+#define PWM_CHANNEL_MAX_NUM        5
+
+/** pwm work mode for signal generate */
+enum tls_pwm_out_mode
+{
+    WM_PWM_OUT_MODE_BRAKE = 0, /**< brake mode */
+    WM_PWM_OUT_MODE_ALLSYC,    /**< all synchronous mode */
+    WM_PWM_OUT_MODE_2SYC,      /**< two channel synchronous mode */
+    WM_PWM_OUT_MODE_MC,        /**< complementary mode */
+    WM_PWM_OUT_MODE_INDPT      /**< independent mode */
+};
+
+/** interrupt type for capture mode */
+enum tls_pwm_cap_int_type{
+    WM_PWM_CAP_RISING_EDGE_INT,         /**< rising edge arises the interrupt */
+    WM_PWM_CAP_FALLING_EDGE_INT,        /**< falling edge arises the interrupt */
+    WM_PWM_CAP_RISING_FALLING_EDGE_INT, /**< both rising edge and falling edge arise the interrupt */
+    WM_PWM_CAP_DMA_INT                  /**< dma request */
+};
+
+/** pwm output status */
+enum tls_pwm_out_en_state{
+    WM_PWM_OUT_EN_STATE_TRI,    /**< set tristate status */
+    WM_PWM_OUT_EN_STATE_OUT     /**< set output status */
+};
+
+/** pwm count mode */
+enum tls_pwm_cnt_type{
+    WM_PWM_CNT_TYPE_EDGE_ALLGN_CAP,     /**< edge alignment(only capture mode) */
+    WM_PWM_CNT_TYPE_EDGE_ALIGN_OUT,     /**< edge alignment(only output mode) */
+    WM_PWM_CNT_TYPE_CENTER_ALIGN        /**< central alignment */
+};
+
+/** pwm cycle type */
+enum tls_pwm_loop_type{
+    WM_PWM_LOOP_TYPE_SINGLE,    /**< single mode */
+    WM_PWM_LOOP_TYPE_LOOP       /**< auto load */
+};
+
+/** pwm waveform inversion mode */
+enum tls_pwm_waveform_inversion{
+    WM_PWM_WAVEFORM_NOINVERSION,    /**< not inverse */
+    WM_PWM_WAVEFORM_INVERSION       /**< inversion */
+};
+
+/** pwm output level in the brake mode */
+enum tls_pwm_brake_out_level{
+    WM_PWM_BRAKE_OUT_HIGH,          /**< output high level */
+    WM_PWM_BRAKE_OUT_LOW            /**< output low  level */
+};
+
+/** pwm initial parameters */
+typedef struct _pwm_init_param{
+    enum tls_pwm_out_mode mode;         /**< work mode */
+    u8 channel;                         /**< channel id 0~4 */
+    u16 clkdiv;                         /**< clock divided value */
+    u8 period;                          /**< period value(output frequency F = CLK/CLK_DIV/PERIOD) */
+    u8 duty;                            /**< duty radio (range 0~255, high level or low level by out_inversion decided */
+    bool dten;                          /**< enable dead zone time (ENABLE or DISABLE) */
+    u8 dtclkdiv;                        /**< dead zone clock divided value (0~3) */
+    u8 dtcnt;                           /**< period number of dead zone time  (0~255) */
+    enum tls_pwm_cnt_type cnt_type;     /**< count type */
+    enum tls_pwm_loop_type loop_type;   /**< cycle type */
+    bool inverse_en;                    /**< output is inverse */
+    u8 pnum;                            /**< generate interrupt after pnum period */
+    bool pnum_int;                      /**< period interrupt is enable */
+}pwm_init_param;
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup PWM_Driver_APIs PWM Driver APIs
+ * @brief PWM driver APIs
+ */
+
+/**
+ * @addtogroup PWM_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to register the pwm interrupt callback function
+ *
+ * @param[in]      callback     the pwm interrupt callback function
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_pwm_isr_register(void (*callback)(void));
+
+/**
+ * @brief          This function is used to set duty radio
+ *
+ * @param[in]      channel    pwm channel NO.,range form 0 to 4
+ * @param[in]      duty       Number of active levels
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_duty_config(u8 channel, u8 duty);
+
+/**
+ * @brief          This function is used to set frequency
+ *
+ * @param[in]      channel    pwm channel NO., range form 0 to 4
+ * @param[in]      clkdiv     clock divider, range 0 to 65535
+ * @param[in]      period     the number of the counting clock cycle
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_freq_config(u8 channel, u16 clkdiv, u8 period);
+
+/**
+ * @brief          This function is used to set the output mode
+ *
+ * @param[in]      channel    pwm channel NO., range form 0 to 4
+ * @param[in]      mode       pwm work mode for signal generate
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_out_mode_config(u8 channel, enum tls_pwm_out_mode mode);
+
+/**
+ * @brief          This function is used to set the counting mode
+ *
+ * @param[in]      channel     pwm channel NO.,range form 0 to 4
+ * @param[in]      cnt_type    counting mode
+ *
+ * @retval         WM_SUCCESS  success
+ * @retval         WM_FAILED   failed
+ *
+ * @note           None
+ */
+int tls_pwm_cnt_type_config(u8 channel, enum tls_pwm_cnt_type cnt_type);
+
+/**
+ * @brief          This function is used to set whether to loop
+ *
+ * @param[in]      channel      pwm channel NO.,range form 0 to 4
+ * @param[in]      loop_mode    whether to loop
+ *
+ * @retval         WM_SUCCESS   success
+ * @retval         WM_FAILED    failed
+ *
+ * @note           None
+ */
+int tls_pwm_loop_mode_config(u8 channel, enum tls_pwm_loop_type loop_mode);
+
+/**
+ * @brief          This function is used to set whether to inverse the output
+
+ *
+ * @param[in]      channel    pwm channel NO.,range form 0 to 4
+ * @param[in]      en         ENABLE or DISABLE
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_out_inverse_cmd(u8 channel, bool en);
+
+/**
+ * @brief          This function is used to set the number of period to be generated
+ *
+ * @param[in]      channel    pwm channel NO.,range form 0 to 4
+ * @param[in]      pnum       the number of period to be generated,range from 0 to 255
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_stoptime_by_period_config(u8 channel, u8 pnum);
+
+/**
+ * @brief          This function is used to set output enable
+ *
+ * @param[in]      channel    pwm channel NO.,channel 0 or channel 4
+ * @param[in]      en         ENABLE or DISABLE
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_output_en_cmd(u8 channel, bool en);
+
+/**
+ * @brief          This function is used to set the dead time
+ *
+ * @param[in]      channel     pwm channel NO.,channel 0 or channel 2
+ * @param[in]      dten        whether enalbe the deat time, ENABLE or DISABLE
+ * @param[in]      dtclkdiv    dead zone clock divider, range 0 to 3
+ * @param[in]      dtcnt       the number of the counting clock cycle, range 0 to 255
+ *
+ * @retval         WM_SUCCESS  success
+ * @retval         WM_FAILED   failed
+ *
+ * @note           None
+ */
+int tls_pwm_deadzone_config(u8 channel, bool dten, u8 dtclkdiv, u8 dtcnt);
+
+/**
+ * @brief          This function is used to set whether to inverse the capture input
+ *
+ * @param[in]      channel    pwm channel NO.,channel 0 or channel 4
+ * @param[in]      en         ENABLE or DISABLE
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_capture_inverse_cmd(u8 channel, bool en);
+
+/**
+ * @brief          This function is used to set break mode
+ *
+ * @param[in]      channel    pwm channel NO.,channel 0 or channel 4
+ * @param[in]      en         whether enable the break mode,ENABLE or DISABLE
+ * @param[in]      brok       when break
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_brake_mode_config(u8 channel, bool en, enum tls_pwm_brake_out_level brok);
+
+/**
+ * @brief          This function is used to enable the capture mode
+ *
+ * @param[in]      channel    pwm channel NO.,channel 0 or channel 4
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_capture_mode_config(u8 channel);
+
+/**
+ * @brief          This function is used to set the interrupt about the number of period
+ *
+ * @param[in]      channel    pwm channel,range from 0 to 4
+ * @param[in]      en         enble or disable
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_stoptime_irq_cmd(u8 channel, bool en);
+
+/**
+ * @brief          This function is used to set the interrupt about the
+                   capture
+ *
+ * @param[in]      channel     pwm channel,channel 0 or channel 4
+ * @param[in]      int_type    interrupt type
+ *
+ * @retval         WM_SUCCESS  success
+ * @retval         WM_FAILED   failed
+ *
+ * @note           None
+ */
+int tls_pwm_capture_irq_type_config(u8 channel, enum tls_pwm_cap_int_type int_type);
+
+/**
+ * @brief          This function is used to initial pwm(out mode)
+ *
+ * @param[in]      pwm_param    structure containing the initialization parameters
+ *
+ * @retval         WM_SUCCESS   success
+ * @retval         WM_FAILED    failed
+ *
+ * @note           None
+ */
+int tls_pwm_out_init(pwm_init_param *pwm_param);
+
+/**
+ * @brief          This function is used to initial pwm(capture mode)
+ *
+ * @param[in]      channel       pwm channel, channel 0 or channel 4
+ * @param[in]      clkdiv        clock divider, range 0 to 65535
+ * @param[in]      inverse_en    whether the input signal is reversed
+ * @param[in]      int_type      interrupt type
+ *
+ * @retval         WM_SUCCESS    success
+ * @retval         WM_FAILED     failed
+ *
+ * @note           None
+ */
+int tls_pwm_cap_init(u8 channel, u16 clkdiv, bool inverse_en, enum tls_pwm_cap_int_type int_type);
+
+/**
+ * @brief          This function is used to start pwm
+ *
+ * @param[in]      channel    pwm channel, range from 0 to 4
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_start(u8 channel);
+
+/**
+ * @brief          This function is used to stop pwm
+ *
+ * @param[in]      channel    pwm channel no, range form 0 to 4
+ * @param[in]      freq       frequency, range from 1 to 156250
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_pwm_freq_set(u8 channel, u32 freq);
+
+/**
+ * @brief          This function is used to set duty radio
+ *
+ * @param[in]      channel    pwm channel NO., range form 0 to 4
+ * @param[in]      duty       duty radio, range from 0 to 255
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_pwm_duty_set(u8 channel, u8 duty);
+
+/**
+ * @brief          This function is used to initial pwm
+ *
+ * @param[in]      channel    pwm channel, range from 0 to 4
+ * @param[in]      freq       is a pointer to frequency, freq range from 1 to 156250
+ * @param[in]      duty       is a pointer to duty radio, duty range from 0 to 255
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_init(u8 channel,u32 freq, u8 duty, u8 pnum);
+
+/**
+ * @brief          This function is used to stop pwm
+ *
+ * @param[in]      channel    pwm channel, range from 0 to 4
+ *
+ * @retval         WM_SUCCESS success
+ * @retval         WM_FAILED  failed
+ *
+ * @note           None
+ */
+int tls_pwm_stop(u8 channel);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_PWM_H */

+ 109 - 0
include/driver/wm_rtc.h

@@ -0,0 +1,109 @@
+/**
+ * @file    wm_rtc.h
+ *
+ * @brief   rtc Driver Module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_RTC_H
+#define WM_RTC_H
+
+#include <time.h>
+#include "wm_type_def.h"
+
+/** rtc interrupt callback */
+typedef void (*tls_rtc_irq_callback)(void *arg);
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup RTC_Driver_APIs RTC Driver APIs
+ * @brief RTC driver APIs
+ */
+
+/**
+ * @addtogroup RTC_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to set pmu rtc time
+ *
+ * @param[in]      tblock    time value
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_set_rtc(struct tm *tblock);
+
+/**
+ * @brief          This function is used to get pmu rtc time
+ *
+ * @param[out]     tblock    time value
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_get_rtc(struct tm *tblock);
+
+/**
+ * @brief          This function is used to register pmu rtc interrupt
+ *
+ * @param[in]      callback    the rtc interrupt call back function
+ * @param[in]      arg         parameter of call back function
+ *
+ * @return         None
+ *
+ * @note
+ * User does not need to clear the interrupt flag.
+ * Rtc callback function is called in interrupt,
+ * so do not operate the critical data in the callback fuuction.
+ * Sending messages to other tasks to handle is recommended.
+ */
+void tls_rtc_isr_register(tls_rtc_irq_callback callback, void *arg);
+
+/**
+ * @brief          This function is used to start pmu rtc timer
+ *
+ * @param[in]      tblock    timer value
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_rtc_timer_start(struct tm *tblock);
+
+/**
+ * @brief          This function is used to stop pmu rtc timer
+ *
+ * @param          None
+ *
+ * @return         None
+ *
+ * @note           This function also is used to clear rtc timer interrupt
+ */
+void tls_rtc_timer_stop(void);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif
+

+ 150 - 0
include/driver/wm_sasc.h

@@ -0,0 +1,150 @@
+#ifndef __WM_SASC_H_
+#define __WM_SASC_H_
+
+#include <core_804.h>
+#include "wm_regs.h"
+
+#define HR_SASC_B1_BASE         (DEVICE_BASE_ADDR + 0xB000)
+#define HR_SASC_FLASH_BASE      (DEVICE_BASE_ADDR + 0xB100)
+#define HR_SASC_B2_BASE         (DEVICE_BASE_ADDR + 0xB200)
+
+#define _R1_Pos(val, rgn)    ((val&0x1) << (rgn))
+#define _R1_Msk(rgn)         (0x1 << (rgn))
+#define _R2_Pos(val, rgn)    ((val&0x3) << (2*rgn))
+#define _R2_Msk(rgn)         (0x3 << (2*rgn))
+
+typedef enum {
+	SASC_UN_SE_USER  =  0,
+	SASC_UN_SE_SUPER,
+	SASC_SE_USER,
+	SASC_SE_SUPER
+} sasc_car_e;
+
+typedef enum {
+	SASC_AP_RW  =  0,
+	SASC_AP_RO,
+	SASC_AP_WO,
+	SASC_AP_DENYALL
+} sasc_ap_e;
+
+typedef enum {
+	SASC_CD_DA_OF  =  0,
+	SASC_CD_DA,
+	SASC_CD_OF,
+	SASC_CD_DENYALL
+} sasc_cd_e;
+
+typedef enum {
+	SASC_REGION_SIZE_4B = 0x5,
+	SASC_REGION_SIZE_8B,
+	SASC_REGION_SIZE_16B,
+	SASC_REGION_SIZE_32B,
+	SASC_REGION_SIZE_64B,
+	SASC_REGION_SIZE_128B,
+	SASC_REGION_SIZE_256B,
+	SASC_REGION_SIZE_512B,
+	SASC_REGION_SIZE_1KB,
+	SASC_REGION_SIZE_2KB,
+	SASC_REGION_SIZE_4KB,
+	SASC_REGION_SIZE_8KB,
+	SASC_REGION_SIZE_16KB,
+	SASC_REGION_SIZE_32KB,
+	SASC_REGION_SIZE_64KB,
+	SASC_REGION_SIZE_128KB,
+	SASC_REGION_SIZE_256KB,
+	SASC_REGION_SIZE_512KB,
+	SASC_REGION_SIZE_1MB,
+	SASC_REGION_SIZE_2MB,
+	SASC_REGION_SIZE_4MB,
+	SASC_REGION_SIZE_8MB
+} sasc_region_size_e;
+
+typedef struct {
+	sasc_car_e car;               /* security and user or super */
+	sasc_ap_e ap;                /* super user and normal user access.*/
+	sasc_cd_e cd;                /* instruction fetched excution */
+} sasc_region_attr_t;
+
+typedef struct {
+	__IOM uint32_t CAR;
+	__IOM uint32_t CR;
+	__IOM uint32_t AP0;
+	__IOM uint32_t CD0;
+	__IOM uint32_t AP1;
+	__IOM uint32_t CD1;
+	__IOM uint32_t AP2;
+	__IOM uint32_t CD2;
+	__IOM uint32_t REGION[8];
+} SASC_Type;
+
+#define SASC_B1                 ((SASC_Type    *) HR_SASC_B1_BASE)
+#define SASC_FLASH              ((SASC_Type    *) HR_SASC_FLASH_BASE)
+#define SASC_B2                 ((SASC_Type    *) HR_SASC_B2_BASE)
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup SASC_Driver_APIs SASC Driver APIs
+ * @brief SASC driver APIs
+ */
+
+/**
+ * @addtogroup SASC_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used enable region.
+ *
+ * @param[in]      block    sasc type
+ * @param[in]      idx      index
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void wm_sasc_enable_region(SASC_Type *block, uint32_t idx);
+
+/**
+ * @brief          This function is used disable region.
+ *
+ * @param[in]      block    sasc type
+ * @param[in]      idx      index
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void wm_sasc_disable_region(SASC_Type *block, uint32_t idx);
+
+/**
+ * @brief          This function is used set region protect.
+ *
+ * @param[in]      base_addr    base address
+ * @param[in]      idx          index
+ * @param[in]      size         size
+ * @param[in]      attr         attribute
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void set_region_protect(uint32_t base_addr, uint32_t idx, sasc_region_size_e size, sasc_region_attr_t *attr);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif

+ 142 - 0
include/driver/wm_sdio_host.h

@@ -0,0 +1,142 @@
+#ifndef __WM_SDIO_HOST_H_
+#define __WM_SDIO_HOST_H_
+
+#include <core_804.h>
+#include "wm_regs.h"
+
+typedef struct {
+	__IOM uint32_t MMC_CTL;
+	__IOM uint32_t MMC_IO;
+	__IOM uint32_t MMC_BYTECNTL;
+	__IM  uint32_t MMC_TR_BLOCKCNT;
+	__IOM uint32_t MMC_CRCCTL;                       /*!< Offset: 0x010 */
+	__IM  uint32_t CMD_CRC;
+	__IM  uint32_t DAT_CRCL;
+	__IM  uint32_t DAT_CRCH;
+	__IOM uint32_t MMC_PORT;                          /*!< Offset: 0x020 */
+	__IOM uint32_t MMC_INT_MASK;
+	__IOM uint32_t MMC_INT_SRC;
+	__IOM uint32_t MMC_CARDSEL;
+	__IM  uint32_t MMC_SIG;                          /*!< Offset: 0x030 */
+	__IOM uint32_t MMC_IO_MBCTL;
+	__IOM uint32_t MMC_BLOCKCNT;
+	__IOM uint32_t MMC_TIMEOUTCNT;
+	__IOM uint32_t CMD_BUF[16];                      /*!< Offset: 0x040 */
+	__IOM uint32_t BUF_CTL;                          /*!< Offset: 0x080 */
+	uint32_t RESERVED3[31U];
+	__IOM uint32_t  DATA_BUF[128];                    /*!< Offset: 0x100 */
+}SDIO_HOST_Type;
+
+#define SDIO_HOST     ((SDIO_HOST_Type *)HR_SDIO_HOST_BASE_ADDR)
+
+typedef struct
+{
+  long long CardCapacity;
+  u32 CardBlockSize;
+  u16 RCA;
+  u8 CardType;
+} SD_CardInfo_t;
+extern SD_CardInfo_t SDCardInfo;
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup SDIOH_Driver_APIs SDIO HOST Driver APIs
+ * @brief SDIO HOST driver APIs
+ */
+
+/**
+ * @addtogroup SDIOH_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to initial the sd host module .
+ *
+ * @param[out]     rca_ref   Pointer to the rca reference
+ *
+ * @retval         status   0 if succeed, otherwise fail
+ *
+ * @note           None
+ */
+int sdh_card_init(uint32_t *rca_ref);
+
+/**
+ * @brief          This function is used to set the width of bus .
+ *
+ * @param[in]     rca  the rca reference
+ * @param[in]     bus_width: 0:1bit; 2:4bits
+ *
+ * @retval         status   0 if succeed, otherwise fail
+ *
+ * @note           None
+ */
+int wm_sd_card_set_bus_width(uint32_t rca, uint8_t bus_width);
+
+/**
+ * @brief          This function is used to read one block data from the sd card with irq mode .
+ *
+ * @param[in]      sd_addr   address that to be read from
+ * @param[in]      buf   Pointer to the buffer that the data shall be read into
+ *
+ * @retval         status   0 if succeed, otherwise fail
+ *
+ * @note           None
+ */
+int wm_sd_card_block_read(uint32_t rca, uint32_t sd_addr, char *buf);
+
+/**
+ * @brief          This function is used to write one block data into the sd card with irq mode .
+ *
+ * @param[in]      sd_addr   address that to be written to
+ * @param[in]      buf   Pointer to the buffer that holding the data to be written
+ *
+ * @retval         status   0 if succeed, otherwise fail
+ *
+ * @note           None
+ */
+int wm_sd_card_block_write(uint32_t rca, uint32_t sd_addr, char *buf);
+
+/**
+ * @brief          This function is used to read blocks of data from the sd card with dma mode .
+ *
+ * @param[in]      sd_addr   address that to be read from
+ * @param[in]      buf   Pointer to the buffer that the data shall be read into
+ * @param[in]      buflen   buffer size, should be integer multiple of 512
+ *
+ * @retval         status   0 if succeed, otherwise fail
+ *
+ * @note           None
+ */
+int wm_sd_card_blocks_read(uint32_t rca, uint32_t sd_addr, char *buf, uint32_t buflen);
+
+/**
+ * @brief          This function is used to write blocks of data into the sd card with dma mode .
+ *
+ * @param[in]      sd_addr   address that to be written to
+ * @param[in]      buf   Pointer to the buffer that holding the data to be written
+ * @param[in]      buflen   buffer size, should be integer multiple of 512
+ *
+ * @retval         status   0 if succeed, otherwise fail
+ *
+ * @note           None
+ */
+int wm_sd_card_blocks_write(uint32_t rca, uint32_t sd_addr, char *buf, uint32_t buflen);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif //__WM_SDIO_HOST_H_
+

+ 137 - 0
include/driver/wm_timer.h

@@ -0,0 +1,137 @@
+/**
+ * @file    wm_timer.h
+ *
+ * @brief   Timer Driver Module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_TIMER_H
+#define WM_TIMER_H
+
+#include "wm_type_def.h"
+/** invalid timer id */
+#define WM_TIMER_ID_INVALID              0xFF
+
+/** timer interrupt callback */
+typedef void (*tls_timer_irq_callback)(void *arg);
+
+/** timer unit */
+enum tls_timer_unit{
+    TLS_TIMER_UNIT_US = 0,    /**< microsecond level(us) */
+    TLS_TIMER_UNIT_MS         /**< millisecond level(ms) */
+};
+
+/** timer configuration */
+struct tls_timer_cfg {
+    enum tls_timer_unit unit;           /**< timer accuracy */
+    u32  timeout;                       /**< timeout period */
+    bool is_repeat;                     /**< cycle timer */
+    tls_timer_irq_callback callback;    /**< timeout callback function */
+    void *arg;                          /**< parameter fot the timeout callback function */
+};
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup TIMER_Driver_APIs TIMER Driver APIs
+ * @brief TIMER driver APIs
+ */
+
+/**
+ * @addtogroup TIMER_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to create a timer
+ *
+ * @param[in]      cfg     timer configuration
+ *
+ * @retval         WM_TIMER_ID_INVALID     failed
+ * @retval         other                   timer id
+ *
+ * @note
+ * User does not need to clear the interrupt flag.
+ * Rtc callback function is called in interrupt,
+ * so do not operate the critical data in the callback fuuction.
+ * Sending messages to other tasks to handle is recommended.
+ */
+u8 tls_timer_create(struct tls_timer_cfg *cfg);
+
+/**
+ * @brief          This function is used to start a timer
+ *
+ * @param[in]      timer_id    timer id
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_timer_start(u8 timer_id);
+
+/**
+ * @brief          This function is used to stop a timer
+ *
+ * @param[in]      timer_id    timer id
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_timer_stop(u8 timer_id);
+
+/**
+ * @brief           This function is used to change a timer wait time
+ *
+ * @param[in]      	timer_id    timer id[0~5]
+ *
+ * @param[in]      	newtime     new wait time
+ *
+ * @retval         	None
+ *
+ * @note            If the timer does not start, this function will start the timer
+ */
+void tls_timer_change(u8 timer_id, u32 newtime);
+
+/**
+ * @brief           This function is used to read a timer's current value
+ *
+ * @param[in]      	timer_id    timer id[0~5]
+ *
+ * @retval          timer's	current  value
+ *
+ * @note            none
+ */
+u32 tls_timer_read(u8 timer_id);
+
+/**
+ * @brief          This function is used to delete a timer
+ *
+ * @param[in]      timer_id    timer id
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_timer_destroy(u8 timer_id);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_TIMER_H */
+

+ 1284 - 0
include/driver/wm_tipc.h

@@ -0,0 +1,1284 @@
+#ifndef __WM_TIPC_H_
+#define __WM_TIPC_H_
+
+#include <core_804.h>
+#include "wm_regs.h"
+
+#define HR_TIPC_BASE         (HR_APB_BASE_ADDR + 0x2400)
+
+typedef union {
+    struct {
+        uint32_t I2C: 1;                         /*!< bit:      0 */
+        uint32_t SAR_ADC: 1;                     /*!< bit:      1 */
+        uint32_t SPI_LS: 1;                      /*!< bit:      2 */
+        uint32_t UART0: 1;                       /*!< bit:      3 */
+        uint32_t UART1: 1;                       /*!< bit:      4 */
+        uint32_t UART2: 1;                       /*!< bit:      5 */
+        uint32_t UART3: 1;                       /*!< bit:      6 */
+        uint32_t UART4: 1;                       /*!< bit:      7 */
+        uint32_t UART5: 1;                       /*!< bit:      8 */
+        uint32_t PORTA: 1;                       /*!< bit:      9 */
+        uint32_t PORTB: 1;                       /*!< bit:      10 */
+        uint32_t WD: 1;                          /*!< bit:      11 */
+        uint32_t TIMER: 1;                       /*!< bit:      12 */
+        uint32_t RFC: 1;                         /*!< bit:      13 */
+        uint32_t LCD: 1;                         /*!< bit:      14 */
+        uint32_t PWM: 1;                         /*!< bit:      15 */
+        uint32_t I2S: 1;                         /*!< bit:      16 */
+        uint32_t BT_MODEM: 1;                    /*!< bit:      17 */
+        uint32_t _reserved0: 14;
+    }b;
+    uint32_t w;
+} TIPC_VLD0_Type;
+
+typedef union {
+    struct {
+        uint32_t SDIO_HOST: 1;                   /*!< bit:      0 */
+        uint32_t FLASH: 1;                       /*!< bit:      1 */
+        uint32_t PSRAM: 1;                       /*!< bit:      2 */
+        uint32_t RSA: 1;                         /*!< bit:      3 */
+        uint32_t DMA: 1;                         /*!< bit:      4 */
+        uint32_t GPSEC: 1;                       /*!< bit:      5 */
+        uint32_t BT: 1;                          /*!< bit:      6 */
+        uint32_t PMU: 1;                         /*!< bit:      7 */
+        uint32_t CLK_RST: 1;                     /*!< bit:      8 */
+        uint32_t MMU: 1;                         /*!< bit:      9 */
+        uint32_t BBP: 1;                         /*!< bit:      10 */
+        uint32_t MAC: 1;                         /*!< bit:      11 */
+        uint32_t SEC: 1;                         /*!< bit:      12 */
+        uint32_t _reserved0: 1;                  /*!< bit:      13 */
+        uint32_t SDIO_SLAVE: 1;                  /*!< bit:      14 */
+        uint32_t SPI_HS: 1;                      /*!< bit:      15 */
+        uint32_t SDIO_WRAPPER: 1;                /*!< bit:      16 */
+        uint32_t RF_BIST: 1;                     /*!< bit:      17 */
+        uint32_t _reserved1: 14;
+    }b;
+    uint32_t w;
+} TIPC_VLD1_Type;
+
+typedef struct {
+	__IOM uint32_t VLD0;
+	__IOM uint32_t VLD1;
+} TIPC_Type;
+
+#define TIPC          ((TIPC_Type    *) HR_TIPC_BASE)
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup TIPC_Driver_APIs TIPC Driver APIs
+ * @brief TIPC driver APIs
+ */
+
+/**
+ * @addtogroup TIPC_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used enable i2c.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_i2c(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.I2C = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable i2c.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_i2c(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.I2C = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable uart0.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_uart0(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART0 = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable uart0.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_uart0(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART0 = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable sar adc.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_sar_adc(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.SAR_ADC = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable sar adc.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_sar_adc(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.SAR_ADC = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable low speed spi.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_lspi(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.SPI_LS = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable low speed spi.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_lspi(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.SPI_LS = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable uart1.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_uart1(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART1 = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable uart1.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_uart1(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART1 = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable uart2.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_uart2(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART2 = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable uart2.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_uart2(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART2 = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable uart3.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_uart3(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART3 = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable uart3.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_uart3(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART3 = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable uart4.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_uart4(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART4 = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable uart4.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_uart4(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART4 = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable uart5.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_uart5(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART5 = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable uart5.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_uart5(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.UART5 = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable porta.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_porta(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.PORTA = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable porta.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_porta(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.PORTA = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable portb.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_portb(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.PORTB = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable portb.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_portb(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.PORTB = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable watch dog.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_watch_dog(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.WD = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable watch dog.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_watch_dog(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.WD = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable timer.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_timer(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.TIMER = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable timer.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_timer(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.TIMER = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable rf controler.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_rf_controler(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.RFC = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable rf controler.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_rf_controler(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.RFC = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable lcd.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_lcd(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.LCD = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable lcd.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_lcd(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.LCD = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable pwm.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_pwm(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.PWM = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable pwm.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_pwm(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.PWM = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable i2s.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_i2s(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.I2S = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable i2s.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_i2s(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.I2S = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable bt modem.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_bt_modem(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.BT_MODEM = 1;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used disable bt modem.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_bt_modem(void)
+{
+	TIPC_VLD0_Type vld0;
+	vld0.w = TIPC->VLD0;
+	vld0.b.BT_MODEM = 0;
+	TIPC->VLD0 = vld0.w;
+}
+
+/**
+ * @brief          This function is used enable sdio host.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_sdio_host(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.SDIO_HOST = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable sdio host.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_sdio_host(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.SDIO_HOST = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable flash.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_flash(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.FLASH = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable flash.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_flash(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.FLASH = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable psram.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_psram(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.PSRAM = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable psram.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_psram(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.PSRAM = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable rsa.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_rsa(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.RSA = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable rsa.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_rsa(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.RSA = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable dma.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_dma(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.DMA = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable dma.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_dma(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.DMA = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable gpsec.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_gpsec(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.GPSEC = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable gpsec.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_gpsec(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.GPSEC = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable bt.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_bt(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.BT = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable bt.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_bt(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.BT = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable pmu.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_pmu(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.PMU = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable pmu.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_pmu(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.PMU = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable clock reset.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_clk_rst(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.CLK_RST = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable clock reset.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_clk_rst(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.CLK_RST = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable mmu.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_mmu(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.MMU = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable mmu.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_mmu(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.MMU = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable bbp.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_bbp(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.BBP = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable bbp.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_bbp(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.BBP = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable mac.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_mac(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.MAC = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable mac.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_mac(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.MAC = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable sec.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_sec(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.SEC = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable sec.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_sec(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.SEC = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable sdio slave.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_sdio_slave(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.SDIO_SLAVE = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable sdio slave.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_sdio_slave(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.SDIO_SLAVE = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable high speed spi.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_hspi(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.SPI_HS = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable high speed spi.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_hspi(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.SPI_HS = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable sdio wrapper.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_sdio_wrapper(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.SDIO_WRAPPER = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable sdio wrapper.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_sdio_wrapper(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.SDIO_WRAPPER = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used enable rf bist.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_enable_rf_bist(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.RF_BIST = 1;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @brief          This function is used disable rf bist.
+ *
+ * @param[in]      None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+__STATIC_INLINE void wm_tipc_disable_rf_bist(void)
+{
+	TIPC_VLD1_Type vld1;
+	vld1.w = TIPC->VLD1;
+	vld1.b.RF_BIST = 0;
+	TIPC->VLD1 = vld1.w;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif

+ 107 - 0
include/driver/wm_touchsensor.h

@@ -0,0 +1,107 @@
+/**
+ * @file    wm_touchsensor.h
+ *
+ * @brief   touchsensor Driver Module
+ *
+ * @author  
+ *
+ * Copyright (c) 2021 Winner Microelectronics Co., Ltd.
+ */
+#include "wm_type_def.h"
+
+/**
+ * @brief          This function is used to initialize touch sensor.
+ *
+ * @param[in]      sensorno    is the touch sensor number from 1-15
+ * @param[in]      scan_period is scan period for per touch sensor ,unit:16ms, >0
+ * @param[in]      window      is count window, window must be greater than 2.Real count window is window - 2.
+ * @param[in]      enable      is touch sensor enable bit.
+ *
+ * @retval         0:success
+ *
+ * @note           if use touch sensor, user must configure the IO multiplex by API wm_touch_sensor_config.
+ */
+int tls_touchsensor_init_config(u32 sensorno, u8 scan_period, u8 window, u32 enable);
+
+/**
+ * @brief          This function is used to deinit touch sensor's selection and disable touch.
+ *
+ * @param[in]      sensorno    is the touch sensor number from 1-15
+ *
+ * @retval         0:success
+ *
+ * @note           if do not use touch sensor, user can deinit by this interface and configure this touch sensor as GPIO.
+ */
+int tls_touchsensor_deinit(u32 sensorno);
+
+
+/**
+ * @brief          This function is used to set threshold per touch sensor.
+ *
+ * @param[in]      sensorno    is the touch sensor number from 1-15
+ * @param[in]      threshold   is the sensorno's touch sensor threshold,max value is 127.
+ *
+ * @retval         0:success. minus value: parameter wrong.
+ *
+ * @note           None
+ */
+int tls_touchsensor_threshold_config(u32 sensorno, u8 threshold);
+
+
+/**
+ * @brief          This function is used to get touch sensor's count number.
+ *
+ * @param[in]      sensorno    is the touch sensor number from 1 to 15.
+ *
+ * @retval         sensorno's count number  .
+ *
+ * @note           None
+ */
+int tls_touchsensor_countnum_get(u32 sensorno);
+
+/**
+ * @brief          This function is used to enable touch sensor's irq.
+ *
+ * @param[in]      sensorno    is the touch sensor number  from 1 to 15.
+ *
+ * @retval         0:successfully enable irq, -1:parameter wrong.
+ *
+ * @note           None
+ */
+int tls_touchsensor_irq_enable(u32 sensorno);
+
+/**
+ * @brief          This function is used to disable touch sensor's irq.
+ *
+ * @param[in]      sensorno    is the touch sensor number  from 1 to 15.
+ *
+ * @retval         0:successfully disable irq, -1:parameter wrong.
+ *
+ * @note           None
+ */
+int tls_touchsensor_irq_disable(u32 sensorno);
+
+/**
+ * @brief          This function is used to register touch sensor's irq callback.
+ *
+ * @param[in]      callback    is call back for user's application.
+ *
+ * @retval         None.
+ *
+ * @note           None
+ */
+void tls_touchsensor_irq_register(void (*callback)(u32 status));
+
+/**
+ * @brief          This function is used to get touch sensor's irq status.
+ *
+ * @param[in]      sensorno    is the touch sensor number  from 1 to 15.
+ *
+ * @retval         >=0:irq status, -1:parameter wrong.
+ *
+ * @note           None
+ */
+int tls_touchsensor_irq_status_get(u32 sensorno);
+
+
+

+ 529 - 0
include/driver/wm_uart.h

@@ -0,0 +1,529 @@
+/**
+ * @file    wm_uart.h
+ *
+ * @brief   uart Driver Module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_UART_H
+#define WM_UART_H
+#include "list.h"
+//#include "wm_regs.h"
+#include "wm_type_def.h"
+#include "wm_osal.h"
+
+#define TLS_UART_RX_BUF_SIZE   4096
+#define TLS_UART_TX_BUF_SIZE   4096
+#define WAKEUP_CHARS           256
+
+#define MBOX_MSG_UART_RX       1
+#define MBOX_MSG_UART_TX       2
+
+
+/** baud rate definition */
+#define UART_BAUDRATE_B600          600
+#define UART_BAUDRATE_B1200	        1200
+#define UART_BAUDRATE_B1800         1800
+#define UART_BAUDRATE_B2400         2400
+#define UART_BAUDRATE_B4800         4800
+#define UART_BAUDRATE_B9600         9600
+#define UART_BAUDRATE_B19200        19200
+#define UART_BAUDRATE_B38400        38400
+#define UART_BAUDRATE_B57600        57600
+#define UART_BAUDRATE_B115200       115200
+#define UART_BAUDRATE_B230400       230400
+#define UART_BAUDRATE_B460800       460800
+#define UART_BAUDRATE_B921600      921600
+#define UART_BAUDRATE_B1000000      1000000
+#define UART_BAUDRATE_B1250000      1250000
+#define UART_BAUDRATE_B1500000      1500000
+#define UART_BAUDRATE_B2000000      2000000
+
+#define UART_RX_INT_FLAG (UIS_RX_FIFO | UIS_RX_FIFO_TIMEOUT | UIS_BREAK |\
+        UIS_OVERRUN | UIS_FRM_ERR | UIS_PARITY_ERR)
+#define UART_RX_ERR_INT_FLAG (UIS_BREAK | UIS_FRM_ERR | \
+        UIS_PARITY_ERR)
+
+#define UART_TX_INT_FLAG (UIS_TX_FIFO | UIS_TX_FIFO_EMPTY)
+
+/** return count in buffer.  */
+#define CIRC_CNT(head,tail,size) (((head) - (tail)) & ((size)-1))
+
+/** Return space available, 0..size-1.  We always leave one free char
+   as a completely full buffer has head == tail, which is the same as
+   empty.  */
+#define CIRC_SPACE(head,tail,size) CIRC_CNT((tail),((head)+1),(size))
+
+/** Return count up to the end of the buffer.  Carefully avoid
+   accessing head and tail more than once, so they can change
+   underneath us without returning inconsistent results.  */
+#define CIRC_CNT_TO_END(head,tail,size) \
+	({int end = (size) - (tail); \
+	  int n = ((head) + end) & ((size)-1); \
+	  n < end ? n : end;})
+
+/** Return space available up to the end of the buffer.  */
+#define CIRC_SPACE_TO_END(head,tail,size) \
+	({int end = (size) - 1 - (head); \
+	  int n = (end + (tail)) & ((size)-1); \
+	  n <= end ? n : end+1;})
+
+#define CIRC_SPACE_TO_END_FULL(head,tail,size) \
+	({int end = (size) - 1 - (head); \
+	  int n = (end + (tail)) & ((size)-1); \
+	  n < end ? n : end+1;})
+
+#define uart_circ_empty(circ)		((circ)->head == (circ)->tail)
+#define uart_circ_chars_pending(circ)	\
+	(CIRC_CNT((circ)->head, (circ)->tail, TLS_UART_TX_BUF_SIZE))
+
+/**
+ * @struct tls_uart_baud_rate    baudrate define
+ */
+struct tls_uart_baud_rate
+{
+    u32 baud_rate;
+    u16 ubdiv;
+    u16 ubdiv_frac;
+};
+
+
+/**
+ * @enum    uart number enum
+ */
+enum
+{
+    TLS_UART_0 = 0,
+    TLS_UART_1 = 1,
+    TLS_UART_2 = 2,
+    TLS_UART_3 = 3,
+    TLS_UART_4 = 4,
+    TLS_UART_5 = 5,    
+    TLS_UART_MAX = 6,
+};
+
+
+/**
+ * @typedef enum TLS_UART_PMODE    Parity Mode
+ */
+typedef enum TLS_UART_PMODE
+{
+    TLS_UART_PMODE_DISABLED = 0,    /**< No Parity */
+    TLS_UART_PMODE_ODD = 1,     /**< Odd Parity */
+    TLS_UART_PMODE_EVEN = 2,    /**< Even Parity */
+    TLS_UART_PMODE_MARK = 3,    /**< The parity bit is always 1. */
+    TLS_UART_PMODE_SPACE = 4,   /**< The parity bit is always 0. */
+} TLS_UART_PMODE_T;
+
+/**
+ * @typedef enum TLS_UART_CHSIZE    Character Size
+ */
+typedef enum TLS_UART_CHSIZE
+{
+    TLS_UART_CHSIZE_5BIT = (0x00 << 0), /**< Character size: 5 bit */
+    TLS_UART_CHSIZE_6BIT = (0x01 << 0), /**< Character size: 6 bit */
+    TLS_UART_CHSIZE_7BIT = (0x02 << 0), /**< Character size: 7 bit */
+    TLS_UART_CHSIZE_8BIT = (0x03 << 0), /**< Character size: 8 bit */
+} TLS_UART_CHSIZE_T;
+
+/**
+ * @typedef enum TLS_UART_FLOW_CTRL_MODE    flow control mode
+ */
+typedef enum TLS_UART_FLOW_CTRL_MODE
+{
+    TLS_UART_FLOW_CTRL_NONE,
+    TLS_UART_FLOW_CTRL_HARDWARE,
+} TLS_UART_FLOW_CTRL_MODE_T;
+
+/**
+ * @typedef enum TLS_UART_RX_FLOW_CTRL_FLAG    flow control rx flag
+ */
+typedef enum TLS_UART_RX_FLOW_CTRL_FLAG
+{
+    TLS_UART_RX_DISABLE,
+    TLS_UART_RX_ENABLE,
+} TLS_UART_RX_FLOW_CTRL_FLAG_T;
+
+/**
+ * @typedef enum TLS_UART_STOPBITS
+ */
+typedef enum TLS_UART_STOPBITS
+{
+    TLS_UART_ONE_STOPBITS,
+    TLS_UART_TWO_STOPBITS,
+} TLS_UART_STOPBITS_T;
+
+
+/**
+ * @typedef enum TLS_UART_STATUS
+ */
+typedef enum TLS_UART_STATUS
+{
+    TLS_UART_STATUS_OK,
+    TLS_UART_STATUS_ERROR,
+} TLS_UART_STATUS_T;
+
+
+/**
+ * @typedef enum TLS_UART_MODE   operation mode
+ */
+typedef enum TLS_UART_MODE
+{
+    TLS_UART_MODE_POLL,         /**< uart operation mode: poll */
+    TLS_UART_MODE_INT,          /**< uart operation mode: interrupt mode */
+} TLS_UART_MODE_T;
+
+/**
+ * @struct tls_uart_icount
+ */
+struct tls_uart_icount
+{
+    u32 cts;
+    u32 dsr;
+    u32 rng;
+    u32 dcd;
+    u32 rx;
+    u32 tx;
+    u32 frame;
+    u32 overrun;
+    u32 parity;
+    u32 brk;
+    u32 buf_overrun;
+};
+
+
+
+/**
+ * @typedef struct tls_uart_options
+ */
+typedef struct tls_uart_options
+{
+    u32 baudrate;    /**< Set baud rate of the UART */
+
+    TLS_UART_CHSIZE_T charlength;   /**< Number of bits to transmit as a character (5 to 8). */
+
+    TLS_UART_PMODE_T paritytype;    /**< Parity type */
+
+    TLS_UART_FLOW_CTRL_MODE_T flow_ctrl;    /**< Flow control type */
+
+    TLS_UART_STOPBITS_T stopbits;    /**< Number of stop bits */
+
+} tls_uart_options_t;
+
+
+/**
+ * @typedef struct tls_uart_circ_buf
+ */
+typedef struct tls_uart_circ_buf
+{
+volatile    u8 *buf;
+volatile   u32 head;
+volatile   u32 tail;
+} tls_uart_circ_buf_t;
+
+#if TLS_CONFIG_CMD_NET_USE_LIST_FTR
+/**
+ * @typedef struct tls_uart_net_buf
+ */
+typedef struct tls_uart_net_buf
+{
+    struct dl_list list;
+    char *buf;
+	void *pbuf;
+    u16 buflen;
+    u16 offset;
+} tls_uart_net_buf_t;
+
+typedef struct tls_uart_net_msg
+{
+    struct dl_list tx_msg_pending_list;
+} tls_uart_net_msg_t;
+#endif
+
+
+/**
+ * @typedef struct TLS_UART_REGS
+ */
+typedef struct TLS_UART_REGS
+{
+    u32 UR_LC;                       /**< line control register */
+    u32 UR_FC;                       /**<  flow control register */
+    u32 UR_DMAC;                  /**< dma control register */
+    u32 UR_FIFOC;                  /**< fifo control register */
+    u32 UR_BD;                       /**< baud rate register */
+    u32 UR_INTM;                   /**< interrupt mask register */
+    u32 UR_INTS;                    /**< interrupt source register */
+    u32 UR_FIFOS;                  /**< fifo status register */
+    u32 UR_TXW;                    /**< tx windows register */
+    u32 UR_RES0;
+    u32 UR_RES1;
+    u32 UR_RES2;
+    u32 UR_RXW;                     /**< rx windows register */
+} TLS_UART_REGS_T;
+
+
+/**
+ * @typedef struct tls_uart_port
+ */
+typedef struct tls_uart_port
+{
+    u32 uart_no;                    /**< uart number: 0 or 1 */
+
+    u32 uart_irq_no;             /**< uart interrupt number */
+
+    u32 plus_char_cnt;
+
+    TLS_UART_MODE_T uart_mode;      /**< uart work mode: interrupt mode or poll mode */
+
+    struct tls_uart_options opts;       /**< uart config parameters */
+
+    int fcStatus;                           /**< flow ctrl status,0 closed ,1 opened */
+
+    enum TLS_UART_RX_FLOW_CTRL_FLAG rxstatus;
+
+    u32 tx_fifofull;                    /**< uart tx fifo trigger level */
+
+    TLS_UART_REGS_T volatile *regs;     /**< uart registers struct pointer */
+
+    struct tls_uart_icount icount;          /**< uart statistics information */
+
+    struct tls_uart_circ_buf recv;          /**< uart ring buffer */
+
+// struct tls_uart_circ_buf xmit;
+
+    struct dl_list tx_msg_pending_list;
+
+    struct dl_list tx_msg_to_be_freed_list;
+
+    u8 hw_stopped;
+
+    tls_os_sem_t *tx_sem;
+
+    char *buf_ptr;
+
+    u16 buf_len;
+
+    s16(*rx_callback) (u16 len, void* priv_data);
+
+    s16(*tx_callback) (struct tls_uart_port * port);
+    s16(*tx_sent_callback) (struct tls_uart_port * port);
+
+    bool tx_dma_on;
+	bool rx_dma_on;
+
+	void *priv_data;
+} tls_uart_port_t;
+
+/**
+ * @typedef struct tls_uart_tx_msg
+ */
+typedef struct tls_uart_tx_msg
+{
+    struct dl_list list;
+    char *buf;
+    u16 buflen;
+    u16 offset;
+    void (*finish_callback) (void *arg);
+    void *callback_arg;
+} tls_uart_tx_msg_t;
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup UART_Driver_APIs UART Driver APIs
+ * @brief UART driver APIs
+ */
+
+/**
+ * @addtogroup UART_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief	This function is used to initial uart port.
+ *
+ * @param[in] uart_no: is the uart number.
+ *	- \ref TLS_UART_0 TLS_UART_1 TLS_UART_2 TLS_UART_3 TLS_UART_4 TLS_UART_5
+ * @param[in] opts: is the uart setting options,if this param is NULL,this function will use the default options.
+ * @param[in] modeChoose:; choose uart2 mode or 7816 mode when uart_no is TLS_UART_2, 0 for uart2 mode and 1 for 7816 mode.
+ *
+ * @retval
+ *	- \ref WM_SUCCESS
+ *	- \ref WM_FAILED
+ *
+ * @note When the system is initialized, the function has been called, so users can not call the function.
+ */
+int tls_uart_port_init(u16 uart_no, tls_uart_options_t * opts, u8 modeChoose);
+
+
+/**
+ * @brief          This function is used to register uart rx interrupt.
+ *
+ * @param[in]      uart_no      TLS_UART_0 or TLS_UART_1
+ * @param[in]      rx_callback  is the uart rx interrupt call back function.
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_uart_rx_callback_register(u16 uart_no, s16(*rx_callback) (u16 len, void* user_data), void* user_data);
+
+void tls_uart_rx_byte_callback_flag(u16 uart_no, u8 flag);
+
+/**
+ * @brief	This function is used to register uart tx interrupt.
+ *
+ * @param[in] uart_no: is the uart numer.
+ * @param[in] callback: is the uart tx interrupt call back function.
+ *
+ * @retval
+ */
+void tls_uart_tx_callback_register(u16 uart_no, s16(*tx_callback) (struct tls_uart_port *port));
+
+
+/**
+ * @brief          This function is used to copy circular buffer data to user buffer.
+ *
+ * @param[in]      uart_no    is the uart numer
+ * @param[in]      buf          is the user buffer
+ * @param[in]      readsize   is the user read size
+ *
+ * @retval         copy data size
+ *
+ * @note           None
+ */
+int tls_uart_read(u16 uart_no, u8 * buf, u16 readsize);
+
+/**
+ * @brief          This function is used to check the available data in the cache buffer.
+ *
+ * @param[in]      uart_no    is the uart numer
+ * @param[in]      readsize   is the user read size
+ *
+ * @retval         if the cache buffer size is greater or equals to readsize , then return readsize; otherwise return 0;
+ *
+ * @note           None
+ */
+
+int tls_uart_try_read(u16 uart_no, int32_t read_size);
+
+
+/**
+ * @brief          This function is used to transfer data synchronously.
+ *
+ * @param[in]      uart_no      is the uart number
+ * @param[in]      buf            is a buf for saving user data
+ * @param[in]      writesize    is the user data length
+ *
+ * @retval         WM_SUCCESS    tx success
+ * @retval         WM_FAILED       tx failed
+ *
+ * @note           None
+ */
+int tls_uart_write(u16 uart_no, char *buf, u16 writesize);
+
+
+/**
+ * @brief          This function is used to transfer data with DMA.
+ *
+ * @param[in]      buf                is a buf for saving user data
+ * @param[in]      writesize        is the user data length
+ * @param[in]      cmpl_callback  function point,when the transfer is completed, the function will be called.
+ *
+ * @retval         WM_SUCCESS    success
+ * @retval         WM_FAILED       failed
+ *
+ * @note           Only uart1 support DMA transfer.
+ */
+int tls_uart_dma_write(char *buf, u16 writesize, void (*cmpl_callback) (void *p), u16 uart_no);
+
+
+/**
+ * @brief          This function is used to set uart parity.
+ *
+ * @param[in]      uart_no      is the uart number
+ * @param[in]      paritytype   is a parity type defined in TLS_UART_PMODE_T
+ *
+ * @retval         WM_SUCCESS	if setting success
+ * @retval         WM_FAILED	 	if setting fail
+ *
+ * @note           None
+ */
+int tls_uart_set_parity(u16 uart_no, TLS_UART_PMODE_T paritytype);
+
+
+/**
+ * @brief          This function is used to set uart baudrate.
+ *
+ * @param[in]      uart_no     is the uart number
+ * @param[in]      baudrate    is the baudrate user want used,the unit is HZ.
+ *
+ * @retval         WM_SUCCESS	if setting success
+ * @retval         WM_FAILED 	if setting fail
+ *
+ * @note           None
+ */
+int tls_uart_set_baud_rate(u16 uart_no, u32 baudrate);
+
+/**
+ * @brief          This function is used to set uart stop bits.
+ *
+ * @param[in]      uart_no     is the uart number
+ * @param[in]      stopbits    is a stop bit type defined in TLS_UART_STOPBITS_T
+ *
+ * @retval         WM_SUCCESS	if setting success
+ * @retval         WM_FAILED	if setting fail
+ *
+ * @note           None
+ */
+int tls_uart_set_stop_bits(u16 uart_no, TLS_UART_STOPBITS_T stopbits);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+void tls_uart_push(int uart_no, u8* data, int length);
+
+
+/**
+ * @brief          This function is used to transfer data asynchronously.
+ *
+ * @param[in]      uart_no      is the uart number
+ * @param[in]      buf            is a buf for saving user data
+ * @param[in]      writesize    is the user data length
+ *
+ * @retval         WM_SUCCESS    tx success
+ * @retval         WM_FAILED       tx failed
+ *
+ * @note           None
+ */
+
+int tls_uart_write_async(u16 uart_no, char *buf, u16 writesize);
+
+/**
+ * @brief	This function is used to register uart tx sent callback function.
+ *
+ * @param[in] uart_no: is the uart numer.
+ * @param[in] callback: is the uart tx sent out call back function.
+ *
+ * @retval
+ */
+
+void tls_uart_tx_sent_callback_register(u16 uart_no, s16(*tx_callback) (struct tls_uart_port *port));
+
+
+
+#endif /* WM_UART_H */

+ 86 - 0
include/driver/wm_watchdog.h

@@ -0,0 +1,86 @@
+/**
+ * @file    wm_watchdog.h
+ *
+ * @brief   watchdog Driver Module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_WATCHDOG_H
+#define WM_WATCHDOG_H
+
+/**
+ * @defgroup Driver_APIs Driver APIs
+ * @brief Driver APIs
+ */
+
+/**
+ * @addtogroup Driver_APIs
+ * @{
+ */
+
+/**
+ * @defgroup WDG_Driver_APIs WDG Driver APIs
+ * @brief WDG driver APIs
+ */
+
+/**
+ * @addtogroup WDG_Driver_APIs
+ * @{
+ */
+
+/**
+ * @brief          This function is used to feed the dog.
+ *
+ * @param          None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_watchdog_clr(void);
+
+/**
+ * @brief          This function is used to init and start the watchdog.
+ *
+ * @param[in]      usec    microseconds
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_watchdog_init(u32 usec);
+
+/**
+ * @brief          This function is used to deinit watchdog
+ *
+ * @param[in]     None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_watchdog_deinit(void);
+
+/**
+ * @brief          This function is used to reset the system.
+ *
+ * @param          None
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+void tls_sys_reset(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WM_WATCHDOG_H */
+

+ 317 - 0
include/list.h

@@ -0,0 +1,317 @@
+/*
+ * @file list.h
+ * @brief Doubly-linked list
+ * @copyright (c) 2009, Jouni Malinen <j@w1.fi>
+ *
+ * @note This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef LIST_H
+#define LIST_H
+
+#include <stdio.h>
+
+/** struct dl_list - Doubly-linked list */
+struct dl_list {
+	struct dl_list *next;    /**< pointer to the next */
+	struct dl_list *prev;    /**< pointer to the previous */
+};
+
+/**
+ * @defgroup System_APIs System APIs
+ * @brief System APIs
+ */
+
+/**
+ * @addtogroup System_APIs
+ * @{
+ */
+
+/**
+ * @defgroup DLIST_APIs DLIST APIs
+ * @brief Double listed APIs
+ */
+
+/**
+ * @addtogroup DLIST_APIs
+ * @{
+ */
+
+/**
+ * @brief          reinitialize the list
+ *
+ * @param[in]      *list    the list
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+static __inline void dl_list_init(struct dl_list *list)
+{
+	list->next = list;
+	list->prev = list;
+}
+
+/**
+ * @brief          Insert a new entry after the specified head
+ *
+ * @param[in]      *list    list head to add it after
+ * @param[in]      *item    new entry to be added
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+static __inline void dl_list_add(struct dl_list *list, struct dl_list *item)
+{
+	item->next = list->next;
+	item->prev = list;
+	list->next->prev = item;
+	list->next = item;
+}
+
+/**
+ * @brief          Insert a new entry before the specified head
+ *
+ * @param[in]      *list        list head to add it after
+ * @param[in]      *item        new entry to be added
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+static __inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item)
+{
+	dl_list_add(list->prev, item);
+}
+
+/**
+ * @brief          deletes entry from list
+ *
+ * @param[in]      *item    the element to delete from the list
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+static __inline void dl_list_del(struct dl_list *item)
+{
+	item->next->prev = item->prev;
+	item->prev->next = item->next;
+	item->next = NULL;
+	item->prev = NULL;
+}
+
+/**
+ * @brief          tests whether a list is empty
+ *
+ * @param[in]      *list    the list to test
+ *
+ * @retval         0        not empty
+ * @retval         1        empty
+ *
+ * @note           None
+ */
+static __inline int dl_list_empty(struct dl_list *list)
+{
+	return list->next == list;
+}
+
+/**
+ * @brief          count length of the list
+ *
+ * @param[in]      *list    the list to count
+ *
+ * @return         length
+ *
+ * @note           None
+ */
+static __inline unsigned int dl_list_len(struct dl_list *list)
+{
+	struct dl_list *item;
+	int count = 0;
+	for (item = list->next; item != list; item = item->next)
+		count++;
+	return count;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifndef offsetof
+/** offset address of the struct member */
+#define offsetof(type, member) ((long) &((type *) 0)->member)
+#endif
+
+/**
+ * @brief          get the struct for this entry
+ *
+ * @param[in]      item      the &struct list_head pointer
+ * @param[in]      type      the type of the struct this is embedded in
+ * @param[in]      member    the name of the list_struct within the struct
+ *
+ * @return         pointer to the struct for this entry
+ *
+ * @note           None
+ */
+#define dl_list_entry(item, type, member) \
+	((type *) ((char *) item - offsetof(type, member)))
+
+/**
+ * @brief          get the first element from a list
+ *
+ * @param[in]      list      the list head to take the element from
+ * @param[in]      type      the type of the struct this is embedded in
+ * @param[in]      member    the name of the list_struct within the struct
+ *
+ * @return         pointer to the first element from a list
+ *
+ * @note           None
+ */
+#define dl_list_first(list, type, member) \
+	(dl_list_empty((list)) ? NULL : \
+	 dl_list_entry((list)->next, type, member))
+
+/**
+ * @brief          get the last element from a list
+ *
+ * @param[in]      list      the list head to take the element from
+ * @param[in]      type      the type of the struct this is embedded in
+ * @param[in]      member    the name of the list_struct within the struct
+ *
+ * @return         pointer to the last element from a list
+ *
+ * @note           None
+ */
+#define dl_list_last(list, type, member) \
+	(dl_list_empty((list)) ? NULL : \
+	 dl_list_entry((list)->prev, type, member))
+
+/**
+ * @brief          iterate over list of given type
+ *
+ * @param[in]      item      a loop cursor
+ * @param[in]      list      the head for your list
+ * @param[in]      type      struct type
+ * @param[in]      member    the name of the list_struct within the struct
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+#define dl_list_for_each(item, list, type, member) \
+	for (item = dl_list_entry((list)->next, type, member); \
+	     &item->member != (list); \
+	     item = dl_list_entry(item->member.next, type, member))
+
+/**
+ * @brief          iterate over list of given type safe against removal of list entry
+ *
+ * @param[in]      item      a loop cursor
+ * @param[in]      n         temporary storage
+ * @param[in]      list      the head for your list
+ * @param[in]      type      struct type
+ * @param[in]      member    the name of the list_struct within the struct
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+#define dl_list_for_each_safe(item, n, list, type, member) \
+	for (item = dl_list_entry((list)->next, type, member), \
+		     n = dl_list_entry(item->member.next, type, member); \
+	     &item->member != (list); \
+	     item = n, n = dl_list_entry(n->member.next, type, member))
+
+/**
+ * @brief          iterate backwards over list of given type
+ *
+ * @param[in]      item      a loop cursor
+ * @param[in]      list      the head for your list
+ * @param[in]      type      struct type
+ * @param[in]      member    the name of the list_struct within the struct
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+#define dl_list_for_each_reverse(item, list, type, member) \
+	for (item = dl_list_entry((list)->prev, type, member); \
+	     &item->member != (list); \
+	     item = dl_list_entry(item->member.prev, type, member))
+
+/** define the list head */
+#define DEFINE_DL_LIST(name) \
+	struct dl_list name = { &(name), &(name) }
+
+/**
+ * @brief          iterate over list of given type
+ *
+ * @param[in]      item      the type * to use as a loop cursor
+ * @param[in]      list      the head for your list
+ * @param[in]      member    the name of the list_struct within the struct
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+#define __dl_list_for_each(item, list, member) \
+	for (item = dl_list_entry((list)->next, typeof(*(item)), member); \
+	     &item->member != (list); \
+	     item = dl_list_entry(item->member.next, typeof(*(item)), member))
+
+/**
+ * @brief          iterate over list of given type safe against removal of list entry
+ *
+ * @param[in]      item      the type * to use as a loop cursor
+ * @param[in]      n         temporary storage
+ * @param[in]      list      the head for your list
+ * @param[in]      member    the name of the list_struct within the struct
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+#define __dl_list_for_each_safe(item, n, list, member) \
+	for (item = dl_list_entry((list)->next, typeof(*(item)), member), \
+		     n = dl_list_entry(item->member.next, typeof(*(item)), member); \
+	     &item->member != (list); \
+	     item = n, n = dl_list_entry(n->member.next, typeof(*(item)), member))
+
+/**
+ * @brief          iterate backwards over list of given type
+ *
+ * @param[in]      item      the type * to use as a loop cursor
+ * @param[in]      list      the head for your list
+ * @param[in]      member    the name of the list_struct within the struct
+ *
+ * @return         None
+ *
+ * @note           None
+ */
+#define __dl_list_for_each_reverse(item, list, member) \
+	for (item = dl_list_entry((list)->prev, typeof(*(item)), member); \
+	     &item->member != (list); \
+	     item = dl_list_entry(item->member.prev, typeof(*(item)), member))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* LIST_H */

+ 17 - 0
include/net/wm_socket.h

@@ -0,0 +1,17 @@
+/**
+ * @file    wm_socket.h
+ *
+ * @brief   socket Module
+ *
+ * @author  dave
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+ 
+#ifndef WM_SOCKET_H
+#define WM_SOCKET_H
+#include "wm_config.h"
+#include "wm_socket2.0.3.h"
+
+
+#endif

+ 422 - 0
include/net/wm_socket2.0.3.h

@@ -0,0 +1,422 @@
+/**
+ * @file    wm_socket2.0.3.h
+ *
+ * @brief   socket203 Module
+ *
+ * @author  dave
+ *
+ * @copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_SOCKET2_0_3_H
+#define WM_SOCKET2_0_3_H
+
+#include "wm_type_def.h"
+#include "wm_netif.h"
+
+//socket state defination
+#define NETCONN_STATE_NONE         0
+#define NETCONN_STATE_WAITING      1
+#define NETCONN_STATE_CONNECTED    2
+#define NETCONN_STATE_CLOSED       3
+
+//socket event defination
+#define NET_EVENT_TCP_JOINED            0
+#define NET_EVENT_TCP_DISCONNECT        1
+#define NET_EVENT_TCP_CONNECTED         2
+#define NET_EVENT_TCP_CONNECT_FAILED    3
+#define NET_EVENT_UDP_START             4
+#define NET_EVENT_UDP_START_FAILED      5
+
+#define TLS_MAX_SOCKET_NUM       4
+#define TLS_MAX_NETCONN_NUM      20
+
+/** Main packet buffer struct */
+struct pbuf {
+  /** next pbuf in singly linked pbuf chain */
+  struct pbuf *next;
+
+  /** pointer to the actual data in the buffer */
+  void *payload;
+
+  /**
+   * total length of this buffer and all next buffers in chain
+   * belonging to the same packet.
+   *
+   * For non-queue packet chains this is the invariant:
+   * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
+   */
+  u16_t tot_len;
+
+  /** length of this buffer */
+  u16_t len;
+
+  /** pbuf_type as u8_t instead of enum to save space */
+  u8_t /*pbuf_type*/ type;
+
+  /** misc flags */
+  u8_t flags;
+
+  /**
+   * the reference count always equals the number of pointers
+   * that refer to this pbuf. This can be pointers from an application,
+   * the stack itself, or pbuf->next pointers from a chain.
+   */
+  u16_t ref;
+};
+
+/**
+* @brief This Function prototype for tcp error callback functions. Called when 
+*                    receives a RST or is unexpectedly closed for any other reason.
+*                   The corresponding socket is already freed when this callback is called!
+*
+* @param[in] skt_num    Is the socket number that returned by tls_socket_create function.
+*
+* @param[in]  err           Error code to indicate why the socket has been closed
+*                        ERR_ABRT: aborted through returning ERR_ABRT from within others
+*                                                      callback functions
+*                        ERR_RST: the connection was reset by the remote host
+*/
+typedef void  (*socket_err_fn)(u8 skt_num, err_t err);
+
+/**
+* @brief This Function prototype for socket receive callback functions. Called when data has
+*                    been received.
+*
+* @param[in] skt_num   Is the socket number that returned by tls_socket_create function.
+*
+* @param[in] p         The received data (or NULL when the connection has been closed!)
+*
+* @param[in] err       An error code if there has been an error receiving, always be ERR_OK 
+*                                    when cs mode is udp.
+*
+* @retval 			The return value is only valid for tcp receive, for upd it means nothing.
+*                   ERR_OK: Return this value after handling the received data.
+*                   ERR_ABRT:  Only return ERR_ABRT if you want to abort the socket from within the
+*                                      callback function!
+*/
+typedef err_t  (*socket_recv_fn)(u8 skt_num, struct pbuf *p, err_t err);
+
+/** 
+* @brief This Function prototype for socket srce ip callback functions. Called when data has
+*                    been received.
+*
+* @param[in] skt_num   Is the socket number that returned by tls_socket_create function.
+*
+* @param[in] datalen           The received data length
+*
+* @param[in] ipsrc         source ip addr
+*
+* @param[in] port          source port
+*
+* @param[in] err           An error code if there has been an error receiving, always be ERR_OK 
+*                                    when cs mode is udp.
+*
+* @retval			The return value is only valid for UDP receive, for udp it means nothing.
+*                   ERR_OK: Return this value after handling the received data.
+*                   ERR_ABRT:  Only return ERR_ABRT if you want to abort the socket from within the
+*                                      callback function!
+*/
+typedef err_t  (*socket_recv_ip_rpt_fn)(u8 skt_num, u16 datalen, u8 *ipsrc, u16 port, err_t err);
+
+/**
+* @brief This Function prototype for tcp connected callback functions. Called when 
+*                   connected to the remote side.
+*
+* @param[in] skt_num   Is the socket number that returned by tls_socket_create function.
+*
+* @param[in] err       An unused error code, always ERR_OK currently.
+*
+* @retval  ERR_OK: Return this value after handling your logic.
+* @retval  ERR_ABRT:  Only return ERR_ABRT if you want to abort the socket from within the
+*                                      callback function!
+*/
+typedef err_t (*socket_connected_fn)(u8 skt_num,  err_t err);
+
+/**
+* @brief This Function prototype for tcp poll callback functions. Called periodically.
+*
+* @param[in] skt_num   Is the socket number that returned by tls_socket_create function.
+*
+* @retval  ERR_OK:     Try to do something periodically.
+* @retval  ERR_ABRT:  Only return ERR_ABRT if you want to abort the socket from within the
+*                                      callback function!
+*/
+typedef err_t (*socket_poll_fn)(u8 skt_num);
+
+/**
+* @brief This Function prototype for tcp accept callback functions. Called when a new
+*                   connection can be accepted on a listening tcp.
+*
+* @param[in] skt_num   Is the socket number that returned by tls_socket_create function.
+*
+* @param[in] err       An error code if there has been an error accepting.
+*
+* @retval  ERR_OK:      Return this value after handling your logic.
+* @retval  ERR_ABRT:  Only return ERR_ABRT if you want to abort the socket from within the
+*                                      callback function!
+*/
+typedef err_t (*socket_accept_fn)(u8 skt_num, err_t err);
+
+/**
+* @brief This Function prototype for socket state changed callback functions. Called when socket
+*                   the sockte's state changed.
+*
+* @param[in] skt_num   Is the socket number that returned by tls_socket_create function.
+*
+* @param[in] event     Is the event number, see socket event defination.
+*
+* @param[in] state     Is the socket state, see socket state defination.
+*/
+typedef void(*socket_state_changed_fn)(u8 skt_num, u8 event, u8 state);
+
+/** Definitions for error constants. */
+typedef enum {
+/** No error, everything OK. */
+  ERR_OK         = 0,
+/** Out of memory error.     */
+  ERR_MEM        = -1,
+/** Buffer error.            */
+  ERR_BUF        = -2,
+/** Timeout.                 */
+  ERR_TIMEOUT    = -3,
+/** Routing problem.         */
+  ERR_RTE        = -4,
+/** Operation in progress    */
+  ERR_INPROGRESS = -5,
+/** Illegal value.           */
+  ERR_VAL        = -6,
+/** Operation would block.   */
+  ERR_WOULDBLOCK = -7,
+/** Address in use.          */
+  ERR_USE        = -8,
+/** Already connecting.      */
+  ERR_ALREADY    = -9,
+/** Conn already established.*/
+  ERR_ISCONN     = -10,
+/** Not connected.           */
+  ERR_CONN       = -11,
+/** Low-level netif error    */
+  ERR_IF         = -12,
+
+/** Connection aborted.      */
+  ERR_ABRT       = -13,
+/** Connection reset.        */
+  ERR_RST        = -14,
+/** Connection closed.       */
+  ERR_CLSD       = -15,
+/** Illegal argument.        */
+  ERR_ARG        = -16
+} err_enum_t;
+
+enum tls_socket_protocol{
+    SOCKET_PROTO_TCP,      /* TCP Protocol    */
+    SOCKET_PROTO_UDP,     /* UDP Protocol   */
+};
+
+enum tls_socket_cs_mode{
+    SOCKET_CS_MODE_CLIENT,    /* Client mode    */
+    SOCKET_CS_MODE_SERVER,    /* Server mode   */
+};
+
+struct tls_socket_desc {
+    enum tls_socket_cs_mode cs_mode;              /* Server mode  or Client mode, Only for tcp protocol is valid */
+    enum tls_socket_protocol protocol;                /* TCP Protocol or UDP Protocol  */
+    ip_addr_t  ip_addr;                                              /* Remote ip address, for tcp client mode is remote server's ip address; for tcp server mode can be any address. */
+	                                                                    /*          for udp is remote server's ip address */
+    u16 port;                                                       /* port, for tcp client mode is remote server's port; for tcp server mode is local listen port . 
+	                                                                              for udp is remote server's port */
+    u16 localport;                                               /* local port, for udp and tcp client is local listen port, for tcp server means nothing, tcp server always listen at port */
+    char host_name[32];                                     /* remote host name, not support for now  */
+    u8  host_len;                                                 /* the length of host name   */
+    u32 timeout;                                                  /* poll timeout, not implemented for now   */
+    socket_err_fn errf;                                          /* a pointer to socket_err_fn   */
+    socket_recv_fn recvf;                                      /* a pointer to socket_recv_fn  */
+    socket_connected_fn connf;                             /* a pointer to socket_connected_fn  */
+    socket_poll_fn pollf;                                        /* a pointer to socket_poll_fn  */
+    socket_accept_fn acceptf;                               /* a pointer to socket_accept_fn   */
+    socket_state_changed_fn state_changed;       /* a pointer to socket_state_changed_fn   */
+    socket_recv_ip_rpt_fn recvwithipf;           /*recv skt info report*/
+};
+
+/**
+* @brief This function is called by your application code to create a socket.
+*
+* @param[in] skd      Is a pointer to an tls_socket_desc.
+*
+* @retval	 ERR_OK    If create socket successfully.
+*              negative number   If an error was detected.
+*/
+int tls_socket_create(struct tls_socket_desc * skd);
+
+/**
+* @brief This function is called by your application code to send data by the socket.
+*
+* @param[in] skt_num      Is the socket number that returned by tls_socket_create function.
+*
+* @param[in] pdata          Is a pointer to the data which need to be send by the socket.
+*
+* @param[in] len              The data's length.
+*
+* @retval	 ERR_OK    If send data successfully.
+*              negative number   If an error was detected.
+*/
+int tls_socket_send(u8 skt_num, void *pdata, u16 len);
+
+/**
+* @brief This function is called by your application code to close the socket, and the related resources would be released.
+*
+* @param[in] skt_num      Is the socket number that returned by tls_socket_create function.
+*
+* @retval	 ERR_OK    If close socket successfully.
+*              negative number   If an error was detected.
+*/
+int tls_socket_close(u8 skt_num);
+
+struct tls_skt_status_ext_t {
+    u8 socket;
+    u8 status;
+    enum tls_socket_protocol protocol;
+    u8 host_ipaddr[4];
+    u16 remote_port;
+    u16 local_port;
+};
+
+struct tls_skt_status_t {
+    u32 socket_cnt;
+    struct tls_skt_status_ext_t skts_ext[1];
+};
+/**
+* @brief This function is called by your application code to get the socket status of specified socket num.
+*
+* @param[in] skt_num      Is the socket number that returned by tls_socket_create function.
+*
+* @param[in] buf          Is a pointer to the data contains the socket status, if the socket is server, also contains it's client's status.
+*
+* @param[in] len          The buf's length. At least, the len should be bigger than sizeof(struct tls_skt_status_t).
+*
+* @retval	 	ERR_OK    If send data successfully.
+*              negative number   If an error was detected.
+*/
+int tls_socket_get_status(u8 skt_num, u8 *buf, u32 bufsize);
+
+/**
+* @brief This function is called by your application code to send data by udp socket.
+*
+* @param[in] localport         This function will search all created sockets, if there is a socket whose localport equals this value and it's protocol is udp,
+*                                          then send the data by this socket, otherwise, nothing to send.
+*
+* @param[in] ip_addr          Is the remote ip address.
+*
+* @param[in] port               Is the remote port which upd send to.
+*
+* @param[in] pdata             Is a pointer to the data which need to be send by the socket.
+*
+* @param[in] len              The data's length.
+* @retval	 	ERR_OK    If send data successfully.
+*              negative number   If an error was detected.
+*/
+int tls_socket_udp_sendto(u16 localport, u8  *ip_addr, u16 port, void *pdata, u16 len);
+
+/**
+ * @ingroup pbuf
+ * Enumeration of pbuf layers
+ */
+typedef enum {
+  /** Includes spare room for transport layer header, e.g. UDP header.
+   * Use this if you intend to pass the pbuf to functions like udp_send().
+   */
+  PBUF_TRANSPORT,
+  /** Includes spare room for IP header.
+   * Use this if you intend to pass the pbuf to functions like raw_send().
+   */
+  PBUF_IP,
+  /** Includes spare room for link layer header (ethernet header).
+   * Use this if you intend to pass the pbuf to functions like ethernet_output().
+   * @see PBUF_LINK_HLEN
+   */
+  PBUF_LINK,
+  /** Includes spare room for additional encapsulation header before ethernet
+   * headers (e.g. 802.11).
+   * Use this if you intend to pass the pbuf to functions like netif->linkoutput().
+   * @see PBUF_LINK_ENCAPSULATION_HLEN
+   */
+  PBUF_RAW_TX,
+  /** Use this for input packets in a netif driver when calling netif->input()
+   * in the most common case - ethernet-layer netif driver. */
+  PBUF_RAW
+} pbuf_layer;
+
+/**
+ * @ingroup pbuf
+ * Enumeration of pbuf types
+ */
+typedef enum {
+  /** pbuf data is stored in RAM, used for TX mostly, struct pbuf and its payload
+      are allocated in one piece of contiguous memory (so the first payload byte
+      can be calculated from struct pbuf).
+      pbuf_alloc() allocates PBUF_RAM pbufs as unchained pbufs (although that might
+      change in future versions).
+      This should be used for all OUTGOING packets (TX).*/
+  PBUF_RAM,
+  /** pbuf data is stored in ROM, i.e. struct pbuf and its payload are located in
+      totally different memory areas. Since it points to ROM, payload does not
+      have to be copied when queued for transmission. */
+  PBUF_ROM,
+  /** pbuf comes from the pbuf pool. Much like PBUF_ROM but payload might change
+      so it has to be duplicated when queued before transmitting, depending on
+      who has a 'ref' to it. */
+  PBUF_REF,
+  /** pbuf payload refers to RAM. This one comes from a pool and should be used
+      for RX. Payload can be chained (scatter-gather RX) but like PBUF_RAM, struct
+      pbuf and its payload are allocated in one piece of contiguous memory (so
+      the first payload byte can be calculated from struct pbuf).
+      Don't use this for TX, if the pool becomes empty e.g. because of TCP queuing,
+      you are unable to receive TCP acks! */
+  PBUF_POOL
+} pbuf_type;
+
+/**
+* @brief This Function allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).
+*
+*                   The actual memory allocated for the pbuf is determined by the
+*                   layer at which the pbuf is allocated and the requested size
+*                   (from the size parameter).
+*
+* @param[in] l                   layer flag to define header size
+* @param[in] length           size of the pbuf's payload
+* @param[in] type             this parameter decides how and where the pbuf
+*
+* @retval  The allocated pbuf. If multiple pbufs where allocated, this
+*                     is the first pbuf of a pbuf chain.
+*/
+struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type);
+
+/**
+* @brief This Function for release the buffer that you receive within the socket_recv_fn callback function.
+*                   Attention please: If you return ERR_OK in the socket_recv_fn callback function, you must call this
+*                                            function to release the buffer by yourself. Otherwise, the buffer do not need be 
+*                                            released by your code.
+*
+* @param[in] p       The buffer you received in the socket_recv_fn callback function.
+*
+* @retval  The number of de-allocated pbufs
+*/
+u8 pbuf_free(struct pbuf *p);
+
+/**
+* @brief This Function for copy (part of) the contents of a packet buffer to an application supplied buffer.
+*
+* @param[in] p     the pbuf from which to copy data.
+*
+* @param[in] dataptr   the application supplied buffer
+*
+* @param[in] len      length of data to copy (dataptr must be big enough). No more 
+*                                than buf->tot_len will be copied, irrespective of len
+*
+* @param[in] offset   offset into the packet buffer from where to begin copying len bytes
+*
+* @retval  The number of bytes copied, or 0 on failure
+*/
+u16_t pbuf_copy_partial(const struct pbuf *p, void *dataptr, u16_t len, u16_t offset);
+#endif
+

+ 15 - 0
include/net/wm_sockets.h

@@ -0,0 +1,15 @@
+/**
+ * @file    wm_sockets.h
+ *
+ * @brief   socket apis
+ *
+ * @author  winnermicro
+ *
+ * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_SOCKET_API_H
+#define WM_SOCKET_API_H
+#include "wm_config.h"
+#include "wm_sockets2.0.3.h"
+#endif
+

+ 1177 - 0
include/net/wm_sockets2.0.3.h

@@ -0,0 +1,1177 @@
+/**
+ * @file    wm_sockets2.0.3.h
+ *
+ * @brief   sockets2.0.3 apis
+ *
+ * @author  winnermicro
+ *
+ * @copyright (c) 2014 Winner Microelectronics Co., Ltd.
+ */
+#ifndef WM_SOCKET_API2_0_3_H
+#define WM_SOCKET_API2_0_3_H
+
+#include <stdio.h>
+#include "wm_type_def.h"
+#include "wm_config.h"
+#include <time.h>
+
+/** If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
+typedef u8_t sa_family_t;
+#endif
+/** If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
+typedef u16_t in_port_t;
+#endif
+
+/** If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
+#if !defined(_NEWLIB_VERSION_H__)
+typedef u32_t in_addr_t;
+#endif
+#endif
+
+struct in_addr {
+  in_addr_t s_addr;
+};
+
+struct in6_addr {
+  union {
+    u32_t u32_addr[4];
+    u8_t  u8_addr[16];
+  } un;
+#define s6_addr  un.u8_addr
+};
+
+/** 255.255.255.255 */
+#define IPADDR_NONE         ((u32_t)0xffffffffUL)
+/** 127.0.0.1 */
+#define IPADDR_LOOPBACK     ((u32_t)0x7f000001UL)
+/** 0.0.0.0 */
+#define IPADDR_ANY          ((u32_t)0x00000000UL)
+/** 255.255.255.255 */
+#define IPADDR_BROADCAST    ((u32_t)0xffffffffUL)
+
+/** 255.255.255.255 */
+#define INADDR_NONE         IPADDR_NONE
+/** 127.0.0.1 */
+#define INADDR_LOOPBACK     IPADDR_LOOPBACK
+/** 0.0.0.0 */
+#define INADDR_ANY          IPADDR_ANY
+/** 255.255.255.255 */
+#define INADDR_BROADCAST    IPADDR_BROADCAST
+
+/** This macro can be used to initialize a variable of type struct in6_addr
+    to the IPv6 wildcard address. */
+#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
+/** This macro can be used to initialize a variable of type struct in6_addr
+    to the IPv6 loopback address. */
+#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
+/** This variable is initialized by the system to contain the wildcard IPv6 address. */
+extern const struct in6_addr in6addr_any;
+
+#if TLS_CONFIG_IPV4
+/** members are in network byte order */
+struct sockaddr_in {
+  u8_t            sin_len;
+  sa_family_t     sin_family;
+  in_port_t       sin_port;
+  struct in_addr  sin_addr;
+#define SIN_ZERO_LEN 8
+  char            sin_zero[SIN_ZERO_LEN];
+};
+#endif /* TLS_CONFIG_IPV4 */
+
+#if TLS_CONFIG_IPV6
+struct sockaddr_in6 {
+  u8_t            sin6_len;      /* length of this structure    */
+  sa_family_t     sin6_family;   /* AF_INET6                    */
+  in_port_t       sin6_port;     /* Transport layer port #      */
+  u32_t           sin6_flowinfo; /* IPv6 flow information       */
+  struct in6_addr sin6_addr;     /* IPv6 address                */
+  u32_t           sin6_scope_id; /* Set of interfaces for scope */
+};
+#endif /* TLS_CONFIG_IPV6 */
+
+struct sockaddr {
+  u8_t        sa_len;
+  sa_family_t sa_family;
+  char        sa_data[14];
+};
+
+struct sockaddr_storage {
+  u8_t        s2_len;
+  sa_family_t ss_family;
+  char        s2_data1[2];
+  u32_t       s2_data2[3];
+#if TLS_CONFIG_IPV6
+  u32_t       s2_data3[3];
+#endif /* TLS_CONFIG_IPV6 */
+};
+
+struct hostent {
+    char  *h_name;      /* Official name of the host. */
+    char **h_aliases;   /* A pointer to an array of pointers to alternative host names,
+                           terminated by a null pointer. */
+    int    h_addrtype;  /* Address type. */
+    int    h_length;    /* The length, in bytes, of the address. */
+    char **h_addr_list; /* A pointer to an array of pointers to network addresses (in
+                           network byte order) for the host, terminated by a null pointer. */
+#define h_addr h_addr_list[0] /* for backward compatibility */
+};
+
+struct sockaddr_store {
+  u8_t        s2_len;
+  sa_family_t ss_family;
+  char        s2_data1[2];
+  u32_t       s2_data2[3];
+#if TLS_CONFIG_IPV6
+  u32_t       s2_data3[3];
+#endif /* TLS_CONFIG_IPV6 */
+};
+
+/** If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
+typedef u32_t socklen_t;
+#endif
+
+struct lwip_sock;
+
+/** Socket protocol types (TCP/UDP/RAW) */
+#define SOCK_STREAM     1
+#define SOCK_DGRAM      2
+#define SOCK_RAW        3
+
+/**
+ * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c)
+ */
+#define SO_REUSEADDR   0x0004 /* Allow local address reuse */
+#define SO_KEEPALIVE   0x0008 /* keep connections alive */
+#define SO_BROADCAST   0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
+
+
+/**
+ * Additional options, not kept in so_options.
+ */
+#define SO_DEBUG       0x0001 /* Unimplemented: turn on debugging info recording */
+#define SO_ACCEPTCONN  0x0002 /* socket has had listen() */
+#define SO_DONTROUTE   0x0010 /* Unimplemented: just use interface addresses */
+#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
+#define SO_LINGER      0x0080 /* linger on close if data present */
+#define SO_DONTLINGER  ((int)(~SO_LINGER))
+#define SO_OOBINLINE   0x0100 /* Unimplemented: leave received OOB data in line */
+#define SO_REUSEPORT   0x0200 /* Unimplemented: allow local address & port reuse */
+#define SO_SNDBUF      0x1001 /* Unimplemented: send buffer size */
+#define SO_RCVBUF      0x1002 /* receive buffer size */
+#define SO_SNDLOWAT    0x1003 /* Unimplemented: send low-water mark */
+#define SO_RCVLOWAT    0x1004 /* Unimplemented: receive low-water mark */
+#define SO_SNDTIMEO    0x1005 /* send timeout */
+#define SO_RCVTIMEO    0x1006 /* receive timeout */
+#define SO_ERROR       0x1007 /* get error status and clear */
+#define SO_TYPE        0x1008 /* get socket type */
+#define SO_CONTIMEO    0x1009 /* Unimplemented: connect timeout */
+#define SO_NO_CHECK    0x100a /* don't create UDP checksum */
+
+/**
+ * Structure used for manipulating linger option.
+ */
+struct linger {
+       int l_onoff;                /* option on/off */
+       int l_linger;               /* linger time in seconds */
+};
+
+/**
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define  SOL_SOCKET  0xfff    /* options for socket level */
+
+
+#define AF_UNSPEC       0
+#define AF_INET         2
+#if TLS_CONFIG_IPV6
+#define AF_INET6        10
+#else /* TLS_CONFIG_IPV6 */
+#define AF_INET6        AF_UNSPEC
+#endif /* TLS_CONFIG_IPV6 */
+#define PF_INET         AF_INET
+#define PF_INET6        AF_INET6
+#define PF_UNSPEC       AF_UNSPEC
+
+#define IPPROTO_IP      0
+#define IPPROTO_ICMP    1
+#define IPPROTO_TCP     6
+#define IPPROTO_UDP     17
+#if TLS_CONFIG_IPV6
+#define IPPROTO_IPV6    41
+#define IPPROTO_ICMPV6  58
+#endif /* TLS_CONFIG_IPV6 */
+#define IPPROTO_UDPLITE 136
+#define IPPROTO_RAW     255
+
+/** Flags we can use with send and recv. */
+#define MSG_PEEK       0x01    /* Peeks at an incoming message */
+#define MSG_WAITALL    0x02    /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */
+#define MSG_OOB        0x04    /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
+#define MSG_DONTWAIT   0x08    /* Nonblocking i/o for this operation only */
+#define MSG_MORE       0x10    /* Sender will send more */
+
+
+/**
+ * Options for level IPPROTO_IP
+ */
+#define IP_TOS             1
+#define IP_TTL             2
+
+
+/*
+ * Options for level IPPROTO_TCP
+ */
+#define TCP_NODELAY    0x01    /* don't delay send to coalesce packets */
+#define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
+#define TCP_KEEPIDLE   0x03    /* set pcb->keep_idle  - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
+#define TCP_KEEPINTVL  0x04    /* set pcb->keep_intvl - Use seconds for get/setsockopt */
+#define TCP_KEEPCNT    0x05    /* set pcb->keep_cnt   - Use number of probes sent for get/setsockopt */
+
+#if TLS_CONFIG_IPV6
+/**
+ * Options for level IPPROTO_IPV6
+ */
+#define IPV6_CHECKSUM       7  /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */
+#define IPV6_V6ONLY         27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */
+#endif /* TLS_CONFIG_IPV6 */
+
+/**
+ * Options for level IPPROTO_UDPLITE
+ */
+#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
+#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
+
+#if TLS_CONFIG_IGMP
+/**
+ * Options and types for UDP multicast traffic handling
+ */
+#define IP_MULTICAST_TTL   5
+#define IP_MULTICAST_IF    6
+#define IP_MULTICAST_LOOP  7
+#endif /* TLS_CONFIG_IGMP */
+
+#if 1// TLS_CONFIG_IGMP
+/**
+ * Options and types related to multicast membership
+ */
+#define IP_ADD_MEMBERSHIP  3
+#define IP_DROP_MEMBERSHIP 4
+
+typedef struct ip_mreq {
+    struct in_addr imr_multiaddr; /* IP multicast address of group */
+    struct in_addr imr_interface; /* local IP address of interface */
+} ip_mreq;
+
+#if TLS_CONFIG_IPV6
+#define IPV6_JOIN_GROUP    38
+#define IPV6_LEAVE_GROUP    39
+typedef struct ipv6_mreq {
+    struct in6_addr ipv6mr_multiaddr; /* IP multicast address of group */
+    int ipv6mr_interface; /* index of interface */
+} ipv6_mreq;
+#endif
+#endif /* TLS_CONFIG_IGMP */
+
+/**
+ * @brief The Type of Service provides an indication of the abstract
+ * parameters of the quality of service desired.  These parameters are
+ * to be used to guide the selection of the actual service parameters
+ * when transmitting a datagram through a particular network.  Several
+ * networks offer service precedence, which somehow treats high
+ * precedence traffic as more important than other traffic (generally
+ * by accepting only traffic above a certain precedence at time of high
+ * load).  The major choice is a three way tradeoff between low-delay,
+ * high-reliability, and high-throughput.
+ * The use of the Delay, Throughput, and Reliability indications may
+ * increase the cost (in some sense) of the service.  In many networks
+ * better performance for one of these parameters is coupled with worse
+ * performance on another.  Except for very unusual cases at most two
+ * of these three indications should be set.
+ */
+#define IPTOS_TOS_MASK          0x1E
+#define IPTOS_TOS(tos)          ((tos) & IPTOS_TOS_MASK)
+#define IPTOS_LOWDELAY          0x10
+#define IPTOS_THROUGHPUT        0x08
+#define IPTOS_RELIABILITY       0x04
+#define IPTOS_LOWCOST           0x02
+#define IPTOS_MINCOST           IPTOS_LOWCOST
+
+/*
+ * @brief The Network Control precedence designation is intended to be used
+ * within a network only.  The actual use and control of that
+ * designation is up to each network. The Internetwork Control
+ * designation is intended for use by gateway control originators only.
+ * If the actual use of these precedence designations is of concern to
+ * a particular network, it is the responsibility of that network to
+ * control the access to, and use of, those precedence designations.
+ */
+#define IPTOS_PREC_MASK                 0xe0
+#define IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
+#define IPTOS_PREC_NETCONTROL           0xe0
+#define IPTOS_PREC_INTERNETCONTROL      0xc0
+#define IPTOS_PREC_CRITIC_ECP           0xa0
+#define IPTOS_PREC_FLASHOVERRIDE        0x80
+#define IPTOS_PREC_FLASH                0x60
+#define IPTOS_PREC_IMMEDIATE            0x40
+#define IPTOS_PREC_PRIORITY             0x20
+#define IPTOS_PREC_ROUTINE              0x00
+
+
+/*
+ * @brief Commands for ioctlsocket(),  taken from the BSD file fcntl.h.
+ * lwip_ioctl only supports FIONREAD and FIONBIO, for now
+ *
+ * Ioctl's have the command encoded in the lower word,
+ * and the size of any in or out parameters in the upper
+ * word.  The high 2 bits of the upper word are used
+ * to encode the in/out status of the parameter; for now
+ * we restrict parameters to at most 128 bytes.
+ */
+#if !defined(FIONREAD) || !defined(FIONBIO)
+#define IOCPARM_MASK    0x7fU           /* parameters must be < 128 bytes */
+#define IOC_VOID        0x20000000UL    /* no parameters */
+#define IOC_OUT         0x40000000UL    /* copy out parameters */
+#define IOC_IN          0x80000000UL    /* copy in parameters */
+#define IOC_INOUT       (IOC_IN|IOC_OUT)
+                                        /* 0x20000000 distinguishes new &
+                                           old ioctl's */
+#define _IO(x,y)        (IOC_VOID|((x)<<8)|(y))
+
+#define _IOR(x,y,t)     (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
+
+#define _IOW(x,y,t)     (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
+#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
+
+#ifndef FIONREAD
+#define FIONREAD    _IOR('f', 127, unsigned long) /* get # bytes to read */
+#endif
+#ifndef FIONBIO
+#define FIONBIO     _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
+#endif
+
+/** Socket I/O Controls: unimplemented */
+#ifndef SIOCSHIWAT
+#define SIOCSHIWAT  _IOW('s',  0, unsigned long)  /* set high watermark */
+#define SIOCGHIWAT  _IOR('s',  1, unsigned long)  /* get high watermark */
+#define SIOCSLOWAT  _IOW('s',  2, unsigned long)  /* set low watermark */
+#define SIOCGLOWAT  _IOR('s',  3, unsigned long)  /* get low watermark */
+#define SIOCATMARK  _IOR('s',  7, unsigned long)  /* at oob mark? */
+#endif
+
+/** commands for fnctl */
+#ifndef F_GETFL
+#define F_GETFL 3
+#endif
+#ifndef F_SETFL
+#define F_SETFL 4
+#endif
+
+/** File status flags and file access modes for fnctl,
+   these are bits in an int. */
+#ifndef O_NONBLOCK
+#define O_NONBLOCK  1 /* nonblocking I/O */
+#endif
+#ifndef O_NDELAY
+#define O_NDELAY    1 /* same as O_NONBLOCK, for compatibility */
+#endif
+
+#ifndef SHUT_RD
+  #define SHUT_RD   0
+  #define SHUT_WR   1
+  #define SHUT_RDWR 2
+#endif
+
+/** FD_SET used for lwip_select */
+#ifndef FD_SET
+#undef  FD_SETSIZE
+
+#ifndef LWIP_SOCKET_OFFSET
+#define LWIP_SOCKET_OFFSET              0
+#endif
+
+#ifndef MEMP_NUM_NETCONN
+#define MEMP_NUM_NETCONN                8
+#endif
+
+/** Make FD_SETSIZE match NUM_SOCKETS in socket.c */
+#define FD_SETSIZE    MEMP_NUM_NETCONN
+#define FDSETSAFESET(n, code) do { \
+  if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \
+  code; }} while(0)
+#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
+  (code) : 0)
+#define FD_SET(n, p)  FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |=  (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
+#define FD_CLR(n, p)  FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
+#define FD_ISSET(n,p) FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &   (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
+#define FD_ZERO(p)    memset((void*)(p), 0, sizeof(*(p)))
+
+typedef struct fd_set
+{
+  unsigned char fd_bits [(FD_SETSIZE+7)/8];
+} fd_set;
+
+#elif LWIP_SOCKET_OFFSET
+#error LWIP_SOCKET_OFFSET does not work with external FD_SET!
+#endif /* FD_SET */
+
+/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
+ * by your system, set this to 0 and include <sys/time.h> in cc.h */
+#ifndef LWIP_TIMEVAL_PRIVATE
+#define LWIP_TIMEVAL_PRIVATE 0
+#endif
+
+#if LWIP_TIMEVAL_PRIVATE
+struct timeval {
+  long    tv_sec;         /* seconds */
+  long    tv_usec;        /* and microseconds */
+};
+#endif /* LWIP_TIMEVAL_PRIVATE */
+int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+
+int bind(int s, const struct sockaddr *name, socklen_t namelen);
+
+int shutdown(int s, int how);
+
+int closesocket(int s);
+
+int connect(int s, const struct sockaddr *name, socklen_t namelen);
+
+int getsockname(int s, struct sockaddr *name, socklen_t *namelen);
+
+int getpeername(int s, struct sockaddr *name, socklen_t *namelen);
+
+int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
+
+int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);
+
+int listen(int s, int backlog);
+
+int recv(int s, void *mem, size_t len, int flags);
+
+int recvfrom(int s, void *mem, size_t len, int flags,
+        struct sockaddr *from, socklen_t *fromlen);
+
+int send(int s, const void *data, size_t size, int flags);
+
+int sendto(int s, const void *data, size_t size, int flags,
+       const struct sockaddr *to, socklen_t tolen);
+
+int socket(int domain, int type, int protocol);
+
+int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
+            struct timeval *timeout);
+
+int ioctlsocket(int s, long cmd, void *argp);
+
+int fcntl(int s, int cmd, int val);
+
+struct hostent* gethostbyname(const char *name);
+
+/** @ingroup socket */
+#define read(s,mem,len)                           recv(s,mem,len,0)
+/** @ingroup socket */
+#define write(s,dataptr,len)                      send(s,dataptr,len,0)
+/** @ingroup socket */
+#define close(s)                                  closesocket(s)
+/** @ingroup socket */
+#define ioctl(s,cmd,argp)                         ioctlsocket(s,cmd,argp)
+
+u32_t ipaddr_addr(const char *cp);
+
+#ifdef htonl
+#undef htonl
+#endif /* htonl */
+#ifdef ntohl
+#undef ntohl
+#endif /* ntohl */
+#ifdef htons
+#undef htons
+#endif /* htons */
+#ifdef ntohs
+#undef ntohs
+#endif /* ntohs */
+
+#define htons(n) 				(((n & 0xff) << 8) | ((n & 0xff00) >> 8))
+#define htonl(n) 				(((n & 0xff) << 24) |\
+			    				((n & 0xff00) << 8) |\
+			   				((n & 0xff0000UL) >> 8) |\
+			    				((n & 0xff000000UL) >> 24))
+#define ntohs(n) 				htons(n)
+#define ntohl(n) 				htonl(n)
+
+/** Create u32_t value from bytes */
+#define LWIP_MAKEU32(a,b,c,d) (((u32_t)((a) & 0xff) << 24) | \
+                               ((u32_t)((b) & 0xff) << 16) | \
+                               ((u32_t)((c) & 0xff) << 8)  | \
+                                (u32_t)((d) & 0xff))
+#define PP_HTONL(x) ((((x) & 0x000000ffUL) << 24) | \
+                     (((x) & 0x0000ff00UL) <<  8) | \
+                     (((x) & 0x00ff0000UL) >>  8) | \
+                     (((x) & 0xff000000UL) >> 24))
+
+#if TLS_CONFIG_IPV4
+/** This is the aligned version of ip4_addr_t,
+   used as local variable, on the stack, etc. */
+struct ip4_addr {
+  u32_t addr;
+};
+
+/** ip4_addr_t uses a struct for convenience only, so that the same defines can
+ * operate both on ip4_addr_t as well as on ip4_addr_p_t. */
+typedef struct ip4_addr ip4_addr_t;
+
+/** Set an IP address given by the four byte-parts */
+#define IP4_ADDR(ipaddr, a,b,c,d)  (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(a,b,c,d))
+
+/** MEMCPY-like copying of IP addresses where addresses are known to be
+ * 16-bit-aligned if the port is correctly configured (so a port could define
+ * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */
+#ifndef IPADDR2_COPY
+#define IPADDR2_COPY(dest, src) SMEMCPY(dest, src, sizeof(ip4_addr_t))
+#endif
+
+/** Copy IP address - faster than ip4_addr_set: no NULL check */
+#define ip4_addr_copy(dest, src) ((dest).addr = (src).addr)
+/** Safely copy one IP address to another (src may be NULL) */
+#define ip4_addr_set(dest, src) ((dest)->addr = \
+                                    ((src) == NULL ? 0 : \
+                                    (src)->addr))
+/** Set complete address to zero */
+#define ip4_addr_set_zero(ipaddr)     ((ipaddr)->addr = 0)
+/** Set address to IPADDR_ANY (no need for lwip_htonl()) */
+#define ip4_addr_set_any(ipaddr)      ((ipaddr)->addr = IPADDR_ANY)
+/** Set address to loopback address */
+#define ip4_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK))
+/** Check if an address is in the loopback region */
+#define ip4_addr_isloopback(ipaddr)    (((ipaddr)->addr & PP_HTONL(IP_CLASSA_NET)) == PP_HTONL(((u32_t)IP_LOOPBACKNET) << 24))
+/** Safely copy one IP address to another and change byte order
+ * from host- to network-order. */
+#define ip4_addr_set_hton(dest, src) ((dest)->addr = \
+                               ((src) == NULL ? 0:\
+                               lwip_htonl((src)->addr)))
+/** IPv4 only: set the IP address given as an u32_t */
+#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
+/** IPv4 only: get the IP address as an u32_t */
+#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr)
+
+/** Get the network address by combining host address with netmask */
+#define ip4_addr_get_network(target, host, netmask) do { ((target)->addr = ((host)->addr) & ((netmask)->addr)); } while(0)
+
+/**
+ * @brief Determine if two address are on the same network.
+ *
+ * @arg addr1 IP address 1
+ * @arg addr2 IP address 2
+ * @arg mask network identifier mask
+ * @return !0 if the network identifiers of both address match
+ */
+#define ip4_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \
+                                              (mask)->addr) == \
+                                             ((addr2)->addr & \
+                                              (mask)->addr))
+#define ip4_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
+
+#define ip4_addr_isany_val(addr1)   ((addr1).addr == IPADDR_ANY)
+#define ip4_addr_isany(addr1) ((addr1) == NULL || ip4_addr_isany_val(*(addr1)))
+
+#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr)
+u8_t ip4_addr_netmask_valid(u32_t netmask);
+
+#define ip4_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL))
+
+#define ip4_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL))
+
+#define ip4_addr_debug_print_parts(debug, a, b, c, d) \
+  LWIP_DEBUGF(debug, ("%" U16_F ".%" U16_F ".%" U16_F ".%" U16_F, a, b, c, d))
+#define ip4_addr_debug_print(debug, ipaddr) \
+  ip4_addr_debug_print_parts(debug, \
+                      (u16_t)((ipaddr) != NULL ? ip4_addr1_16(ipaddr) : 0),       \
+                      (u16_t)((ipaddr) != NULL ? ip4_addr2_16(ipaddr) : 0),       \
+                      (u16_t)((ipaddr) != NULL ? ip4_addr3_16(ipaddr) : 0),       \
+                      (u16_t)((ipaddr) != NULL ? ip4_addr4_16(ipaddr) : 0))
+#define ip4_addr_debug_print_val(debug, ipaddr) \
+  ip4_addr_debug_print_parts(debug, \
+                      ip4_addr1_16(&(ipaddr)),       \
+                      ip4_addr2_16(&(ipaddr)),       \
+                      ip4_addr3_16(&(ipaddr)),       \
+                      ip4_addr4_16(&(ipaddr)))
+
+/** Get one byte from the 4-byte address */
+#define ip4_addr1(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[0])
+#define ip4_addr2(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[1])
+#define ip4_addr3(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[2])
+#define ip4_addr4(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[3])
+/** These are cast to u16_t, with the intent that they are often arguments
+ * to printf using the U16_F format from cc.h. */
+#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr))
+#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr))
+#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr))
+#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr))
+
+#define IP4ADDR_STRLEN_MAX  16
+
+/** For backwards compatibility */
+#define ip_ntoa(ipaddr)  ipaddr_ntoa(ipaddr)
+
+u32_t ipaddr_addr(const char *cp);
+int ip4addr_aton(const char *cp, ip4_addr_t *addr);
+/** returns ptr to static buffer; not reentrant! */
+char *ip4addr_ntoa(const ip4_addr_t *addr);
+char *ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen);
+
+
+/** directly map this to the lwip internal functions */
+#define inet_addr(cp)                   ipaddr_addr(cp)
+#define inet_aton(cp, addr)             ip4addr_aton(cp, (ip4_addr_t*)addr)
+#define inet_ntoa(addr)       ipaddr_ntoa((ip_addr_t*)&(addr))
+#endif
+
+#if TLS_CONFIG_IPV6
+/** This is the aligned version of ip6_addr_t,
+    used as local variable, on the stack, etc. */
+struct ip6_addr {
+  u32_t addr[4];
+};
+
+/** IPv6 address */
+typedef struct ip6_addr ip6_addr_t;
+
+/** Set an IPv6 partial address given by byte-parts */
+#define IP6_ADDR_PART(ip6addr, index, a,b,c,d) \
+  (ip6addr)->addr[index] = PP_HTONL(LWIP_MAKEU32(a,b,c,d))
+
+/** Set a full IPv6 address by passing the 4 u32_t indices in network byte order
+    (use PP_HTONL() for constants) */
+#define IP6_ADDR(ip6addr, idx0, idx1, idx2, idx3) do { \
+  (ip6addr)->addr[0] = idx0; \
+  (ip6addr)->addr[1] = idx1; \
+  (ip6addr)->addr[2] = idx2; \
+  (ip6addr)->addr[3] = idx3; } while(0)
+
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK1(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[0]) >> 16) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK2(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[0])) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK3(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[1]) >> 16) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK4(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[1])) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK5(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[2]) >> 16) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK6(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[2])) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK7(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[3]) >> 16) & 0xffff))
+/** Access address in 16-bit block */
+#define IP6_ADDR_BLOCK8(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[3])) & 0xffff))
+
+/** Copy IPv6 address - faster than ip6_addr_set: no NULL check */
+#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \
+                                    (dest).addr[1] = (src).addr[1]; \
+                                    (dest).addr[2] = (src).addr[2]; \
+                                    (dest).addr[3] = (src).addr[3];}while(0)
+/** Safely copy one IPv6 address to another (src may be NULL) */
+#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \
+                                   (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \
+                                   (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \
+                                   (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0)
+
+/** Set complete address to zero */
+#define ip6_addr_set_zero(ip6addr)    do{(ip6addr)->addr[0] = 0; \
+                                         (ip6addr)->addr[1] = 0; \
+                                         (ip6addr)->addr[2] = 0; \
+                                         (ip6addr)->addr[3] = 0;}while(0)
+
+/** Set address to ipv6 'any' (no need for lwip_htonl()) */
+#define ip6_addr_set_any(ip6addr)       ip6_addr_set_zero(ip6addr)
+/** Set address to ipv6 loopback address */
+#define ip6_addr_set_loopback(ip6addr) do{(ip6addr)->addr[0] = 0; \
+                                          (ip6addr)->addr[1] = 0; \
+                                          (ip6addr)->addr[2] = 0; \
+                                          (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0)
+/** Safely copy one IPv6 address to another and change byte order
+ * from host- to network-order. */
+#define ip6_addr_set_hton(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : lwip_htonl((src)->addr[0]); \
+                                        (dest)->addr[1] = (src) == NULL ? 0 : lwip_htonl((src)->addr[1]); \
+                                        (dest)->addr[2] = (src) == NULL ? 0 : lwip_htonl((src)->addr[2]); \
+                                        (dest)->addr[3] = (src) == NULL ? 0 : lwip_htonl((src)->addr[3]);}while(0)
+
+
+/**
+ * @brief  Determine if two IPv6 address are on the same network.
+ *
+ * @arg addr1 IPv6 address 1
+ * @arg addr2 IPv6 address 2
+ * @return !0 if the network identifiers of both address match
+ */
+#define ip6_addr_netcmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
+                                       ((addr1)->addr[1] == (addr2)->addr[1]))
+
+#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
+                                    ((addr1)->addr[1] == (addr2)->addr[1]) && \
+                                    ((addr1)->addr[2] == (addr2)->addr[2]) && \
+                                    ((addr1)->addr[3] == (addr2)->addr[3]))
+
+#define ip6_get_subnet_id(ip6addr)   (lwip_htonl((ip6addr)->addr[2]) & 0x0000ffffUL)
+
+#define ip6_addr_isany_val(ip6addr) (((ip6addr).addr[0] == 0) && \
+                                     ((ip6addr).addr[1] == 0) && \
+                                     ((ip6addr).addr[2] == 0) && \
+                                     ((ip6addr).addr[3] == 0))
+#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || ip6_addr_isany_val(*(ip6addr)))
+
+#define ip6_addr_isloopback(ip6addr) (((ip6addr)->addr[0] == 0UL) && \
+                                      ((ip6addr)->addr[1] == 0UL) && \
+                                      ((ip6addr)->addr[2] == 0UL) && \
+                                      ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
+
+#define ip6_addr_isglobal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xe0000000UL)) == PP_HTONL(0x20000000UL))
+
+#define ip6_addr_islinklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfe800000UL))
+
+#define ip6_addr_issitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfec00000UL))
+
+#define ip6_addr_isuniquelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xfe000000UL)) == PP_HTONL(0xfc000000UL))
+
+#define ip6_addr_isipv4mappedipv6(ip6addr) (((ip6addr)->addr[0] == 0) && ((ip6addr)->addr[1] == 0) && (((ip6addr)->addr[2]) == PP_HTONL(0x0000FFFFUL)))
+
+#define ip6_addr_ismulticast(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL))
+#define ip6_addr_multicast_transient_flag(ip6addr)  ((ip6addr)->addr[0] & PP_HTONL(0x00100000UL))
+#define ip6_addr_multicast_prefix_flag(ip6addr)     ((ip6addr)->addr[0] & PP_HTONL(0x00200000UL))
+#define ip6_addr_multicast_rendezvous_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00400000UL))
+#define ip6_addr_multicast_scope(ip6addr) ((lwip_htonl((ip6addr)->addr[0]) >> 16) & 0xf)
+#define IP6_MULTICAST_SCOPE_RESERVED            0x0
+#define IP6_MULTICAST_SCOPE_RESERVED0           0x0
+#define IP6_MULTICAST_SCOPE_INTERFACE_LOCAL     0x1
+#define IP6_MULTICAST_SCOPE_LINK_LOCAL          0x2
+#define IP6_MULTICAST_SCOPE_RESERVED3           0x3
+#define IP6_MULTICAST_SCOPE_ADMIN_LOCAL         0x4
+#define IP6_MULTICAST_SCOPE_SITE_LOCAL          0x5
+#define IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL  0x8
+#define IP6_MULTICAST_SCOPE_GLOBAL              0xe
+#define IP6_MULTICAST_SCOPE_RESERVEDF           0xf
+#define ip6_addr_ismulticast_iflocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff010000UL))
+#define ip6_addr_ismulticast_linklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff020000UL))
+#define ip6_addr_ismulticast_adminlocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff040000UL))
+#define ip6_addr_ismulticast_sitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff050000UL))
+#define ip6_addr_ismulticast_orglocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff080000UL))
+#define ip6_addr_ismulticast_global(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff0e0000UL))
+
+/** @todo define get/set for well-know multicast addresses, e.g. ff02::1 */
+#define ip6_addr_isallnodes_iflocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff010000UL)) && \
+    ((ip6addr)->addr[1] == 0UL) && \
+    ((ip6addr)->addr[2] == 0UL) && \
+    ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
+
+#define ip6_addr_isallnodes_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
+    ((ip6addr)->addr[1] == 0UL) && \
+    ((ip6addr)->addr[2] == 0UL) && \
+    ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
+#define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
+                (ip6addr)->addr[1] = 0; \
+                (ip6addr)->addr[2] = 0; \
+                (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0)
+
+#define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
+    ((ip6addr)->addr[1] == 0UL) && \
+    ((ip6addr)->addr[2] == 0UL) && \
+    ((ip6addr)->addr[3] == PP_HTONL(0x00000002UL)))
+#define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
+                (ip6addr)->addr[1] = 0; \
+                (ip6addr)->addr[2] = 0; \
+                (ip6addr)->addr[3] = PP_HTONL(0x00000002UL);}while(0)
+
+#define ip6_addr_issolicitednode(ip6addr) ( ((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
+        ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \
+        (((ip6addr)->addr[3] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) )
+
+#define ip6_addr_set_solicitednode(ip6addr, if_id) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
+                (ip6addr)->addr[1] = 0; \
+                (ip6addr)->addr[2] = PP_HTONL(0x00000001UL); \
+                (ip6addr)->addr[3] = (PP_HTONL(0xff000000UL) | (if_id));}while(0)
+
+#define ip6_addr_cmp_solicitednode(ip6addr, sn_addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
+                                    ((ip6addr)->addr[1] == 0) && \
+                                    ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \
+                                    ((ip6addr)->addr[3] == (PP_HTONL(0xff000000UL) | (sn_addr)->addr[3])))
+
+/* IPv6 address states. */
+#define IP6_ADDR_INVALID      0x00
+#define IP6_ADDR_TENTATIVE    0x08
+#define IP6_ADDR_TENTATIVE_1  0x09 /* 1 probe sent */
+#define IP6_ADDR_TENTATIVE_2  0x0a /* 2 probes sent */
+#define IP6_ADDR_TENTATIVE_3  0x0b /* 3 probes sent */
+#define IP6_ADDR_TENTATIVE_4  0x0c /* 4 probes sent */
+#define IP6_ADDR_TENTATIVE_5  0x0d /* 5 probes sent */
+#define IP6_ADDR_TENTATIVE_6  0x0e /* 6 probes sent */
+#define IP6_ADDR_TENTATIVE_7  0x0f /* 7 probes sent */
+#define IP6_ADDR_VALID        0x10 /* This bit marks an address as valid (preferred or deprecated) */
+#define IP6_ADDR_PREFERRED    0x30
+#define IP6_ADDR_DEPRECATED   0x10 /* Same as VALID (valid but not preferred) */
+
+#define IP6_ADDR_TENTATIVE_COUNT_MASK 0x07 /* 1-7 probes sent */
+
+#define ip6_addr_isinvalid(addr_state) (addr_state == IP6_ADDR_INVALID)
+#define ip6_addr_istentative(addr_state) (addr_state & IP6_ADDR_TENTATIVE)
+#define ip6_addr_isvalid(addr_state) (addr_state & IP6_ADDR_VALID) /* Include valid, preferred, and deprecated. */
+#define ip6_addr_ispreferred(addr_state) (addr_state == IP6_ADDR_PREFERRED)
+#define ip6_addr_isdeprecated(addr_state) (addr_state == IP6_ADDR_DEPRECATED)
+
+#define ip6_addr_debug_print_parts(debug, a, b, c, d, e, f, g, h) \
+  LWIP_DEBUGF(debug, ("%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F, \
+                      a, b, c, d, e, f, g, h))
+#define ip6_addr_debug_print(debug, ipaddr) \
+  ip6_addr_debug_print_parts(debug, \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK1(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK2(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK3(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK4(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK5(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK6(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK7(ipaddr) : 0),    \
+                      (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK8(ipaddr) : 0))
+#define ip6_addr_debug_print_val(debug, ipaddr) \
+  ip6_addr_debug_print_parts(debug, \
+                      IP6_ADDR_BLOCK1(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK2(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK3(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK4(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK5(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK6(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK7(&(ipaddr)),    \
+                      IP6_ADDR_BLOCK8(&(ipaddr)))
+
+#define IP6ADDR_STRLEN_MAX    46
+
+int ip6addr_aton(const char *cp, ip6_addr_t *addr);
+/** returns ptr to static buffer; not reentrant! */
+char *ip6addr_ntoa(const ip6_addr_t *addr);
+char *ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen);
+                                    
+#endif
+
+/** @ingroup ipaddr
+ * IP address types for use in ip_addr_t.type member.
+ * @see tcp_new_ip_type(), udp_new_ip_type(), raw_new_ip_type().
+ */
+enum lwip_ip_addr_type {
+  /** IPv4 */
+  IPADDR_TYPE_V4 =   0U,
+  /** IPv6 */
+  IPADDR_TYPE_V6 =   6U,
+  /** IPv4+IPv6 ("dual-stack") */
+  IPADDR_TYPE_ANY = 46U
+};
+
+#if TLS_CONFIG_IPV4&&TLS_CONFIG_IPV6
+/**
+ * @ingroup ipaddr
+ * A union struct for both IP version's addresses.
+ * ATTENTION: watch out for its size when adding IPv6 address scope!
+ */
+typedef struct ip_addr {
+  union {
+    ip6_addr_t ip6;
+    ip4_addr_t ip4;
+  } u_addr;
+  /** @ref lwip_ip_addr_type */
+  u8_t type;
+} ip_addr_t;
+
+extern const ip_addr_t ip_addr_any_type;
+
+/** @ingroup ip4addr */
+#define IPADDR4_INIT(u32val)          { { { { u32val, 0ul, 0ul, 0ul } } }, IPADDR_TYPE_V4 }
+/** @ingroup ip4addr */
+#define IPADDR4_INIT_BYTES(a,b,c,d)   IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d)))
+/** @ingroup ip6addr */
+#define IPADDR6_INIT(a, b, c, d)      { { { { a, b, c, d } } }, IPADDR_TYPE_V6 }
+/** @ingroup ip6addr */
+#define IPADDR6_INIT_HOST(a, b, c, d) { { { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } } }, IPADDR_TYPE_V6 }
+
+/** @ingroup ipaddr */
+#define IP_IS_ANY_TYPE_VAL(ipaddr)    (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_ANY)
+/** @ingroup ipaddr */
+#define IPADDR_ANY_TYPE_INIT          { { { { 0ul, 0ul, 0ul, 0ul } } }, IPADDR_TYPE_ANY }
+
+/** @ingroup ip4addr */
+#define IP_IS_V4_VAL(ipaddr)          (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V4)
+/** @ingroup ip6addr */
+#define IP_IS_V6_VAL(ipaddr)          (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V6)
+/** @ingroup ip4addr */
+#define IP_IS_V4(ipaddr)              (((ipaddr) == NULL) || IP_IS_V4_VAL(*(ipaddr)))
+/** @ingroup ip6addr */
+#define IP_IS_V6(ipaddr)              (((ipaddr) != NULL) && IP_IS_V6_VAL(*(ipaddr)))
+
+#define IP_SET_TYPE_VAL(ipaddr, iptype) do { (ipaddr).type = (iptype); }while(0)
+#define IP_SET_TYPE(ipaddr, iptype)     do { if((ipaddr) != NULL) { IP_SET_TYPE_VAL(*(ipaddr), iptype); }}while(0)
+#define IP_GET_TYPE(ipaddr)           ((ipaddr)->type)
+
+#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) (IP_GET_TYPE(&pcb->local_ip) == IP_GET_TYPE(ipaddr))
+#define IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr) (IP_IS_ANY_TYPE_VAL(pcb->local_ip) || IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr))
+
+/** @ingroup ip6addr
+ * Convert generic ip address to specific protocol version
+ */
+#define ip_2_ip6(ipaddr)   (&((ipaddr)->u_addr.ip6))
+/** @ingroup ip4addr
+ * Convert generic ip address to specific protocol version
+ */
+#define ip_2_ip4(ipaddr)   (&((ipaddr)->u_addr.ip4))
+
+/** @ingroup ip4addr */
+#define IP_ADDR4(ipaddr,a,b,c,d)      do { IP4_ADDR(ip_2_ip4(ipaddr),a,b,c,d); \
+                                           IP_SET_TYPE_VAL(*(ipaddr), IPADDR_TYPE_V4); } while(0)
+/** @ingroup ip6addr */
+#define IP_ADDR6(ipaddr,i0,i1,i2,i3)  do { IP6_ADDR(ip_2_ip6(ipaddr),i0,i1,i2,i3); \
+                                           IP_SET_TYPE_VAL(*(ipaddr), IPADDR_TYPE_V6); } while(0)
+/** @ingroup ip6addr */
+#define IP_ADDR6_HOST(ipaddr,i0,i1,i2,i3)  IP_ADDR6(ipaddr,PP_HTONL(i0),PP_HTONL(i1),PP_HTONL(i2),PP_HTONL(i3))
+
+/** @ingroup ipaddr */
+#define ip_addr_copy(dest, src)      do{ IP_SET_TYPE_VAL(dest, IP_GET_TYPE(&src)); if(IP_IS_V6_VAL(src)){ \
+  ip6_addr_copy(*ip_2_ip6(&(dest)), *ip_2_ip6(&(src))); }else{ \
+  ip4_addr_copy(*ip_2_ip4(&(dest)), *ip_2_ip4(&(src))); }}while(0)
+/** @ingroup ip6addr */
+#define ip_addr_copy_from_ip6(dest, src)      do{ \
+  ip6_addr_copy(*ip_2_ip6(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V6); }while(0)
+/** @ingroup ip4addr */
+#define ip_addr_copy_from_ip4(dest, src)      do{ \
+  ip4_addr_copy(*ip_2_ip4(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V4); }while(0)
+/** @ingroup ip4addr */
+#define ip_addr_set_ip4_u32(ipaddr, val)  do{if(ipaddr){ip4_addr_set_u32(ip_2_ip4(ipaddr), val); \
+  IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0)
+/** @ingroup ip4addr */
+#define ip_addr_get_ip4_u32(ipaddr)  (((ipaddr) && IP_IS_V4(ipaddr)) ? \
+  ip4_addr_get_u32(ip_2_ip4(ipaddr)) : 0)
+/** @ingroup ipaddr */
+#define ip_addr_set(dest, src) do{ IP_SET_TYPE(dest, IP_GET_TYPE(src)); if(IP_IS_V6(src)){ \
+  ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); }else{ \
+  ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_set_ipaddr(dest, src) ip_addr_set(dest, src)
+/** @ingroup ipaddr */
+#define ip_addr_set_zero(ipaddr)     do{ \
+  ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, 0); }while(0)
+/** @ingroup ip5addr */
+#define ip_addr_set_zero_ip4(ipaddr)     do{ \
+  ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }while(0)
+/** @ingroup ip6addr */
+#define ip_addr_set_zero_ip6(ipaddr)     do{ \
+  ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }while(0)
+/** @ingroup ipaddr */
+#define ip_addr_set_any(is_ipv6, ipaddr)      do{if(is_ipv6){ \
+  ip6_addr_set_any(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \
+  ip4_addr_set_any(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_set_loopback(is_ipv6, ipaddr) do{if(is_ipv6){ \
+  ip6_addr_set_loopback(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \
+  ip4_addr_set_loopback(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_set_hton(dest, src)  do{if(IP_IS_V6(src)){ \
+  ip6_addr_set_hton(ip_2_ip6(ipaddr), (src)); IP_SET_TYPE(dest, IPADDR_TYPE_V6); }else{ \
+  ip4_addr_set_hton(ip_2_ip4(ipaddr), (src)); IP_SET_TYPE(dest, IPADDR_TYPE_V4); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_get_network(target, host, netmask) do{if(IP_IS_V6(host)){ \
+  ip4_addr_set_zero(ip_2_ip4(target)); IP_SET_TYPE(target, IPADDR_TYPE_V6); } else { \
+  ip4_addr_get_network(ip_2_ip4(target), ip_2_ip4(host), ip_2_ip4(netmask)); IP_SET_TYPE(target, IPADDR_TYPE_V4); }}while(0)
+/** @ingroup ipaddr */
+#define ip_addr_netcmp(addr1, addr2, mask) ((IP_IS_V6(addr1) && IP_IS_V6(addr2)) ? \
+  0 : \
+  ip4_addr_netcmp(ip_2_ip4(addr1), ip_2_ip4(addr2), mask))
+/** @ingroup ipaddr */
+#define ip_addr_cmp(addr1, addr2)    ((IP_GET_TYPE(addr1) != IP_GET_TYPE(addr2)) ? 0 : (IP_IS_V6_VAL(*(addr1)) ? \
+  ip6_addr_cmp(ip_2_ip6(addr1), ip_2_ip6(addr2)) : \
+  ip4_addr_cmp(ip_2_ip4(addr1), ip_2_ip4(addr2))))
+/** @ingroup ipaddr */
+#define ip_addr_isany(ipaddr)        ((IP_IS_V6(ipaddr)) ? \
+  ip6_addr_isany(ip_2_ip6(ipaddr)) : \
+  ip4_addr_isany(ip_2_ip4(ipaddr)))
+/** @ingroup ipaddr */
+#define ip_addr_isany_val(ipaddr)        ((IP_IS_V6_VAL(ipaddr)) ? \
+  ip6_addr_isany_val(*ip_2_ip6(&(ipaddr))) : \
+  ip4_addr_isany_val(*ip_2_ip4(&(ipaddr))))
+/** @ingroup ipaddr */
+#define ip_addr_isbroadcast(ipaddr, netif) ((IP_IS_V6(ipaddr)) ? \
+  0 : \
+  ip4_addr_isbroadcast(ip_2_ip4(ipaddr), netif))
+/** @ingroup ipaddr */
+#define ip_addr_ismulticast(ipaddr)  ((IP_IS_V6(ipaddr)) ? \
+  ip6_addr_ismulticast(ip_2_ip6(ipaddr)) : \
+  ip4_addr_ismulticast(ip_2_ip4(ipaddr)))
+/** @ingroup ipaddr */
+#define ip_addr_isloopback(ipaddr)  ((IP_IS_V6(ipaddr)) ? \
+  ip6_addr_isloopback(ip_2_ip6(ipaddr)) : \
+  ip4_addr_isloopback(ip_2_ip4(ipaddr)))
+/** @ingroup ipaddr */
+#define ip_addr_islinklocal(ipaddr)  ((IP_IS_V6(ipaddr)) ? \
+  ip6_addr_islinklocal(ip_2_ip6(ipaddr)) : \
+  ip4_addr_islinklocal(ip_2_ip4(ipaddr)))
+#define ip_addr_debug_print(debug, ipaddr) do { if(IP_IS_V6(ipaddr)) { \
+  ip6_addr_debug_print(debug, ip_2_ip6(ipaddr)); } else { \
+  ip4_addr_debug_print(debug, ip_2_ip4(ipaddr)); }}while(0)
+#define ip_addr_debug_print_val(debug, ipaddr) do { if(IP_IS_V6_VAL(ipaddr)) { \
+  ip6_addr_debug_print_val(debug, *ip_2_ip6(&(ipaddr))); } else { \
+  ip4_addr_debug_print_val(debug, *ip_2_ip4(&(ipaddr))); }}while(0)
+/** @ingroup ipaddr */
+#define ipaddr_ntoa(addr)   (((addr) == NULL) ? "NULL" : \
+  ((IP_IS_V6(addr)) ? ip6addr_ntoa(ip_2_ip6(addr)) : ip4addr_ntoa(ip_2_ip4(addr))))
+/** @ingroup ipaddr */
+#define ipaddr_ntoa_r(addr, buf, buflen)   (((addr) == NULL) ? "NULL" : \
+  ((IP_IS_V6(addr)) ? ip6addr_ntoa_r(ip_2_ip6(addr), buf, buflen) : ip4addr_ntoa_r(ip_2_ip4(addr), buf, buflen)))
+int ipaddr_aton(const char *cp, ip_addr_t *addr);
+
+/** @ingroup ipaddr */
+#define IPADDR_STRLEN_MAX   IP6ADDR_STRLEN_MAX
+
+/** @ingroup ipaddr */
+#define ip4_2_ipv4_mapped_ipv6(ip6addr, ip4addr) do { \
+  (ip6addr)->addr[3] = (ip4addr)->addr; \
+  (ip6addr)->addr[2] = PP_HTONL(0x0000FFFFUL); \
+  (ip6addr)->addr[1] = 0; \
+  (ip6addr)->addr[0] = 0; } while(0);
+
+/** @ingroup ipaddr */
+#define unmap_ipv4_mapped_ipv6(ip4addr, ip6addr) \
+  (ip4addr)->addr = (ip6addr)->addr[3];
+
+#define IP46_ADDR_ANY(type) (((type) == IPADDR_TYPE_V6)? IP6_ADDR_ANY : IP4_ADDR_ANY)
+
+#else
+#define IP_ADDR_PCB_VERSION_MATCH(addr, pcb)         1
+#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) 1
+
+#if TLS_CONFIG_IPV4
+typedef ip4_addr_t ip_addr_t;
+#define IPADDR4_INIT(u32val)                    { u32val }
+#define IPADDR4_INIT_BYTES(a,b,c,d)             IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d)))
+#define IP_IS_V4_VAL(ipaddr)                    1
+#define IP_IS_V6_VAL(ipaddr)                    0
+#define IP_IS_V4(ipaddr)                        1
+#define IP_IS_V6(ipaddr)                        0
+#define IP_IS_ANY_TYPE_VAL(ipaddr)              0
+#define IP_SET_TYPE_VAL(ipaddr, iptype)
+#define IP_SET_TYPE(ipaddr, iptype)
+#define IP_GET_TYPE(ipaddr)                     IPADDR_TYPE_V4
+#define ip_2_ip4(ipaddr)                        (ipaddr)
+#define IP_ADDR4(ipaddr,a,b,c,d)                IP4_ADDR(ipaddr,a,b,c,d)
+
+#define ip_addr_copy(dest, src)                 ip4_addr_copy(dest, src)
+#define ip_addr_copy_from_ip4(dest, src)        ip4_addr_copy(dest, src)
+#define ip_addr_set_ip4_u32(ipaddr, val)        ip4_addr_set_u32(ip_2_ip4(ipaddr), val)
+#define ip_addr_get_ip4_u32(ipaddr)             ip4_addr_get_u32(ip_2_ip4(ipaddr))
+#define ip_addr_set(dest, src)                  ip4_addr_set(dest, src)
+#define ip_addr_set_ipaddr(dest, src)           ip4_addr_set(dest, src)
+#define ip_addr_set_zero(ipaddr)                ip4_addr_set_zero(ipaddr)
+#define ip_addr_set_zero_ip4(ipaddr)            ip4_addr_set_zero(ipaddr)
+#define ip_addr_set_any(is_ipv6, ipaddr)        ip4_addr_set_any(ipaddr)
+#define ip_addr_set_loopback(is_ipv6, ipaddr)   ip4_addr_set_loopback(ipaddr)
+#define ip_addr_set_hton(dest, src)             ip4_addr_set_hton(dest, src)
+#define ip_addr_get_network(target, host, mask) ip4_addr_get_network(target, host, mask)
+#define ip_addr_netcmp(addr1, addr2, mask)      ip4_addr_netcmp(addr1, addr2, mask)
+#define ip_addr_cmp(addr1, addr2)               ip4_addr_cmp(addr1, addr2)
+#define ip_addr_isany(ipaddr)                   ip4_addr_isany(ipaddr)
+#define ip_addr_isany_val(ipaddr)               ip4_addr_isany_val(ipaddr)
+#define ip_addr_isloopback(ipaddr)              ip4_addr_isloopback(ipaddr)
+#define ip_addr_islinklocal(ipaddr)             ip4_addr_islinklocal(ipaddr)
+#define ip_addr_isbroadcast(addr, netif)        ip4_addr_isbroadcast(addr, netif)
+#define ip_addr_ismulticast(ipaddr)             ip4_addr_ismulticast(ipaddr)
+#define ip_addr_debug_print(debug, ipaddr)      ip4_addr_debug_print(debug, ipaddr)
+#define ip_addr_debug_print_val(debug, ipaddr)  ip4_addr_debug_print_val(debug, ipaddr)
+#define ipaddr_ntoa(ipaddr)                     ip4addr_ntoa(ipaddr)
+#define ipaddr_ntoa_r(ipaddr, buf, buflen)      ip4addr_ntoa_r(ipaddr, buf, buflen)
+#define ipaddr_aton(cp, addr)                   ip4addr_aton(cp, addr)
+
+#define IPADDR_STRLEN_MAX   IP4ADDR_STRLEN_MAX
+
+#define IP46_ADDR_ANY(type) (IP4_ADDR_ANY)
+#else
+typedef ip6_addr_t ip_addr_t;
+#define IPADDR6_INIT(a, b, c, d)                { { a, b, c, d } }
+#define IPADDR6_INIT_HOST(a, b, c, d)           { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } }
+#define IP_IS_V4_VAL(ipaddr)                    0
+#define IP_IS_V6_VAL(ipaddr)                    1
+#define IP_IS_V4(ipaddr)                        0
+#define IP_IS_V6(ipaddr)                        1
+#define IP_IS_ANY_TYPE_VAL(ipaddr)              0
+#define IP_SET_TYPE_VAL(ipaddr, iptype)
+#define IP_SET_TYPE(ipaddr, iptype)
+#define IP_GET_TYPE(ipaddr)                     IPADDR_TYPE_V6
+#define ip_2_ip6(ipaddr)                        (ipaddr)
+#define IP_ADDR6(ipaddr,i0,i1,i2,i3)            IP6_ADDR(ipaddr,i0,i1,i2,i3)
+#define IP_ADDR6_HOST(ipaddr,i0,i1,i2,i3)       IP_ADDR6(ipaddr,PP_HTONL(i0),PP_HTONL(i1),PP_HTONL(i2),PP_HTONL(i3))
+
+#define ip_addr_copy(dest, src)                 ip6_addr_copy(dest, src)
+#define ip_addr_copy_from_ip6(dest, src)        ip6_addr_copy(dest, src)
+#define ip_addr_set(dest, src)                  ip6_addr_set(dest, src)
+#define ip_addr_set_ipaddr(dest, src)           ip6_addr_set(dest, src)
+#define ip_addr_set_zero(ipaddr)                ip6_addr_set_zero(ipaddr)
+#define ip_addr_set_zero_ip6(ipaddr)            ip6_addr_set_zero(ipaddr)
+#define ip_addr_set_any(is_ipv6, ipaddr)        ip6_addr_set_any(ipaddr)
+#define ip_addr_set_loopback(is_ipv6, ipaddr)   ip6_addr_set_loopback(ipaddr)
+#define ip_addr_set_hton(dest, src)             ip6_addr_set_hton(dest, src)
+#define ip_addr_get_network(target, host, mask) ip6_addr_set_zero(target)
+#define ip_addr_netcmp(addr1, addr2, mask)      0
+#define ip_addr_cmp(addr1, addr2)               ip6_addr_cmp(addr1, addr2)
+#define ip_addr_isany(ipaddr)                   ip6_addr_isany(ipaddr)
+#define ip_addr_isany_val(ipaddr)               ip6_addr_isany_val(ipaddr)
+#define ip_addr_isloopback(ipaddr)              ip6_addr_isloopback(ipaddr)
+#define ip_addr_islinklocal(ipaddr)             ip6_addr_islinklocal(ipaddr)
+#define ip_addr_isbroadcast(addr, netif)        0
+#define ip_addr_ismulticast(ipaddr)             ip6_addr_ismulticast(ipaddr)
+#define ip_addr_debug_print(debug, ipaddr)      ip6_addr_debug_print(debug, ipaddr)
+#define ip_addr_debug_print_val(debug, ipaddr)  ip6_addr_debug_print_val(debug, ipaddr)
+#define ipaddr_ntoa(ipaddr)                     ip6addr_ntoa(ipaddr)
+#define ipaddr_ntoa_r(ipaddr, buf, buflen)      ip6addr_ntoa_r(ipaddr, buf, buflen)
+#define ipaddr_aton(cp, addr)                   ip6addr_aton(cp, addr)
+
+#define IPADDR_STRLEN_MAX   IP6ADDR_STRLEN_MAX
+
+#define IP46_ADDR_ANY(type) (IP6_ADDR_ANY)
+#endif
+#endif
+
+
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN     IP4ADDR_STRLEN_MAX
+#endif
+#if TLS_CONFIG_IPV6
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN    IP6ADDR_STRLEN_MAX
+#endif
+#endif
+
+#if TLS_CONFIG_IPV4 && TLS_CONFIG_IPV6
+/** @ingroup socket */
+#define inet_ntop(af,src,dst,size) \
+    (((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) \
+     : (((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL))
+/** @ingroup socket */
+#define inet_pton(af,src,dst) \
+    (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) \
+     : (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0))
+#elif TLS_CONFIG_IPV4 /* TLS_CONFIG_IPV4 && TLS_CONFIG_IPV6 */
+#define inet_ntop(af,src,dst,size) \
+    (((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL)
+#define inet_pton(af,src,dst) \
+    (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0)
+#else /* TLS_CONFIG_IPV4 && TLS_CONFIG_IPV6 */
+#define inet_ntop(af,src,dst,size) \
+    (((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) : NULL)
+#define inet_pton(af,src,dst) \
+    (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) : 0)
+#endif /* TLS_CONFIG_IPV4 && TLS_CONFIG_IPV6 */
+
+extern void print_ipaddr(ip_addr_t *ip);
+
+extern struct netif *wm_ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src);
+#endif

+ 18 - 0
include/os/wm_os_config.h

@@ -0,0 +1,18 @@
+/**
+ * @file    wm_os_config.h
+ *
+ * @brief   WM OS select freertos or ucos
+ *
+ * @author  winnermicro
+ *
+ * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
+ */
+ 
+#ifndef __WM_OS_CONFIG_H__
+#define __WM_OS_CONFIG_H__
+#define OS_CFG_ON  1
+#define OS_CFG_OFF 0
+
+#undef TLS_OS_FREERTOS
+#define TLS_OS_FREERTOS                     OS_CFG_ON   /*FreeRTOS need to modify wm_config.inc*/
+#endif

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