build: W600-SDK importiert, Firmware-Build und Hello am EVK

Docker-Build mit gcc-arm-none-eabi 4.9-2014q4 (statt Homebrew-Cask) verwendet,
Dockerfile/tools/docker.sh dafür aus Task 13 vorgezogen. cmake/sdk.cmake schont
gcc 4.9 (kennt -fcommon/-Wno-error=... nicht). Zwei zusätzliche SDK-Stubs
(EarlyInit, pre_gpio_config) in src/sys/sdk_stubs.c ergänzt, siehe sdk/PATCHES.md.
This commit is contained in:
Michael Sauer
2026-09-11 12:52:26 +02:00
parent 4e7ff78fc6
commit 1b0501179d
610 changed files with 224089 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+225
View File
@@ -0,0 +1,225 @@
/**
******************************************************************************
* @file misc.c
* @author MCD Application Team
* @version V3.6.1
* @date 05-March-2012
* @brief This file provides all the miscellaneous firmware functions (add-on
* to CMSIS functions).
*/
/* Includes ------------------------------------------------------------------*/
#include "misc.h"
/** @addtogroup W600_Driver
* @{
*/
/** @defgroup MISC
* @brief MISC driver modules
* @{
*/
/** @defgroup MISC_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup MISC_Private_Defines
* @{
*/
#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000)
/**
* @}
*/
/** @defgroup MISC_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup MISC_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup MISC_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup MISC_Private_Functions
* @{
*/
/**
* @brief Configures the priority grouping: pre-emption priority and subpriority.
* @param NVIC_PriorityGroup: specifies the priority grouping bits length.
* This parameter can be one of the following values:
* @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority
* 4 bits for subpriority
* @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority
* 3 bits for subpriority
* @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority
* 2 bits for subpriority
* @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority
* 1 bits for subpriority
* @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority
* 0 bits for subpriority
* @retval None
*/
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
/* Check the parameters */
// assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
/* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}
/**
* @brief Initializes the NVIC peripheral according to the specified
* parameters in the NVIC_InitStruct.
* @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains
* the configuration information for the specified NVIC peripheral.
* @retval None
*/
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{
uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
/* Check the parameters */
// assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
// assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));
// assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
{
/* Compute the Corresponding IRQ Priority --------------------------------*/
tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
tmppre = (0x4 - tmppriority);
tmpsub = tmpsub >> tmppriority;
tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
tmppriority = tmppriority << 0x04;
NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
/* Enable the Selected IRQ Channels --------------------------------------*/
NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
}
else
{
/* Disable the Selected IRQ Channels -------------------------------------*/
NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
}
}
void NVIC_Configration(int irqno, FunctionalState irqstatus)
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = irqno;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = irqstatus;
NVIC_Init(&NVIC_InitStruct);
}
/**
* @brief Sets the vector table location and Offset.
* @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory.
* This parameter can be one of the following values:
* @arg NVIC_VectTab_RAM
* @arg NVIC_VectTab_FLASH
* @param Offset: Vector Table base offset field. This value must be a multiple
* of 0x200.
* @retval None
*/
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
{
/* Check the parameters */
// assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
// assert_param(IS_NVIC_OFFSET(Offset));
SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
}
/**
* @brief Selects the condition for the system to enter low power mode.
* @param LowPowerMode: Specifies the new mode for the system to enter low power mode.
* This parameter can be one of the following values:
* @arg NVIC_LP_SEVONPEND
* @arg NVIC_LP_SLEEPDEEP
* @arg NVIC_LP_SLEEPONEXIT
* @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState)
{
/* Check the parameters */
// assert_param(IS_NVIC_LP(LowPowerMode));
// assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
SCB->SCR |= LowPowerMode;
}
else
{
SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode);
}
}
/**
* @brief Configures the SysTick clock source.
* @param SysTick_CLKSource: specifies the SysTick clock source.
* This parameter can be one of the following values:
* @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.
* @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.
* @retval None
*/
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{
/* Check the parameters */
// assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
{
SysTick->CTRL |= SysTick_CLKSource_HCLK;
}
else
{
SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT 2014 Winner Microelectronics Co., Ltd. *****END OF FILE****/
+93
View File
@@ -0,0 +1,93 @@
#if GCC_COMPILE
#include <reent.h>
extern int sendchar(int ch);
_ssize_t _write_r (struct _reent *r, int file, const void *ptr, size_t len)
{
size_t i;
char *p;
p = (char*) ptr;
for (i = 0; i < len; i++)
{
sendchar(*p++);
}
return len;
}
_ssize_t _read_r(struct _reent *r, int file, void *ptr, size_t len)
{
return 0;
}
int _close_r(struct _reent *r, int file)
{
return 0;
}
_off_t _lseek_r(struct _reent *r, int file, _off_t ptr, int dir)
{
return (_off_t)0; /* Always indicate we are at file beginning. */
}
int _fstat_r(struct _reent *r, int file, struct stat *st)
{
return 0;
}
int _isatty(int file)
{
return 1;
}
void abort(void)
{
while(1);
}
extern char end[];
extern char __HeapLimit[];
static char *heap_ptr = end;
static char *heap_end = __HeapLimit;
/**
* @brief This function is used to extend current heap size, Limit is __HeapLimit
*
* @param[in] None
*
* @return None
*
* @note Normally, it is just used in gcc mode.
*/
void * _sbrk_r(struct _reent *_s_r, ptrdiff_t nbytes)
{
char *base;
base = heap_ptr;
if(base + nbytes > heap_end)
{
return (void *)-1;
}
heap_ptr += nbytes;
return base;
}
void * tls_reserve_mem_lock(int nbytes)
{
if(heap_end - (nbytes + 4) <= heap_ptr)
{
return NULL;
}
heap_end -= (nbytes + 4);
return (void *)((((int)heap_end + 3) >> 2) << 2);
}
void tls_reserve_mem_unlock(void)
{
heap_end = __HeapLimit;
}
#endif
+256
View File
@@ -0,0 +1,256 @@
/* File: startup_ARMCM3.S
* Purpose: startup file for Cortex-M3 devices. Should use with
* GCC for ARM Embedded Processors
* Version: V2.0
* Date: 16 August 2013
*
* Copyright (c) 2011 - 2013 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
.syntax unified
.arch armv7-m
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 0xc00
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifdef __HEAP_SIZE
.equ Heap_Size, __HEAP_SIZE
#else
//.equ Heap_Size, 0x1A000
.equ Heap_Size, 0x21000
#endif
.globl __heap_base
.globl __HeapLimit
__heap_base:
.if Heap_Size
.space Heap_Size
.endif
.size __heap_base, . - __heap_base
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .isr_vector
.align 2
.globl __isr_vector
__isr_vector:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long DebugMon_Handler /* Debug Monitor Handler */
.long 0 /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long OS_CPU_SysTickHandler /* SysTick Handler */
/* External interrupts */
.long SDIO_RX_IRQHandler /*HSPI&SDIO SLAVE Trasmit*/
.long SDIO_TX_IRQHandler /*HSPI & SDIO SLAVE Receive Data*/
.long 0 /*Not Used*/
.long SDIO_TX_CMD_IRQHandler /*HSPI & SDIO SLAVE Receive Command*/
.long tls_wl_mac_isr /*MAC isr*/
.long 0 /*Not Used*/
.long tls_wl_rx_isr /*Wi-Fi Rx isr*/
.long tls_wl_mgmt_tx_isr /*Wi-Fi Managment tx isr*/
.long tls_wl_data_tx_isr /*Wi-Fi Data Tx isr*/
.long PMU_TIMER1_IRQHandler /*PMU Timer1*/
.long PMU_TIMER0_IRQHandler /*PMU Timer0*/
.long PMU_GPIO_WAKE_IRQHandler /*PMU Wakeup pin isr*/
.long PMU_SDIO_WAKE_IRQHandler /*SDIO Wakeup isr*/
.long DMA_Channel0_IRQHandler /*DMA Channel 0*/
.long DMA_Channel1_IRQHandler /*DMA Channel 1*/
.long DMA_Channel2_IRQHandler /*DMA Channel 2*/
.long DMA_Channel3_IRQHandler /*DMA Channel 3*/
.long DMA_Channel4_7_IRQHandler /*DMA Channel 4-7*/
.long DMA_BURST_IRQHandler /*DMA Burst isr*/
.long I2C_IRQHandler /*I2C isr*/
.long ADC_IRQHandler /*ADC isr*/
.long SPI_LS_IRQHandler /*Master SPI isr*/
.long SPI_HS_IRQHandler /*HSPI isr, not used*/
.long UART0_IRQHandler /*UART0 isr*/
.long UART1_IRQHandler /*UART1 isr*/
.long GPIOA_IRQHandler /*GPIOA isr*/
.long TIM0_IRQHandler /*TIM0 isr*/
.long TIM1_IRQHandler /*TIM1 isr*/
.long TIM2_IRQHandler /*TIM2 isr*/
.long TIM3_IRQHandler /*TIM3 isr*/
.long TIM4_IRQHandler /*TIM4 isr*/
.long TIM5_IRQHandler /*TIM5 isr*/
.long WDG_IRQHandler /*Watchdog isr*/
.long 0 /*Not Used*/
.long 0 /*Not Used*/
.long PWM_IRQHandler /*PWM isr*/
.long I2S_IRQHandler /*I2S isr*/
.long PMU_RTC_IRQHandler /*PMU RTC isr*/
.long RSA_IRQHandler /*RSA isr*/
.long CRYPTION_IRQHandler /*CRYPTION isr*/
.long GPIOB_IRQHandler /*GPIOB isr*/
.long UART2_IRQHandler /*UART2&7816 isr*/
.size __isr_vector, . - __isr_vector
.text
.thumb
.thumb_func
.align 2
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Firstly it copies data from read only memory to RAM.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
.L_loop1:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt .L_loop1
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
.L_loop3:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt .L_loop3
/*
#ifndef __NO_SYSTEM_INIT
bl SystemInit
#endif
*/
bl main
.pool
.size Reset_Handler, . - Reset_Handler
.align 1
.thumb_func
.weak Default_Handler
.type Default_Handler, %function
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler MemManage_Handler
def_irq_handler BusFault_Handler
def_irq_handler UsageFault_Handler
def_irq_handler SVC_Handler
def_irq_handler DebugMon_Handler
def_irq_handler PendSV_Handler
def_irq_handler OS_CPU_SysTickHandler
def_irq_handler SDIO_RX_IRQHandler
def_irq_handler SDIO_TX_IRQHandler
def_irq_handler SDIO_TX_CMD_IRQHandler
def_irq_handler tls_wl_mac_isr
def_irq_handler tls_wl_rx_isr
def_irq_handler tls_wl_mgmt_tx_isr
def_irq_handler tls_wl_data_tx_isr
/*def_irq_handler PMU_TIMER1_IRQHandler*/
/*def_irq_handler PMU_TIMER0_IRQHandler*/
/*def_irq_handler PMU_GPIO_WAKE_IRQHandler*/
def_irq_handler PMU_SDIO_WAKE_IRQHandler
def_irq_handler DMA_Channel0_IRQHandler
def_irq_handler DMA_Channel1_IRQHandler
def_irq_handler DMA_Channel2_IRQHandler
def_irq_handler DMA_Channel3_IRQHandler
def_irq_handler DMA_Channel4_7_IRQHandler
def_irq_handler DMA_BURST_IRQHandler
/*def_irq_handler I2C_IRQHandler*/
def_irq_handler ADC_IRQHandler
def_irq_handler SPI_LS_IRQHandler
def_irq_handler SPI_HS_IRQHandler
def_irq_handler UART0_IRQHandler
def_irq_handler UART1_IRQHandler
def_irq_handler GPIOA_IRQHandler
def_irq_handler TIM0_IRQHandler
def_irq_handler TIM1_IRQHandler
def_irq_handler TIM2_IRQHandler
def_irq_handler TIM3_IRQHandler
def_irq_handler TIM4_IRQHandler
def_irq_handler TIM5_IRQHandler
def_irq_handler WDG_IRQHandler
/*def_irq_handler PWM_IRQHandler*/
/*def_irq_handler I2S_IRQHandler*/
/*def_irq_handler PMU_RTC_IRQHandler*/
def_irq_handler RSA_IRQHandler
def_irq_handler CRYPTION_IRQHandler
def_irq_handler GPIOB_IRQHandler
def_irq_handler UART2_IRQHandler
.end
+72
View File
@@ -0,0 +1,72 @@
# THE VERSION NUMBER
SET(CMAKE_SYSTEM_NAME Generic)
CMAKE_MINIMUM_REQUIRED (VERSION 3.10)
PROJECT(WCOMMON)
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
SET(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
set(CMAKE_VERBOSE_MAKEFILE OFF)
# ENABLE ASM
ENABLE_LANGUAGE(ASM)
SET(CMAKE_STATIC_LIBRARY_PREFIX)
SET(CMAKE_STATIC_LIBRARY_SUFFIX)
SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX)
SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX)
# C FLAGS
SET(CMAKE_C_FLAGS " -mthumb --function-sections --data-sections -mcpu=cortex-m3 -std=gnu99 -mabi=aapcs -march=armv7-m -fno-builtin -Wall")
STRING(APPEND CMAKE_C_FLAGS " -DGCC_COMPILE=1 -DWOLFSSL_USER_SETTINGS -D_IN_ADDR_T_DECLARED -D__MACHINE_ENDIAN_H__ -D_TIMEVAL_DEFINED -D__INSIDE_CYGWIN_NET__ ")
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -gdwarf-2 -Wall -DDEBUG ")
SET(CMAKE_C_FLAGS_RELEASE "-Os -Wall")
# DEBUG ASM FLAGS
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -O0 -g3 -gdwarf-2 -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin -DDEBUG ")
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE} -Os -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin ")
# Library sources
SET(LIBRARY_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/fwup/wm_fwup.c"
"${CMAKE_CURRENT_SOURCE_DIR}/mem/wm_mem.c"
"${CMAKE_CURRENT_SOURCE_DIR}/Params/wm_param.c"
"${CMAKE_CURRENT_SOURCE_DIR}/task/wm_wl_mbox.c"
"${CMAKE_CURRENT_SOURCE_DIR}/task/wm_wl_task.c"
"${CMAKE_CURRENT_SOURCE_DIR}/task/wm_wl_timers.c"
"${CMAKE_CURRENT_SOURCE_DIR}/utils/utils.c"
"${CMAKE_CURRENT_SOURCE_DIR}/crypto/wm_crypto_hard.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/hmac.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/md2.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/md4.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/sha224.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/sha384.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/digest/sha512.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/keyformat/asn1.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/keyformat/base64.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/keyformat/x509.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/math/pstm_mul_comba.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/prng/prng.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/prng/yarrow.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/pubkey/dh.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/pubkey/ecc.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/pubkey/pkcs.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/pubkey/pubkey.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/pubkey/rsa.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/symmetric/aesGCM.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/symmetric/des3.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/symmetric/idea.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/symmetric/rc2.c"
# "${CMAKE_CURRENT_SOURCE_DIR}/crypto/symmetric/seed.c"
)
function(ADD_LIB_TARGET LIBTARGET)
add_library(${LIBTARGET} OBJECT ${LIBRARY_SOURCES})
# ADD_CUSTOM_COMMAND(TARGET ${LIBTARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXECUTABLE_OUTPUT_PATH}/${LIBTARGET} ${CMAKE_CURRENT_SOURCE_DIR}/../../Lib/GNU/${LIBTARGET})
endfunction()
ADD_LIB_TARGET(wmcommon.a)
File diff suppressed because it is too large Load Diff
+124
View File
@@ -0,0 +1,124 @@
/*****************************************************************************
*
* File Name : tls_param.h
*
* Description: param manager Module
*
* Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd.
* All rights reserved.
*
* Author : dave
*
* Date : 2014-6-12
*****************************************************************************/
#ifndef TLS_PARAM_H
#define TLS_PARAM_H
#include "wm_type_def.h"
struct tls_param_quick_connect{
bool quick_connect_en;
u8 chanId;
};
struct tls_sys_param {
struct tls_param_hardware_version hardware_version;
struct tls_param_bssid bssid;
struct tls_param_ssid ssid;
u8 channel_enable;
u8 channel;
u8 wireless_region;
u8 encry;
u8 wireless_protocol;
u8 auto_create_adhoc;
u8 auto_retrycnt;
u8 auto_roam;
u8 auto_powersave;
u8 ssid_broadcast_enable;
u16 channellist;
struct tls_param_key key;
struct tls_param_bgr wbgr;
struct tls_param_wps wps;
struct tls_param_ip ipcfg;
u8 local_dnsname[32];
u8 local_device_name[32];
struct tls_param_oray_client oray_client_setting;
u8 upnp_enable;
u8 always_online;
u8 user_port_mode;
u8 res_2;
struct tls_param_uart uart_cfg;
u8 auto_mode;
u8 res_3;
u16 transparent_trigger_length;
u16 transparent_trigger_period;
struct tls_param_socket remote_socket_cfg;
u32 debug_mode;
u32 res_4[2]; /* reserv and mark the end */
/*escape char*/
u8 EscapeChar;
u8 EscReserved;
u16 EscapePeriod; /* unit: ms */
u8 IoMode;
u8 CmdMode;
u8 PassWord[6];
struct tls_webs_cfg WebsCfg;
u8 oneshotflag;
u8 oneshotres[2];
struct tls_param_sha1 psk;
struct tls_param_original_key original_key;
struct tls_param_ssid original_ssid;
u8 auto_reconnect;
u8 res_5[3];
struct tls_param_quick_connect quick_connect;
u8 key_changed;
u8 ssid_changed;
struct tls_param_ssid apsta_ssid;
struct tls_param_sha1 apsta_psk;
u8 res_6[1];
u8 channel4softap;
u8 encry4softap;
struct tls_param_key key4softap;
struct tls_param_ip ipcfg4softap;
struct tls_param_bgr wbgr4softap;
char sntp_service1[32];
char sntp_service2[32];
char sntp_service3[32];
struct tls_param_tem_offset params_tem;
};
struct tls_param_flash {
u32 magic;
u16 partition_num;
u16 modify_count;
u32 resv_1;
u16 resv_2;
u16 length;
struct tls_sys_param parameters;
u32 crc32;
};
#endif /* WM_PARAM_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+765
View File
@@ -0,0 +1,765 @@
/*****************************************************************************
*
* File Name : wm_mem.c
*
* Description: memory manager Module
*
* Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd.
* All rights reserved.
*
* Author : dave
*
* Date : 2014-6-12
*****************************************************************************/
#include "wm_osal.h"
#include "wm_mem.h"
#include "list.h"
#include <string.h>
extern u8 tls_get_isr_count(void);
/**
* This variable is set if the memory mananger has been initialized.
* This is available only for debug version of the driver
*/
bool memory_manager_initialized = false;
/**
* This mutex is used to synchronize the list of allocated
* memory blocks. This is a debug version only feature
*/
tls_os_sem_t *mem_sem;
#if WM_MEM_DEBUG
struct dl_list memory_used_list;
struct dl_list memory_free_list;
#define MEM_BLOCK_SIZE 600
MEMORY_BLOCK mem_blocks[MEM_BLOCK_SIZE];
u32 alloc_heap_mem_bytes = 0;
u32 alloc_heap_mem_blk_cnt = 0;
u32 alloc_heap_mem_max_size = 0;
#define PRE_OVERSIZE 0
#define OVERSIZE 0
/**
* This is a debug only function that performs memory management operations for us.
* Memory allocated using this function is tracked, flagged when leaked, and caught for
* overflows and underflows.
*
* \param size The size in bytes of memory to
* allocate
*
* \param file The full path of file where this
* function is invoked from
* \param line The line number in the file where this
* method was called from
* \return Pointer to the allocated memory or NULL in case of a failure
*/
void * mem_alloc_debug(u32 size, char* file, int line)
{
void *buf = NULL;
u32 pad_len;
int i = 0;
u32 cpu_sr;
//
// If the memory manager has not been initialized, do so now
//
cpu_sr = tls_os_set_critical();
if (!memory_manager_initialized) {
tls_os_status_t os_status;
memory_manager_initialized = true;
//
// NOTE: If two thread allocate the very first allocation simultaneously
// it could cause double initialization of the memory manager. This is a
// highly unlikely scenario and will occur in debug versions only.
//
os_status = tls_os_sem_create(&mem_sem, 1);
if(os_status != TLS_OS_SUCCESS)
printf("mem_alloc_debug: tls_os_sem_create mem_sem error\n");
dl_list_init(&memory_used_list);
dl_list_init(&memory_free_list);
for(i = 0; i < MEM_BLOCK_SIZE; i++)
{
dl_list_add_tail(&memory_free_list, &mem_blocks[i].list);
}
}
tls_os_release_critical(cpu_sr);
tls_os_sem_acquire(mem_sem, 0);
cpu_sr = tls_os_set_critical();
//
// Allocate the required memory chunk plus header and trailer bytes
//
pad_len = sizeof(u32) - (size & 0x3);
buf = malloc(sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + size + pad_len + OVERSIZE + sizeof(MEMORY_PATTERN));
if (buf) {
//
// Memory allocation succeeded. Add information about the allocated
// block in the list that tracks all allocations.
//
PMEMORY_PATTERN mem_ptn_hd;
PMEMORY_PATTERN mem_ptn_tl;
PMEMORY_BLOCK mem_blk_hd1;
if(dl_list_empty(&memory_free_list))
{
printf("Memory blocks empty!\n");
free(buf);
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
tls_mem_alloc_info();
return NULL;
}
mem_blk_hd1 = dl_list_first(&memory_free_list, MEMORY_BLOCK, list);
dl_list_del(&mem_blk_hd1->list);
dl_list_add_tail(&memory_used_list, &mem_blk_hd1->list);
alloc_heap_mem_bytes += size+sizeof(MEMORY_PATTERN)+sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE;
alloc_heap_mem_blk_cnt++;
if (alloc_heap_mem_bytes > alloc_heap_mem_max_size)
{
alloc_heap_mem_max_size = alloc_heap_mem_bytes;
//printf("alloc_heap_mem_max_size=%d\n", alloc_heap_mem_max_size);
}
mem_blk_hd1->pad = pad_len;
mem_blk_hd1->file = file;
mem_blk_hd1->line = line;
mem_blk_hd1->length = size;
mem_blk_hd1->header_pattern = (u32)buf;
// Fill in the memory header and trailer
mem_ptn_hd = (PMEMORY_PATTERN)buf;
mem_ptn_hd->pattern0= MEM_HEADER_PATTERN;
/*mem_ptn_hd->pattern1= MEM_HEADER_PATTERN;
mem_ptn_hd->pattern2= MEM_HEADER_PATTERN;
mem_ptn_hd->pattern3= MEM_HEADER_PATTERN;*/
mem_ptn_tl = (PMEMORY_PATTERN)(((u8 *)(buf))+size + sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE);
mem_ptn_tl->pattern0= MEM_TAILER_PATTERN;
/*mem_ptn_tl->pattern1= MEM_TAILER_PATTERN;
mem_ptn_tl->pattern2= MEM_TAILER_PATTERN;
mem_ptn_tl->pattern3= MEM_TAILER_PATTERN;*/
// Jump ahead by memory header so pointer returned to caller points at the right place
buf = ((u8 *)buf) + sizeof (MEMORY_PATTERN) + PRE_OVERSIZE;
#if 0
printf("==>Memory was allocated from %s at line %d with length %d\n",
mem_blk_hd->file,
mem_blk_hd->line,
mem_blk_hd->length);
printf("==>mem alloc ptr = 0x%x\n", buf);
#endif
}
else
{
printf("==>Memory was allocated from %s at line %d with length %d, allocated size %d, count %d\n",
file,
line,
size, alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
tls_mem_alloc_info();
return buf;
}
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
return buf;
}
void * mem_calloc_debug(u32 n, u32 size, char* file, int line)
{
void *buf = NULL;
u32 pad_len;
int i = 0;
u32 cpu_sr;
//
// If the memory manager has not been initialized, do so now
//
cpu_sr = tls_os_set_critical();
if (!memory_manager_initialized) {
tls_os_status_t os_status;
memory_manager_initialized = true;
//
// NOTE: If two thread allocate the very first allocation simultaneously
// it could cause double initialization of the memory manager. This is a
// highly unlikely scenario and will occur in debug versions only.
//
os_status = tls_os_sem_create(&mem_sem, 1);
if(os_status != TLS_OS_SUCCESS)
printf("mem_alloc_debug: tls_os_sem_create mem_sem error\n");
dl_list_init(&memory_used_list);
dl_list_init(&memory_free_list);
for(i = 0; i < MEM_BLOCK_SIZE; i++)
{
dl_list_add_tail(&memory_free_list, &mem_blocks[i].list);
}
}
tls_os_release_critical(cpu_sr);
tls_os_sem_acquire(mem_sem, 0);
cpu_sr = tls_os_set_critical();
//
// Allocate the required memory chunk plus header and trailer bytes
//
pad_len = sizeof(u32) - ((n*size) & 0x3);
buf = malloc(sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + n*size + pad_len + OVERSIZE + sizeof(MEMORY_PATTERN));
if (buf) {
//
// Memory allocation succeeded. Add information about the allocated
// block in the list that tracks all allocations.
//
PMEMORY_PATTERN mem_ptn_hd;
PMEMORY_PATTERN mem_ptn_tl;
PMEMORY_BLOCK mem_blk_hd1;
if(dl_list_empty(&memory_free_list))
{
printf("Memory blocks empty!\n");
free(buf);
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
tls_mem_alloc_info();
return NULL;
}
mem_blk_hd1 = dl_list_first(&memory_free_list, MEMORY_BLOCK, list);
dl_list_del(&mem_blk_hd1->list);
dl_list_add_tail(&memory_used_list, &mem_blk_hd1->list);
alloc_heap_mem_bytes += n*size+sizeof(MEMORY_PATTERN)+sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE;
alloc_heap_mem_blk_cnt++;
if (alloc_heap_mem_bytes > alloc_heap_mem_max_size)
{
alloc_heap_mem_max_size = alloc_heap_mem_bytes;
//printf("alloc_heap_mem_max_size=%d\n", alloc_heap_mem_max_size);
}
mem_blk_hd1->pad = pad_len;
mem_blk_hd1->file = file;
mem_blk_hd1->line = line;
mem_blk_hd1->length = n*size;
mem_blk_hd1->header_pattern = (u32)buf;
// Fill in the memory header and trailer
mem_ptn_hd = (PMEMORY_PATTERN)buf;
mem_ptn_hd->pattern0= MEM_HEADER_PATTERN;
/*mem_ptn_hd->pattern1= MEM_HEADER_PATTERN;
mem_ptn_hd->pattern2= MEM_HEADER_PATTERN;
mem_ptn_hd->pattern3= MEM_HEADER_PATTERN;*/
mem_ptn_tl = (PMEMORY_PATTERN)(((u8 *)(buf))+n*size + sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE);
mem_ptn_tl->pattern0= MEM_TAILER_PATTERN;
/*mem_ptn_tl->pattern1= MEM_TAILER_PATTERN;
mem_ptn_tl->pattern2= MEM_TAILER_PATTERN;
mem_ptn_tl->pattern3= MEM_TAILER_PATTERN;*/
// Jump ahead by memory header so pointer returned to caller points at the right place
buf = ((u8 *)buf) + sizeof (MEMORY_PATTERN) + PRE_OVERSIZE;
#if 0
printf("==>Memory was allocated from %s at line %d with length %d\n",
mem_blk_hd->file,
mem_blk_hd->line,
mem_blk_hd->length);
printf("==>mem alloc ptr = 0x%x\n", buf);
#endif
}
else
{
printf("==>Memory was allocated from %s at line %d with length %d, allocated size %d, count %d\n",
file,
line,
n*size, alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
tls_mem_alloc_info();
return buf;
}
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
return buf;
}
/**
* This routine is called to free memory which was previously allocated using MpAllocateMemory function.
* Before freeing the memory, this function checks and makes sure that no overflow or underflows have
* happened and will also try to detect multiple frees of the same memory chunk.
*
* \param p Pointer to allocated memory
*/
void mem_free_debug(void *p, char* file, int line)
{
PMEMORY_PATTERN mem_ptn_hd;
PMEMORY_PATTERN mem_ptn_tl;
PMEMORY_BLOCK mem_blk_hd1;
u8 needfree = 0;
u8 haserr = 0;
u32 cpu_sr;
// Jump back by memory header size so we can get to the header
mem_ptn_hd = (PMEMORY_PATTERN) (((u8 *)p) - sizeof(MEMORY_PATTERN) - PRE_OVERSIZE);
tls_os_sem_acquire(mem_sem, 0);
cpu_sr = tls_os_set_critical();
dl_list_for_each(mem_blk_hd1, &memory_used_list, MEMORY_BLOCK, list){
if(mem_blk_hd1->header_pattern == (u32)mem_ptn_hd)
{
needfree = 1;
break;
}
}
if(needfree)
{
dl_list_del(&mem_blk_hd1->list);
dl_list_add_tail(&memory_free_list, &mem_blk_hd1->list);
alloc_heap_mem_bytes -= mem_blk_hd1->length + sizeof(MEMORY_PATTERN) + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + OVERSIZE +
mem_blk_hd1->pad;
alloc_heap_mem_blk_cnt--;
}
if(needfree == 0)
{
printf("Memory Block %p was deallocated from %s at line %d \n", mem_ptn_hd, file, line);
printf("Memory %p has been deallocated!\n", p);
dl_list_for_each_reverse(mem_blk_hd1, &memory_free_list, MEMORY_BLOCK, list){
if(mem_blk_hd1->header_pattern == (u32)mem_ptn_hd)
{
printf("Memory Block %p has been put free list!\n", mem_ptn_hd);
break;
}
}
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
tls_mem_alloc_info();
return;
}
#if 0
if(mem_blk_hd1->line == 976 || mem_blk_hd1->line == 983)
{
printf("Memory Block %p can not deallocated from %s at line %d \n", mem_ptn_hd, file, line);
printf("Memory %p has been deallocated!\n", p);
tls_mem_alloc_info();
}
#endif
mem_ptn_tl = (PMEMORY_PATTERN) ((u8 *)p + mem_blk_hd1->length + mem_blk_hd1->pad + OVERSIZE);
//
// Check that header was not corrupted
//
if (mem_ptn_hd->pattern0 != MEM_HEADER_PATTERN /*|| mem_ptn_hd->pattern1 != MEM_HEADER_PATTERN
|| mem_ptn_hd->pattern2 != MEM_HEADER_PATTERN || mem_ptn_hd->pattern3 != MEM_HEADER_PATTERN*/)
{
printf("Memory %p was deallocated from %s at line %d \n", p, file, line);
printf("Memory header corruption due to underflow detected at memory block %p\n",
mem_ptn_hd);
printf("Header pattern 0(0x%x)\n",//, 1(0x%x), 2(0x%x), 3(0x%x)
mem_ptn_hd->pattern0/*,
mem_ptn_hd->pattern1,
mem_ptn_hd->pattern2,
mem_ptn_hd->pattern3*/);
//printf("Dumping information about memory block. "
// "This information may itself have been "
// "corrupted and could cause machine to bugcheck.\n");
printf("Memory was allocated from %s at line %d with length %d\n",
mem_blk_hd1->file,
mem_blk_hd1->line,
mem_blk_hd1->length);
haserr = 1;
}
#if 0
printf("<==free memory allocated from %s at line %d with length %d\n",
mem_blk_hd->file,
mem_blk_hd->line,
mem_blk_hd->length);
printf("<==free memory 0x%x\n", (u8 *)mem_blk_hd+sizeof(*mem_blk_hd));
#endif
//
// Check that trailer was not corrupted
//
if(mem_ptn_tl->pattern0 != MEM_TAILER_PATTERN /*|| mem_ptn_tl->pattern1 != MEM_TAILER_PATTERN
|| mem_ptn_tl->pattern2 != MEM_TAILER_PATTERN || mem_ptn_tl->pattern3 != MEM_TAILER_PATTERN*/) {
printf("Memory %p was deallocated from %s at line %d \n", p, file, line);
printf("Memory tailer corruption due to overflow detected at %p\n", mem_ptn_hd);
printf("Tailer pattern 0(0x%x)\n",//, 1(0x%x), 2(0x%x), 3(0x%x)
mem_ptn_tl->pattern0/*,
mem_ptn_tl->pattern1,
mem_ptn_tl->pattern2,
mem_ptn_tl->pattern3*/);
//printf("Dumping information about memory block. "
// "This information may itself have been "
// "corrupted and could cause machine to bugcheck.\n");
printf("Memory was allocated from %s at line %d with length %d\n",
mem_blk_hd1->file, mem_blk_hd1->line, mem_blk_hd1->length);
haserr = 1;
}
if(needfree){
free(mem_ptn_hd);
}
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
if(haserr)
tls_mem_alloc_info();
}
void * mem_realloc_debug(void *mem_address, u32 size, char* file, int line)
{
void * mem_re_addr;
u32 cpu_sr;
if ((mem_re_addr = mem_alloc_debug(size, file, line)) == NULL){
printf("mem_realloc_debug failed(size=%d).\n", size);
return NULL;
}
if(mem_address != NULL)
{
cpu_sr = tls_os_set_critical();
memcpy(mem_re_addr, mem_address, size);
tls_os_release_critical(cpu_sr);
mem_free_debug(mem_address, file, line);
}
//printf("mem_realloc_debug mem_address=%p, mem_re_addr=%p, size=%d, file=%s, line=%d\n", mem_address, mem_re_addr, size, file, line);
return mem_re_addr;
}
void tls_mem_alloc_info(void)
{
int i;
MEMORY_BLOCK * pos;
u32 cpu_sr;
tls_os_sem_acquire(mem_sem, 0);
cpu_sr = tls_os_set_critical();
printf("==>Memory was allocated size %d, count %d\n",
alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
i = 1;
dl_list_for_each(pos, &memory_used_list, MEMORY_BLOCK, list){
printf("Block(%2d): addr<%p>, file<%s>, line<%d>, length<%d>\n",
i, pos->header_pattern, pos->file, pos->line, pos->length);
i++;
}
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
}
int is_safe_addr_debug(void* p, u32 len, char* file, int line)
{
int i;
MEMORY_BLOCK * pos;
u32 cpu_sr;
if(((u32)p) >= (u32)0x64ae8 || ((u32)p) < (u32)0x54ae8)
{
return 1;
}
tls_os_sem_acquire(mem_sem, 0);
cpu_sr = tls_os_set_critical();
i = 1;
dl_list_for_each(pos, &memory_used_list, MEMORY_BLOCK, list){
if((pos->header_pattern + sizeof (MEMORY_PATTERN) + PRE_OVERSIZE) <= ((u32)p) && ((u32)p) <= ((u32)(pos->header_pattern + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + pos->length)))
{
if(((u32)p) + len > ((u32)(pos->header_pattern + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + pos->length)))
{
printf("==>Memory oversize. Block(%2d): addr<%p>, file<%s>, line<%d>, length<%d>\n",
i, pos->header_pattern, pos->file, pos->line, pos->length);
break;
}
else
{
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
return 1;
}
}
//else if(((u32)p) < pos->header_pattern)
//{
// //tls_os_release_critical(cpu_sr);
// tls_os_sem_release(mem_sem);
// return 1;
// }
i++;
}
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
printf("==>Memory is not safe addr<%p>, file<%s>, line<%d>.\n",p, file, line);
return 0;
}
#else /* WM_MEM_DEBUG */
#if TLS_OS_FREERTOS
u32 alloc_heap_mem_bytes = 0;
u32 alloc_heap_mem_blk_cnt = 0;
u32 alloc_heap_mem_max_size = 0;
#define OS_MEM_FLAG (0x5AA5A55A)
#define MEM_HEAD_FLAG (0xBB55B55B)
#endif
void * mem_alloc_debug(u32 size)
{
u32 cpu_sr = 0;
u32 *buffer = NULL;
#if TLS_OS_FREERTOS
u32 flag = 0;
#endif
if (!memory_manager_initialized) {
tls_os_status_t os_status;
memory_manager_initialized = true;
//
// NOTE: If two thread allocate the very first allocation simultaneously
// it could cause double initialization of the memory manager. This is a
// highly unlikely scenario and will occur in debug versions only.
//
os_status = tls_os_sem_create(&mem_sem, 1);
if(os_status != TLS_OS_SUCCESS)
printf("mem_alloc_debug: tls_os_sem_create mem_sem error\n");
}
#if TLS_OS_FREERTOS
size += 8;
if(tls_get_isr_count() > 0)
{
extern void *pvPortMalloc( size_t xWantedSize );
buffer = pvPortMalloc(size);
flag = OS_MEM_FLAG;
}
else
{
tls_os_sem_acquire(mem_sem, 0);
cpu_sr = tls_os_set_critical();
buffer = (u32*)malloc(size);
}
if(buffer)
{
*buffer = MEM_HEAD_FLAG;
buffer++;
*buffer = flag;
buffer++;
}
if(tls_get_isr_count() == 0)
{
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
}
#else //UCOSII
cpu_sr = tls_os_set_critical();
buffer = (u32*)malloc(size);
tls_os_release_critical(cpu_sr);
#endif
// if(buffer == NULL)
// {
// printf("malloc error \n");
// }
return buffer;
}
void mem_free_debug(void *p)
{
u32 cpu_sr = 0;
#if TLS_OS_FREERTOS
u32* intMemPtr = (void*)p;
if(tls_get_isr_count() == 0)
{
tls_os_sem_acquire(mem_sem, 0);
cpu_sr = tls_os_set_critical();
}
if(p)
{
intMemPtr = intMemPtr - 2;
if(*intMemPtr != MEM_HEAD_FLAG)
{
//printf("mem_free_debug ptr error!!!!!\n");
}
else
{
intMemPtr++;
if(*intMemPtr == OS_MEM_FLAG)
{
extern void vPortFree( void *pv );
intMemPtr -= 1;
vPortFree(intMemPtr);
}
else
{
intMemPtr -= 1;
free(intMemPtr);
}
}
}
if(tls_get_isr_count() == 0)
{
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
}
#else //UCOSII
cpu_sr = tls_os_set_critical();
free(p);
tls_os_release_critical(cpu_sr);
#endif
}
void * mem_realloc_debug(void *mem_address, u32 size)
{
u32 * mem_re_addr = NULL;
u32 cpu_sr = 0;
#if TLS_OS_FREERTOS
u32 flag = 0;
u32 length = size + 8;
if(tls_get_isr_count() > 0)
{
extern void *pvPortMalloc( size_t xWantedSize );
mem_re_addr = pvPortMalloc(length);
flag = OS_MEM_FLAG;
if (mem_re_addr)
{
return NULL;
}
if(mem_address != NULL)
{
memcpy((u8 *)(mem_re_addr + 2), (u8 *)mem_address, size);
mem_free_debug(mem_address);
}
}
else
{
tls_os_sem_acquire(mem_sem, 0);
cpu_sr = tls_os_set_critical();
if (!mem_address)
{
mem_re_addr = (u32*)malloc(length);
}else{
mem_re_addr = (u32 *)realloc(((u32 *)mem_address-2), length);
}
}
if(mem_re_addr)
{
*mem_re_addr = MEM_HEAD_FLAG;
mem_re_addr++;
*mem_re_addr = flag;
mem_re_addr++;
}
if(tls_get_isr_count() == 0)
{
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
}
#else
cpu_sr = tls_os_set_critical();
mem_re_addr = realloc(mem_address, size);
tls_os_release_critical(cpu_sr);
#endif
if(mem_re_addr == NULL)
{
printf("realloc error \n");
}
return mem_re_addr;
}
void *mem_calloc_debug(u32 n, u32 size)
{
u32 cpu_sr = 0;
u32 *buffer = NULL;
u32 length = 0;
#if TLS_OS_FREERTOS
u32 flag = 0;
length = n*size;
length += 8;
if(tls_get_isr_count() > 0)
{
extern void *pvPortMalloc( size_t xWantedSize );
buffer = pvPortMalloc(length);
flag = OS_MEM_FLAG;
}
else
{
tls_os_sem_acquire(mem_sem, 0);
cpu_sr = tls_os_set_critical();
buffer = (u32*)malloc(length);
}
if(buffer)
{
memset(buffer, 0, length);
*buffer = MEM_HEAD_FLAG;
buffer++;
*buffer = flag;
buffer++;
}
if(tls_get_isr_count() == 0)
{
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
}
#else //UCOSII
cpu_sr = tls_os_set_critical();
buffer = (u32*)calloc(n,size);
tls_os_release_critical(cpu_sr);
#endif
// if(buffer == NULL)
// {
// printf("calloc error \n");
// }
return buffer;
}
/**
* @brief This function is used to get available memory
*
* @param[in] None
*
* @return None
*
* @note None.
*/
#if !defined(__CC_ARM)
extern unsigned int __HeapLimit;
#else
extern unsigned int __heap_limit;
#endif
unsigned int tls_mem_get_avail_heapsize(void)
{
unsigned int heap_size;
int *p = NULL;
unsigned int cpu_sr = 0;
tls_os_sem_acquire(mem_sem, 0);
cpu_sr = tls_os_set_critical();
p = malloc(4);
if (p)
{
#if !defined(__CC_ARM)
heap_size = (unsigned int)&__HeapLimit - (unsigned int)p;
#else
heap_size = (unsigned int)&__heap_limit - (unsigned int)p;
#endif
free(p);
p = NULL;
}else{
heap_size = 0;
}
tls_os_release_critical(cpu_sr);
tls_os_sem_release(mem_sem);
return heap_size;
}
#endif /* WM_MEM_DEBUG */
+160
View File
@@ -0,0 +1,160 @@
/**
* @file wm_wl_mbox.c
*
* @brief mailbox (mbox) APIs
*
* @author dave
*
* Copyright (c) 2015 Winner Microelectronics Co., Ltd.
*/
#include "wm_mem.h"
#include "wm_wl_mbox.h"
#include "wm_wl_task.h"
const void * const tls_null_pointer = (void *)0;
/**
* @brief create a malibox
*
* @param[out] *mbox pointer to the mailbox
* @param[in] size size of mailbox
*
* @retval TLS_OS_SUCCESS success
* @retval TLS_OS_ERROR failed
*
* @note None
*/
s8 tls_mbox_new(tls_mbox_t *mbox, int size)
{
s8 err;
tls_os_status_t status;
if (size == 0)
size = 10;
status = tls_os_queue_create(mbox, size);
if (status == TLS_OS_SUCCESS) {
err = TLS_OS_SUCCESS;
}
else
err = TLS_OS_ERROR;
return err;
}
#ifndef tls_mbox_valid
/**
* @brief check if an mbox is valid/allocated
*
* @param[in] mbox pointer to the mailbox
*
* @retval 0 invalid
* @retval 1 valid
*
* @note None
*/
int tls_mbox_valid(tls_mbox_t mbox)
{
if (mbox == NULL)
return 0;
else
return 1;
}
#endif
/**
* @brief sends a message to a mailbox
*
* @param[in] mbox pointer to the mailbox
* @param[in] *msg pointer to the message to be post
*
* @return None
*
* @note None
*/
void tls_mbox_post(tls_mbox_t mbox, void *msg)
{
u8 err;
u8 i=0;
if(msg == NULL )
msg = (void*)tls_null_pointer;
/* try 10 times */
while (i < 10)
{
err = tls_os_queue_send(mbox, msg, 0);
if(err == TLS_OS_SUCCESS)
break;
i++;
tls_os_time_delay(5);
}
}
/**
* @brief posts the "msg" to the mailbox.
*
* @param[in] mbox pointer to the mailbox
* @param[in] *msg pointer to the message to be post
*
* @retval TLS_OS_SUCCESS success
* @retval TLS_OS_ERROR failed
*
* @note this function have to block until the "msg" is really posted.
*/
s8 tls_mbox_trypost(tls_mbox_t mbox, void *msg)
{
u8 err;
if( msg == NULL )
{
msg = (void*)tls_null_pointer;
}
err = tls_os_queue_send(mbox, msg, 0);
if(err == TLS_OS_SUCCESS)
return TLS_OS_SUCCESS;
return TLS_OS_ERROR;
}
/**
* @brief waits for a message within the specified time
*
* @param[in] mbox pointer to the mailbox
* @param[out] **msg pointer to the message to be received
* @param[in] timeout the specified time
*
* @retval SYS_ARCH_TIMEOUT time out
* @retval other time of elapsed
*
* @note None
*/
u32 tls_arch_mbox_fetch(tls_mbox_t mbox, void **msg, u32 timeout)
{
u8 err;
u32 ucos_timeout = 0;
u32 in_timeout = timeout * HZ / 1000;
u32 tick_start, tick_stop, tick_elapsed;
if(timeout && in_timeout == 0)
in_timeout = 1;
tick_start = tls_os_get_time();
// *msg = OSQPend(mbox, in_timeout, &err);
err = tls_os_queue_receive(mbox,msg,0,in_timeout);
// if (err == OS_ERR_TIMEOUT ) {
if (err != TLS_OS_SUCCESS ) {
ucos_timeout = SYS_ARCH_TIMEOUT;
return ucos_timeout;
}
tick_stop = tls_os_get_time();
// Take care of wrap-around.
if( tick_stop >= tick_start )
tick_elapsed = tick_stop - tick_start;
else
tick_elapsed = 0xFFFFFFFF - tick_start + tick_stop ;
return tick_elapsed * 1000/HZ;
}
+164
View File
@@ -0,0 +1,164 @@
#include "wm_mem.h"
#include "wm_wl_timers.h"
#include "wm_wl_task.h"
#include <string.h>
static tls_mbox_t task_mbox[TLS_MBOX_ALL_COUNT];
struct task_msg wl_msg[TLS_MSG_ALL_COUONT];
//#define TLS_MSG_ID_TX_MGMT_CMPLT 0
//#define TLS_MSG_ID_MLME_TASK 1
static void
task_thread(void *arg)
{
struct task_msg *msg;
start_routine fun;
void * argu;
struct task_parameter *task_param = (struct task_parameter *)arg;
while (1) { /* MAIN Loop */
/* wait for a message, timeouts are processed while waiting */
tls_timeouts_mbox_fetch_p(task_param->timeo_id, task_mbox[task_param->mbox_id], (void **)&msg);
switch (msg->type) {
case TASK_MSG_CALLBACK:
msg->msg.cb.function(msg->msg.cb.ctx);
tls_mem_free(msg);
break;
case TASK_MSG_CALLBACK_STATIC:
fun = msg->msg.cbs.function;
argu = msg->msg.cbs.ctx;
msg->msg.cbs.cnt--;
fun(argu);
break;
case TASK_MSG_TIMEOUT:
tls_timeout_p(task_param->timeo_id, msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
tls_mem_free(msg);
break;
case TASK_MSG_UNTIMEOUT:
tls_untimeout_p(task_param->timeo_id, msg->msg.tmo.h, msg->msg.tmo.arg);
tls_mem_free(msg);
break;
default:
break;
}
}
}
s8 tls_wl_task_run(struct task_parameter *task_param)
{
if(tls_mbox_new(&task_mbox[task_param->mbox_id], task_param->mbox_size) != TLS_OS_SUCCESS) {
return -1;
}
tls_os_task_create(NULL, "WL_TSK",
//tls_os_task_create(NULL, task_param->name,
task_thread,
(void *)task_param,
(void *)(task_param->stk_start),
task_param->stk_size * sizeof(u32),
TLS_TASK_START_PRIO+task_param->task_id,
0);
return 0;
}
s8
tls_wl_task_callback_static(struct task_parameter *task_param, start_routine function, void *ctx, u8 block, u8 msg_id)
{
struct task_msg *msg = &wl_msg[msg_id];
if (msg->msg.cbs.cnt > 0)
return TLS_OS_ERROR;
if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
msg->type = TASK_MSG_CALLBACK_STATIC;
msg->msg.cbs.function = function;
msg->msg.cbs.ctx = ctx;
if (block) {
tls_mbox_post(task_mbox[task_param->mbox_id], (void *)msg);
}
else {
if (tls_mbox_trypost(task_mbox[task_param->mbox_id], (void *)msg) != TLS_OS_SUCCESS)
return TLS_OS_ERROR;
}
msg->msg.cbs.cnt++;
return TLS_OS_SUCCESS;
}
return TLS_OS_ERROR;
}
s8
tls_wl_task_callback(struct task_parameter *task_param, start_routine function, void *ctx, u8 block)
{
struct task_msg *msg;
if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
msg = (struct task_msg *)tls_mem_alloc(sizeof(struct task_msg));
if (msg == NULL) {
return TLS_OS_ERROR;
}
msg->type = TASK_MSG_CALLBACK;
msg->msg.cb.function = function;
msg->msg.cb.ctx = ctx;
if (block) {
tls_mbox_post(task_mbox[task_param->mbox_id], msg);
} else {
if (tls_mbox_trypost(task_mbox[task_param->mbox_id], msg) != TLS_OS_SUCCESS) {
//printf("tls_mbox_trypost error.\n");
tls_mem_free(msg);
return TLS_OS_ERROR;
}
}
return TLS_OS_SUCCESS;
}
return TLS_OS_ERROR;
}
s8
tls_wl_task_add_timeout(struct task_parameter *task_param, u32 msecs, tls_timeout_handler h, void *arg)
{
struct task_msg *msg;
if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
msg = (struct task_msg *)tls_mem_alloc(sizeof(struct task_msg));
if (msg == NULL) {
return TLS_OS_ERROR;
}
msg->type = TASK_MSG_TIMEOUT;
msg->msg.tmo.msecs = msecs;
msg->msg.tmo.h = h;
msg->msg.tmo.arg = arg;
tls_mbox_post(task_mbox[task_param->mbox_id], msg);
return TLS_OS_SUCCESS;
}
return TLS_OS_ERROR;
}
s8
tls_wl_task_untimeout(struct task_parameter *task_param, tls_timeout_handler h, void *arg)
{
struct task_msg *msg;
if (tls_mbox_valid(task_mbox[task_param->mbox_id])) {
msg = (struct task_msg *)tls_mem_alloc(sizeof(struct task_msg));
if (msg == NULL) {
return TLS_OS_ERROR;
}
msg->type = TASK_MSG_UNTIMEOUT;
msg->msg.tmo.h = h;
msg->msg.tmo.arg = arg;
tls_mbox_post(task_mbox[task_param->mbox_id], msg);
return TLS_OS_SUCCESS;
}
return TLS_OS_ERROR;
}
s8
tls_wl_task_init(void)
{
memset(wl_msg, 0, sizeof(struct task_msg));
return 0;
}
+180
View File
@@ -0,0 +1,180 @@
#include <string.h>
#include "wm_mem.h"
#include "wm_wl_timers.h"
#include "wm_wl_task.h"
struct tls_timeo {
struct tls_timeo *next;
u32 time;
tls_timeout_handler h;
void *arg;
};
/** The one and only timeout list */
struct tls_timeo *next_timeout[TLS_TIMEO_ALL_COUONT];
/**
* @brief Wait (forever) for a message to arrive in an mbox.
* While waiting, timeouts are processed
*
* @param[in] timeo_assigned timer NO. by assigned
* @param[in] mbox the mbox to fetch the message from
* @param[out] **msg the place to store the message
*
* @return None
*
* @note None
*/
void tls_timeouts_mbox_fetch_p(u8 timeo_assigned, tls_mbox_t mbox, void **msg)
{
u32 time_needed;
struct tls_timeo *tmptimeout;
tls_timeout_handler handler;
void *arg;
struct tls_timeo **timeo = &next_timeout[timeo_assigned];
again:
if (!(*timeo)) {
time_needed = tls_arch_mbox_fetch(mbox, msg, 0);
} else {
if ((*timeo)->time > 0) {
time_needed = tls_arch_mbox_fetch(mbox, msg, (*timeo)->time);
} else {
time_needed = SYS_ARCH_TIMEOUT;
}
if (time_needed == SYS_ARCH_TIMEOUT) {
/* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
could be fetched. We should now call the timeout handler and
deallocate the memory allocated for the timeout. */
tmptimeout = *timeo;
*timeo = tmptimeout->next;
handler = tmptimeout->h;
arg = tmptimeout->arg;
tls_mem_free(tmptimeout);
if (handler != NULL) {
handler(arg);
}
/* We try again to fetch a message from the mbox. */
goto again;
} else {
/* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
occured. The time variable is set to the number of
milliseconds we waited for the message. */
if (time_needed < (*timeo)->time) {
(*timeo)->time -= time_needed;
} else {
(*timeo)->time = 0;
}
}
}
}
/**
* @brief create a one-shot timer (aka timeout)
*
* @param[in] timeo_assigned timer NO. by assigned
* @param[in] msecs time in milliseconds after that the timer should expire
* @param[in] handler callback function that would be called by the timeout
* @param[in] *arg callback argument that would be passed to handler
*
* @return None
*
* @note while waiting for a message using sys_timeouts_mbox_fetch()
*/
void tls_timeout_p(u8 timeo_assigned, u32 msecs, tls_timeout_handler handler, void *arg)
{
struct tls_timeo *timeout, *t;
struct tls_timeo **timeo = &next_timeout[timeo_assigned];
timeout = (struct tls_timeo *)tls_mem_alloc(sizeof(struct tls_timeo));
if (timeout == NULL) {
return;
}
timeout->next = NULL;
timeout->h = handler;
timeout->arg = arg;
timeout->time = msecs;
if (*timeo == NULL) {
*timeo = timeout;
return;
}
if ((*timeo)->time > msecs) {
(*timeo)->time -= msecs;
timeout->next = *timeo;
*timeo = timeout;
} else {
for(t = *timeo; t != NULL; t = t->next) {
timeout->time -= t->time;
if (t->next == NULL || t->next->time > timeout->time) {
if (t->next != NULL) {
t->next->time -= timeout->time;
}
timeout->next = t->next;
t->next = timeout;
break;
}
}
}
}
/**
* @brief Go through timeout list (for this task only) and remove the first
* matching entry, even though the timeout has not triggered yet
*
* @param[in] timeo_assigned timer NO. by assigned
* @param[in] handler callback function that would be called by the timeout
* @param[in] *arg callback argument that would be passed to handler
*
* @return None
*
* @note None
*/
void tls_untimeout_p(u8 timeo_assigned, tls_timeout_handler handler, void *arg)
{
struct tls_timeo *prev_t, *t;
struct tls_timeo **timeo = &next_timeout[timeo_assigned];
if (*timeo == NULL) {
return;
}
for (t = *timeo, prev_t = NULL; t != NULL; prev_t = t, t = t->next) {
if ((t->h == handler) && (t->arg == arg)) {
/* We have a match */
/* Unlink from previous in list */
if (prev_t == NULL) {
*timeo = t->next;
} else {
prev_t->next = t->next;
}
/* If not the last one, add time of this one back to next */
if (t->next != NULL) {
t->next->time += t->time;
}
tls_mem_free(t);
return;
}
}
return;
}
/**
* @brief timer initialized
*
* @param None
*
* @return None
*
* @note None
*/
s8 tls_wl_timer_init(void)
{
memset(next_timeout, 0, sizeof(struct tls_timeo *) * TLS_TIMEO_ALL_COUONT);
return 0;
}
File diff suppressed because it is too large Load Diff
+11
View File
@@ -0,0 +1,11 @@
#ifndef WM_COMMON
#define WM_COMMON
#include "../Platform/Common/fwup/wm_fwup.c"
#include "../Platform/Common/task/wm_wl_mbox.c"
#include "../Platform/Common/task/wm_wl_task.c"
#include "../Platform/Common/task/wm_wl_timers.c"
#include "../Platform/Common/utils/utils.c"
#include "../Platform/Common/crypto/wm_crypto_hard.c"
#include "../Platform/Common/mem/wm_mem.c"
#include "../Platform/Common/Params/wm_param.c"
#endif //WM_COMMON
+291
View File
@@ -0,0 +1,291 @@
/**************************************************************************//**
* @file wm_i2s.c
* @author
* @version
* @date
* @brief
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd. All rights reserved.
*****************************************************************************/
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include "wm_regs.h"
#include "wm_7816.h"
#include "wm_gpio.h"
#include "wm_uart.h"
#include "wm_cpu.h"
#include "wm_osal.h"
#define DEBUG_7816 1
#if DEBUG_7816
#define PRINT_DEBUG(fmt, args...) do{(printf("[DEBUG] "), printf(fmt, ##args));}while(0)
#else
#define PRINT_DEBUG(fmt, args...)
#endif
#define SYS_CLK (40000000)
sc_io_map sc_io;
/**
* @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)
{
if (sc_io.initialed == 0)
{
printf("error : 7816 io map must init....\r\n");
return ;
}
if (mode) //gpio mode
{
tls_io_cfg_set(sc_io.clk_pin_num, WM_IO_OPTION5);
tls_io_cfg_set(sc_io.io_pin_num, WM_IO_OPTION5);
tls_gpio_cfg(sc_io.clk_pin_num, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
tls_gpio_cfg(sc_io.io_pin_num, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
}
else //7816 mode
{
tls_io_cfg_set(sc_io.clk_pin_num, sc_io.clk_opt);
tls_io_cfg_set(sc_io.io_pin_num, sc_io.io_opt);
}
}
/**
* @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)
{
uint32_t reg;
bgt = (bgt > 0x1f) ? 0x1F : bgt;
reg = tls_reg_read32(HR_UART2_LINE_CTRL);
reg &= ~(0x1f << 11);
reg |= (bgt << 11);
tls_reg_write32(HR_UART2_LINE_CTRL, reg);
}
/**
* @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)
{
uint32_t reg;
reg = tls_reg_read32(HR_UART2_LINE_CTRL);
reg &= ~(0x7 << 16);
tls_reg_write32(HR_UART2_LINE_CTRL, reg|(count<<16));
tls_bitband_write(HR_UART2_LINE_CTRL, 19, 1);
}
/**
* @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)
{
uint32_t reg;
reg = tls_reg_read32(HR_UART2_LINE_CTRL);
reg &= ~(0x7 << 20);
tls_reg_write32(HR_UART2_LINE_CTRL, reg|(count<<20));
tls_bitband_write(HR_UART2_LINE_CTRL, 23, 1);
}
/**
* @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)
{
uint32_t reg;
reg = tls_reg_read32(HR_UART2_BAUD_RATE_CTRL);
reg &= ~ 0xFFFF;
reg |= etu;
tls_reg_write32(HR_UART2_BAUD_RATE_CTRL, reg);
}
/**
* @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)
{
uint32_t reg;
uint8_t div;
tls_sys_clk clk;
tls_sys_clk_get(&clk);
div = (clk.apbclk * 1000000 + freq)/(2 * freq) - 1;
reg = tls_reg_read32(HR_UART2_BAUD_RATE_CTRL);
reg &= ~ 0x3F0000;
reg |= (div<<16);
tls_reg_write32(HR_UART2_BAUD_RATE_CTRL, reg);
}
/**
* @brief
* close af to use PB29 and PB30(uart2_rx as default if af is on) as gpio
* @retval
*/
void wm_sc_powerInit(void)
{
#ifdef WM_SC_PWR_PIN
u32 regValue;
// PB29 AF close, used as GPIO
regValue = tls_reg_read32(HR_GPIOB_AFSEL);
regValue &= ~0x20000000;
tls_reg_write32(HR_GPIOB_AFSEL, regValue);
// PB30 AF close, used as GPIO
regValue = tls_reg_read32(HR_GPIOB_AFSEL);
regValue &= ~0x40000000;
tls_reg_write32(HR_GPIOB_AFSEL, regValue);
#endif
}
/**
* @brief
* power on the 7816 device if power is controled by GPIO
* @retval
*/
void wm_sc_poweron(void)
{
#ifdef WM_SC_PWR_PIN
tls_gpio_cfg(WM_SC_PWR_PIN, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
tls_gpio_write(WM_SC_PWR_PIN, 1);
#endif
}
/**
* @brief
* power off the 7816 device if power is controled by GPIO
* @retval
*/
void wm_sc_poweroff(void)
{
#ifdef WM_SC_PWR_PIN
tls_gpio_cfg(WM_SC_PWR_PIN, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
tls_gpio_write(WM_SC_PWR_PIN, 0);
#endif
}
/**
* @brief
* driver the reset gpio in low level
* @retval
*/
void wm_sc_rst_low(void)
{
#ifdef WM_SC_RST_PIN
tls_gpio_cfg(WM_SC_RST_PIN, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
tls_gpio_write(WM_SC_RST_PIN, 0);
#endif
}
/**
* @brief
* driver the reset gpio in high level
* @retval
*/
void wm_sc_rst_high(void)
{
#ifdef WM_SC_RST_PIN
tls_gpio_cfg(WM_SC_RST_PIN, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
tls_gpio_write(WM_SC_RST_PIN, 1);
#endif
}
/**
* @brief
* hotrest the 7816 device obey the 7816-3 timing
* @retval
*/
void wm_sc_hotreset(void)
{
uint32_t delay = 0xffff;
/* set the rst pin to low */
wm_sc_rst_low();
/* delay */
while(delay--);
/* set f/d to default 372 */
wm_sc_set_etu(WM_SC_DEFAULT_FD);
/* set the rst pin to high */
wm_sc_rst_high();
}
/**
* @brief
* colreset the 7816 device obey the 7816-3 timing
* @retval
*/
void wm_sc_colreset(void)
{
/* power down */
wm_sc_poweroff();
/* select the clk io in gpio mode */
wm_sc_io_clk_config(1);
/* reset the clk pin */
tls_gpio_write(sc_io.clk_pin_num, 0);
/* reset the io pin */
tls_gpio_write(sc_io.io_pin_num, 0);
/* set the ret pin to low */
wm_sc_rst_low();
/* power on the card */
wm_sc_poweron();
/* config the model in 7816 mode */
wm_sc_7816_mode(1);
/* select the clk io pin in 7816 mode */
wm_sc_io_clk_config(0);
/* config the output clock freq*/
wm_sc_set_frequency(5000000);
/* set the F/D to default (372)*/
wm_sc_set_etu(WM_SC_DEFAULT_FD);
/* set the rst pin to high */
wm_sc_rst_high();
}
/**
* @brief
* deactive the 7816 device obey the 7816-3 timing
* @retval
*/
void wm_sc_deactive(void)
{
/* set the rst pin in low level*/
wm_sc_rst_low();
/* select the clk and io pin to 7816 mode */
wm_sc_io_clk_config(0);
/* disable the output clock */
wm_sc_clk_enable(0);
/* select the clk and io pin to gpio mode */
wm_sc_io_clk_config(1);
/* set the clk pin to low */
tls_gpio_write(sc_io.clk_pin_num, 0);
/* set the io pin to low */
tls_gpio_write(sc_io.io_pin_num, 0);
/* set the power pin to low */
wm_sc_poweroff();
}
+64
View File
@@ -0,0 +1,64 @@
# THE VERSION NUMBER
SET(CMAKE_SYSTEM_NAME Generic)
CMAKE_MINIMUM_REQUIRED (VERSION 3.10)
PROJECT(WMDRIVER)
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
SET(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
set(CMAKE_VERBOSE_MAKEFILE OFF)
# ENABLE ASM
ENABLE_LANGUAGE(ASM)
SET(CMAKE_STATIC_LIBRARY_PREFIX)
SET(CMAKE_STATIC_LIBRARY_SUFFIX)
SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX)
SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX)
# C FLAGS
SET(CMAKE_C_FLAGS " -mthumb --function-sections --data-sections -mcpu=cortex-m3 -std=gnu99 -mabi=aapcs -march=armv7-m -fno-builtin ")
STRING(APPEND CMAKE_C_FLAGS " -DGCC_COMPILE=1 -DWOLFSSL_USER_SETTINGS -D_IN_ADDR_T_DECLARED -D__MACHINE_ENDIAN_H__ -D_TIMEVAL_DEFINED -D__INSIDE_CYGWIN_NET__ ")
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -gdwarf-2 -Wall -DDEBUG ")
SET(CMAKE_C_FLAGS_RELEASE "-Os -Wall")
# DEBUG ASM FLAGS
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -O0 -g3 -gdwarf-2 -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin -DDEBUG ")
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE} -Os -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin ")
# Library sources
SET(LIBRARY_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/adc/wm_adc.c"
"${CMAKE_CURRENT_SOURCE_DIR}/cpu/wm_cpu.c"
"${CMAKE_CURRENT_SOURCE_DIR}/dma/wm_dma.c"
"${CMAKE_CURRENT_SOURCE_DIR}/efuse/wm_efuse.c"
"${CMAKE_CURRENT_SOURCE_DIR}/flash/wm_fls.c"
"${CMAKE_CURRENT_SOURCE_DIR}/flash/wm_fls_gd25qxx.c"
"${CMAKE_CURRENT_SOURCE_DIR}/gpio/wm_gpio.c"
"${CMAKE_CURRENT_SOURCE_DIR}/gpio/wm_gpio_afsel.c"
"${CMAKE_CURRENT_SOURCE_DIR}/hspi/wm_hspi.c"
"${CMAKE_CURRENT_SOURCE_DIR}/i2c/wm_i2c.c"
"${CMAKE_CURRENT_SOURCE_DIR}/irq/wm_irq.c"
"${CMAKE_CURRENT_SOURCE_DIR}/pwm/wm_pwm.c"
"${CMAKE_CURRENT_SOURCE_DIR}/pmu/wm_pmu.c"
"${CMAKE_CURRENT_SOURCE_DIR}/rtc/wm_rtc.c"
"${CMAKE_CURRENT_SOURCE_DIR}/spi/wm_hostspi.c"
"${CMAKE_CURRENT_SOURCE_DIR}/timer/wm_timer.c"
"${CMAKE_CURRENT_SOURCE_DIR}/uart/wm_uart.c"
"${CMAKE_CURRENT_SOURCE_DIR}/watchdog/wm_watchdog.c"
"${CMAKE_CURRENT_SOURCE_DIR}/internalflash/wm_internal_fls.c"
"${CMAKE_CURRENT_SOURCE_DIR}/i2s/wm_i2s.c"
"${CMAKE_CURRENT_SOURCE_DIR}/io/wm_io.c"
"${CMAKE_CURRENT_SOURCE_DIR}/lcd/wm_lcd.c"
"${CMAKE_CURRENT_SOURCE_DIR}/7816/wm_7816.c"
)
function(ADD_LIB_TARGET LIBTARGET)
add_library(${LIBTARGET} OBJECT ${LIBRARY_SOURCES})
# ADD_CUSTOM_COMMAND(TARGET ${LIBTARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXECUTABLE_OUTPUT_PATH}/${LIBTARGET} ${CMAKE_CURRENT_SOURCE_DIR}/../../Lib/GNU/${LIBTARGET})
endfunction()
ADD_LIB_TARGET(wmdriver.a)
+517
View File
@@ -0,0 +1,517 @@
/*****************************************************************************
*
* File Name : wm_adc.c
*
* Description: adc Driver Module
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
* All rights reserved.
*
* Author : dave
*
* Date : 2014-8-15
*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "wm_regs.h"
#include "wm_adc.h"
#include "wm_dma.h"
#include "misc.h"
#include "wm_io.h"
#include "wm_irq.h"
static u16 adc_offset = 0;
volatile ST_ADC gst_adc;
volatile u8 adc_irq_flag = 0;
void ADC_IRQHandler(void)
{
u16 adcvalue;
int reg;
reg = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
if(reg & CONFIG_ADC_INT) //ADC�ж�
{
adc_irq_flag = 1;
tls_adc_clear_irq(ADC_INT_TYPE_ADC);
adcvalue = tls_read_adc_result();
if(gst_adc.adc_cb)
gst_adc.adc_cb(&adcvalue,1);
}
if(reg & CONFIG_ADC_INT_CMP)
{
tls_adc_clear_irq(ADC_INT_TYPE_ADC_COMP);
if(gst_adc.adc_bigger_cb)
gst_adc.adc_bigger_cb(NULL, 0);
}
}
static void adc_dma_isr_callbk(void)
{
if(gst_adc.adc_dma_cb)
gst_adc.adc_dma_cb((u16 *)(ADC_DEST_BUFFER_DMA), gst_adc.valuelen);
}
void tls_adc_init(u8 ifusedma,u8 dmachannel)
{
tls_reg_write32(HR_SD_ADC_CONFIG_REG, 0x0);
tls_irq_enable(ADC_IRQn);
//ע���жϺ�channel�йأ�������Ҫ������
if(ifusedma)
{
gst_adc.dmachannel = tls_dma_request(dmachannel, 0); //����dma����Ҫֱ��ָ������Ϊ�����dma���ܻᱻ�������ʹ��
tls_dma_irq_register(gst_adc.dmachannel, (void(*)(void*))adc_dma_isr_callbk, NULL, TLS_DMA_IRQ_TRANSFER_DONE);
}
//printf("\ndma channel = %d\n",gst_adc.dmachannel);
}
void tls_adc_clear_irq(int inttype)
{
int reg;
reg = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
if(ADC_INT_TYPE_ADC == inttype)
{
reg |= CONFIG_ADC_INT;
tls_reg_write32(HR_SD_ADC_CONFIG_REG, reg);
}
else if(ADC_INT_TYPE_ADC_COMP== inttype)
{
reg |= CONFIG_ADC_INT_CMP;
tls_reg_write32(HR_SD_ADC_CONFIG_REG, reg);
}
else if(ADC_INT_TYPE_DMA == inttype)
{
tls_dma_irq_clr(gst_adc.dmachannel, TLS_DMA_IRQ_TRANSFER_DONE);
}
}
void tls_adc_irq_register(int inttype, void (*callback)(u16 *buf, u16 len))
{
if(ADC_INT_TYPE_ADC == inttype)
{
gst_adc.adc_cb = callback;
}
else if(ADC_INT_TYPE_DMA == inttype)
{
gst_adc.adc_dma_cb = callback;
}
else if(ADC_INT_TYPE_ADC_COMP == inttype)
{
gst_adc.adc_bigger_cb = callback;
}
}
u16 tls_read_adc_result(void)
{
u32 value;
u16 ret;
value = tls_reg_read32(HR_SD_ADC_RESULT_REG);
ret = value&0x3fff;
return ret;
}
void tls_adc_start_with_cpu(int Channel)
{
u32 value;
Channel &= CONFIG_ADC_CHL_MASK;
/* Stop adc first */
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value &= ~CONFIG_ADC_DMA_MASK;
value &= ~CONFIG_ADC_START;
value |= Channel;
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value |= CONFIG_ADC_START;
value |= CONFIG_ADC_INT_MASK;
if(Channel < 8)
{
value |= CONFIG_ADC_G_CTRL12;
value &= ~ CONFIG_ADC_VCM(0x3F);
value |= CONFIG_ADC_VCM(0x1F);
}
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
}
void tls_adc_enable_calibration_buffer_offset(void)
{
u32 value;
/* Stop adc first */
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value &= ~CONFIG_ADC_DMA_MASK;
value &= ~CONFIG_ADC_START;
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value |= CONFIG_ADC_CHL_OFFSET;
value |= CONFIG_ADC_START;
value |= CONFIG_ADC_INT_MASK;
value |= CONFIG_ADC_EN_CAL;
value |= CONFIG_ADC_G_CTRL12;
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
}
void tls_adc_temp_offset_with_cpu(u8 calTemp12)
{
u32 value;
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value &= ~CONFIG_ADC_DMA_MASK;
value &= ~CONFIG_ADC_START;
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value |= CONFIG_ADC_CHL_TEMP;
value |= CONFIG_ADC_START;
value |= CONFIG_ADC_INT_MASK;
if(calTemp12)
{
value |= CONFIG_ADC_CAL_OFFSET_TEMP12;
}
else
{
value &= ~CONFIG_ADC_CAL_OFFSET_TEMP12;
}
value &= ~CONFIG_ADC_G_CTRL12;
value |= CONFIG_ADC_TEMP_ON;
value |= CONFIG_ADC_G_TEMP12(3);
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value); /*start adc*/
}
void tls_adc_voltage_start_with_cpu(void)
{
u32 value;
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value &= ~CONFIG_ADC_DMA_MASK;
value &= ~CONFIG_ADC_START;
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value |= CONFIG_ADC_CHL_VOLT;
value |= CONFIG_ADC_START;
value |= CONFIG_ADC_INT_MASK;
value |= CONFIG_ADC_G_CTRL12;
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value); /*start adc*/
}
void tls_adc_start_with_dma(int Channel, int Length)
{
u32 value;
int len;
if(Channel < 0 || Channel > 11)
return;
if(Length > ADC_DEST_BUFFER_SIZE)
len = ADC_DEST_BUFFER_SIZE;
else
len = Length;
gst_adc.valuelen = len;
Channel &= CONFIG_ADC_CHL_MASK;
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value &= ~CONFIG_ADC_START; //stop
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
/* Stop dma if necessary */
while(DMA_CHNLCTRL_REG(gst_adc.dmachannel) & 1)
{
DMA_CHNLCTRL_REG(gst_adc.dmachannel) = 2;
}
DMA_SRCADDR_REG(gst_adc.dmachannel) = HR_SD_ADC_RESULT_REG;
DMA_DESTADDR_REG(gst_adc.dmachannel) = ADC_DEST_BUFFER_DMA;
/* Hard, Normal, adc_req */
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
if (Channel == 8){
DMA_MODE_REG(gst_adc.dmachannel) = (0x01 | (0+6)<<2);
value |= (0x1 << 11);
}
else if (Channel == 9){
DMA_MODE_REG(gst_adc.dmachannel) = (0x01 | (2+6)<<2);
value |= (0x1 << 13);
}
else if (Channel == 10){
DMA_MODE_REG(gst_adc.dmachannel) = (0x01 | (4+6)<<2);
value |= (0x1 << 15);
}
else if (Channel == 11){
DMA_MODE_REG(gst_adc.dmachannel) = (0x01 | (6+6)<<2);
value |= (0x1 << 17);
}
else{
DMA_MODE_REG(gst_adc.dmachannel) = (0x01 | (Channel+6)<<2);
value |= (0x1 << (11 + Channel));
}
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
/* Dest_add_inc, halfword, */
DMA_CTRL_REG(gst_adc.dmachannel) = (1<<3)|(1<<5)|((len*2)<<8);
DMA_INTMASK_REG &= ~(0x01 << (gst_adc.dmachannel *2 + 1));
DMA_CHNLCTRL_REG(gst_adc.dmachannel) = 1; /* Enable dma */
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value |= CONFIG_ADC_START;
value |= Channel;
if(Channel < 8)
{
value |= CONFIG_ADC_G_CTRL12;
value &= ~ CONFIG_ADC_VCM(0x3F);
value |= CONFIG_ADC_VCM(0x1F);
}
// printf("config value==%x\n", value);
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value); /*start adc*/
}
void tls_adc_stop(int ifusedma)
{
u32 value;
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value &= ~CONFIG_ADC_START;
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
if(ifusedma)
tls_dma_free(gst_adc.dmachannel);
}
void tls_adc_config_cmp_reg(int cmp_data, int cmp_pol)
{
u32 value;
cmp_data &= 0x3FFF;
value = tls_reg_read32(HR_SD_ADC_RESULT_REG);
value &= ~(0x3FFF<<14);
value |= (cmp_data<<14);
tls_reg_write32(HR_SD_ADC_RESULT_REG, value);
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value |= CONFIG_ADC_CMP_INT_MASK;
if(cmp_pol)
{
value |= CONFIG_ADC_CMP_POL;
}
else
{
value &= ~CONFIG_ADC_CMP_POL;
}
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
}
void tls_adc_cmp_start(int Channel, int cmp_data, int cmp_pol)
{
u32 value;
Channel &= CONFIG_ADC_CHL_MASK;
/* Stop adc first */
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value &= ~CONFIG_ADC_DMA_MASK;
value &= ~CONFIG_ADC_START;
value |= Channel;
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
tls_adc_config_cmp_reg(cmp_data, cmp_pol);
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
value |= CONFIG_ADC_START;
if(Channel < 8)
{
value |= CONFIG_ADC_G_CTRL12;
value &= ~ CONFIG_ADC_VCM(0x3F);
value |= CONFIG_ADC_VCM(0x1F);
}
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value); /*start adc*/
}
void tls_adc_reference_sel(int ref)
{
u32 value;
value = tls_reg_read32(HR_SD_ADC_CONFIG_REG);
if(ADC_REFERENCE_EXTERNAL == ref)
{
value &= ~CONFIG_ADC_REF_SEL;
value |= CONFIG_ADC_BUF_BYPASS;
}
else if(ADC_REFERENCE_INTERNAL == ref)
{
value |= CONFIG_ADC_REF_SEL;
value &= ~CONFIG_ADC_BUF_BYPASS;
}
tls_reg_write32(HR_SD_ADC_CONFIG_REG, value);
}
void tls_adc_set_clk(int div)
{
u32 value;
value = tls_reg_read32(HR_CLK_DIV_CTL);
value &= ~(0xffff<<12);
value |= (div << 12);
value |= ((u32)0x1<<31);
tls_reg_write32(HR_CLK_DIV_CTL, value);
}
void signedToUnsignedData(u16 *adcValue, u16 *offset)
{
// s16 temp = 0;
if(*adcValue >= 8192)
{
*adcValue -= 8192;
}
else
{
*adcValue += 8192;
}
/* if (*offset >=8192)
{
temp =((*offset-1)&0x1FFF) - 8192;
}else{
temp = *offset;
}
*adcValue -= temp;
*/
}
static void waitForAdcDone(void)
{
while(1)
{
if(adc_irq_flag) //ADC�ж�
{
adc_irq_flag = 0;
break;
}
}
}
static void waitForStable(void)
{
volatile u32 count;
count = 2000;
while( count-- );
}
u16 adc_get_offset(void)
{
tls_adc_init(0, 0);
tls_adc_reference_sel(ADC_REFERENCE_INTERNAL);
adc_irq_flag = 0;
waitForStable();
tls_adc_enable_calibration_buffer_offset(); //ʹ��У׼����
waitForAdcDone();
adc_offset = tls_read_adc_result(); //��ȡadcת�����
tls_adc_stop(0);
//printf("\r\noffset:%d", adc_offset);
return adc_offset;
}
u32 adc_get_interTemp(void)
{
u16 code2, code1, realCode;
u32 tem;
tls_adc_init(0, 0);
tls_adc_reference_sel(ADC_REFERENCE_INTERNAL);
adc_irq_flag = 0;
waitForStable();
tls_adc_temp_offset_with_cpu(1); //code2
waitForAdcDone();
code2 = tls_read_adc_result();
tls_adc_stop(0);
signedToUnsignedData(&code2, &adc_offset);
adc_irq_flag = 0;
waitForStable();
tls_adc_temp_offset_with_cpu(0); //code1
waitForAdcDone();
code1 = tls_read_adc_result();
tls_adc_stop(0);
signedToUnsignedData(&code1, &adc_offset);
realCode = ( (code1-code2)/2+8192 );
//printf("code1:%d, code2:%d, realCode:%d\r\n", code1, code2, realCode);
//printf("\r\nTEMP:%.1f", realCode*0.12376-1294.58);
//return (realCode*0.12376-1294.58);
tem = realCode*124-1294580;
//printf("tem:%d\r\n", tem);
return tem;
}
u16 adc_get_inputVolt(u8 channel)
{
u16 average = 0;
/*calibration*/
adc_get_offset();
/*get value*/
tls_adc_init(0, 0);
tls_adc_reference_sel(ADC_REFERENCE_INTERNAL);
adc_irq_flag = 0;
waitForStable();
tls_adc_start_with_cpu(channel);
waitForAdcDone();
average = tls_read_adc_result();
tls_adc_stop(0);
signedToUnsignedData(&average, &adc_offset);
//printf("ch[%d]inputVolt:%.3f\r\n", channel+1, ((average-8192.0)/8192*2.25/1.2 + 1.584));
return average;
}
u16 adc_get_interVolt(void)
{
u16 voltValue;
/*calibration*/
adc_get_offset();
/*get value*/
tls_adc_init(0, 0);
tls_adc_reference_sel(ADC_REFERENCE_INTERNAL);
adc_irq_flag = 0;
waitForStable();
tls_adc_voltage_start_with_cpu();
waitForAdcDone();
voltValue = tls_read_adc_result();
tls_adc_stop(0);
signedToUnsignedData(&voltValue, &adc_offset);
float voltage = ( 1.214 - ((float)voltValue-8192)/8192*2.25/1.2 )*2;
printf("interVolt:%.2f\r\n", voltage);
return voltValue;
}
u32 adc_temp(void)
{
u32 tem;
adc_get_offset();
tem = adc_get_interTemp();
return tem;
}
+86
View File
@@ -0,0 +1,86 @@
/**
* @file wm_cpu.c
*
* @brief cpu driver module
*
* @author kevin
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
*/
#include "wm_debug.h"
#include "wm_regs.h"
#include "wm_irq.h"
#include "wm_cpu.h"
#include "wm_pwm.h"
#include "wm_uart.h"
#include "wm_wifi.h"
extern void Debug_UartInit(void);
void tls_sys_clock_switch_hook(void)
{
tls_sys_clk sysclk;
tls_sys_clk_get(&sysclk);
tls_reg_write32(HR_TIMER_CFG, sysclk.apbclk-1);
/*to do, like uart baudrate switch, other device clock switch*/
tls_uart_set_baud_rate(0, 115200);
}
/**
* @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)
{
u32 RegValue;
u8 wlanDiv, cpuDiv;
RegValue = tls_reg_read32(HR_CLK_DIV_CTL);
wlanDiv = (RegValue>>4)&0x0F;
RegValue &= 0xFFFFF000;
RegValue |= 0x80000000;
switch(clk)
{
case CPU_CLK_40M:
cpuDiv = 4;
break;
default:
cpuDiv = 2;
break;
}
RegValue |= ((wlanDiv*4/cpuDiv)<<8) | (wlanDiv<<4) | cpuDiv;
tls_reg_write32(HR_CLK_DIV_CTL, RegValue);
return;
}
/**
* @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)
{
u32 value;
value = tls_reg_read32(HR_CLK_DIV_CTL);
sysclk->apbclk = W600_PLL_CLK_MHZ/4/((value>>4)&0x0F);
sysclk->cpuclk = W600_PLL_CLK_MHZ/(value&0x0F);
sysclk->wlanclk = W600_PLL_CLK_MHZ/((value>>4)&0x0F);
}
+405
View File
@@ -0,0 +1,405 @@
/**
* @file wm_dma.c
*
* @brief DMA Driver Module
*
* @author dave
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "misc.h"
#include "wm_dma.h"
#include "wm_regs.h"
#include "wm_irq.h"
#include "wm_osal.h"
#include "wm_pmu.h"
static u16 dma_used_bit = 0;
struct tls_dma_channels {
unsigned char channels[8]; /* list of channels */
};
typedef void (*dma_irq_callback)(void *p);
struct dma_irq_context {
u8 flags;
dma_irq_callback burst_done_pf;
void *burst_done_priv;
dma_irq_callback transfer_done_pf;
void *transfer_done_priv;
};
static struct dma_irq_context dma_context[8];
static struct tls_dma_channels channels;
extern void wm_delay_ticks(uint32_t ticks);
static void dma_irq_proc(void *p)
{
unsigned char ch;
unsigned int int_src;
ch = (unsigned char)(unsigned long)p;
int_src = tls_reg_read32(HR_DMA_INT_SRC);
if (ch > 3)
{
for (ch = 4; ch < 8; ch++)
{
if (int_src & (TLS_DMA_IRQ_BOTH_DONE << ch * 2))
break;
}
if (8 == ch)
return;
}
if ((int_src & (TLS_DMA_IRQ_BOTH_DONE << ch * 2)) &&
(TLS_DMA_IRQ_BOTH_DONE == dma_context[ch].flags))
{
tls_dma_irq_clr(ch, TLS_DMA_IRQ_BOTH_DONE);
if (dma_context[ch].burst_done_pf)
dma_context[ch].burst_done_pf(dma_context[ch].burst_done_priv);
}
else if ((int_src & (TLS_DMA_IRQ_BURST_DONE << ch * 2)) &&
(TLS_DMA_IRQ_BURST_DONE == dma_context[ch].flags))
{
tls_dma_irq_clr(ch, TLS_DMA_IRQ_BOTH_DONE);
if (dma_context[ch].burst_done_pf)
dma_context[ch].burst_done_pf(dma_context[ch].burst_done_priv);
}
else if ((int_src & (TLS_DMA_IRQ_TRANSFER_DONE << ch * 2)) &&
(TLS_DMA_IRQ_TRANSFER_DONE == dma_context[ch].flags))
{
tls_dma_irq_clr(ch, TLS_DMA_IRQ_BOTH_DONE);
if (dma_context[ch].transfer_done_pf)
dma_context[ch].transfer_done_pf(dma_context[ch].transfer_done_priv);
}
return;
}
void DMA_Channel0_IRQHandler(void)
{
dma_irq_proc((void *)0);
}
void DMA_Channel1_IRQHandler(void)
{
dma_irq_proc((void *)1);
}
void DMA_Channel2_IRQHandler(void)
{
dma_irq_proc((void *)2);
}
void DMA_Channel3_IRQHandler(void)
{
dma_irq_proc((void *)3);
}
void DMA_Channel4_7_IRQHandler(void)
{
dma_irq_proc((void *)4);
}
/**
* @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)
{
unsigned int int_src = 0;
int_src |= flags << 2 * ch;
tls_reg_write32(HR_DMA_INT_SRC, int_src);
return;
}
/**
* @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)
{
unsigned int mask;
mask = tls_reg_read32(HR_DMA_INT_MASK);
mask |= TLS_DMA_IRQ_BOTH_DONE << 2 * ch;
mask &= ~(flags << 2 * ch);
tls_reg_write32(HR_DMA_INT_MASK, mask);
dma_context[ch].flags = flags;
if (flags & TLS_DMA_IRQ_BURST_DONE)
{
dma_context[ch].burst_done_pf = callback;
dma_context[ch].burst_done_priv = arg;
}
if (flags & TLS_DMA_IRQ_TRANSFER_DONE)
{
dma_context[ch].transfer_done_pf = callback;
dma_context[ch].transfer_done_priv = arg;
}
if (ch > 3)
ch = 4;
tls_irq_enable(DMA0_INT + ch);
return;
}
/**
* @brief This function is used to Wait until DMA operation completes
*
* @param[in] ch channel no
*
* @retval 0 completed
* @retval -1 failed
*
* @note None
*/
int tls_dma_wait_complt(unsigned char ch)
{
unsigned long timeout = 0;
while(DMA_CHNLCTRL_REG(ch) & DMA_CHNL_CTRL_CHNL_ON)
{
tls_os_time_delay(1);
timeout ++;
if(timeout > 500)
return -1;
}
return 0;
}
/**
* @brief This function is used to Start the DMA controller by Wrap
*
* @param[in] ch channel no
* @param[in] dma_desc pointer to DMA channel descriptor structure
* @param[in] auto_reload does restart when current transfer complete
* @param[in] src_zize dource address size
* @param[in] dest_zize destination address size
*
* @retval 1 success
* @retval 0 failed
*
* @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)
{
if((ch > 7) && !dma_desc) return 1;
DMA_SRCWRAPADDR_REG(ch) = dma_desc->src_addr;
DMA_DESTWRAPADDR_REG(ch) = dma_desc->dest_addr;
DMA_WRAPSIZE_REG(ch) = (dest_zize << 16) | src_zize;
DMA_CTRL_REG(ch) = ((dma_desc->dma_ctrl & 0x1ffff) << 1) | (auto_reload ? 0x1: 0x0);
DMA_CHNLCTRL_REG(ch) |= DMA_CHNL_CTRL_CHNL_ON;
return 0;
}
/**
* @brief This function is used to Start the DMA controller
*
* @param[in] ch channel no
* @param[in] dma_desc pointer to DMA channel descriptor structure
* @param[in] auto_reload does restart when current transfer complete
*
* @retval 0 success
* @retval 1 failed
*
* @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)
{
if((ch > 7) && !dma_desc) return 1;
if ((dma_used_bit &(1<<ch)) == 0)
{
dma_used_bit |= (1<<ch);
}
DMA_SRCADDR_REG(ch) = dma_desc->src_addr;
DMA_DESTADDR_REG(ch) = dma_desc->dest_addr;
DMA_CTRL_REG(ch) = ((dma_desc->dma_ctrl & 0x7fffff) << 1) | (auto_reload ? 0x1: 0x0);
DMA_CHNLCTRL_REG(ch) |= DMA_CHNL_CTRL_CHNL_ON;
return 0;
}
/**
* @brief This function is used to To stop current DMA channel transfer
*
* @param[in] ch channel no. to be stopped
*
* @retval 0 success
* @retval 1 failed
*
* @note
* If channel stop, DMA_CHNL_CTRL_CHNL_ON bit in DMA_CHNLCTRL_REG is cleared.
*/
unsigned char tls_dma_stop(unsigned char ch)
{
if(ch > 7) return 1;
if(DMA_CHNLCTRL_REG(ch) & DMA_CHNL_CTRL_CHNL_ON)
{
DMA_CHNLCTRL_REG(ch) |= DMA_CHNL_CTRL_CHNL_OFF;
while(DMA_CHNLCTRL_REG(ch) & DMA_CHNL_CTRL_CHNL_ON);
}
return 0;
}
/**
* @brief This function is used to Request a free dma channel
*
* @param[in] ch channel no.
* @param[in] flags flags setted to selected channel
*
* @return Channel no. that is free now
*
* @note
* If ch is 0, the function will select a random free channel,
* else return the selected channel no.
*/
unsigned char tls_dma_request(unsigned char ch, unsigned char flags)
{
unsigned char freeCh = 0;
int i = 0;
if (ch == 0)
{
for (i = 0; i < 8; i++)
{
if (!(channels.channels[i] & TLS_DMA_FLAGS_CHANNEL_VALID))
{
freeCh = i;
break;
}
}
if (8 == i)
{
printf("!!!there is no free DMA channel.!!!\n");
freeCh = 0;
}
}
else if ((ch >0) && (ch < 8))
{
if (!(channels.channels[ch] & TLS_DMA_FLAGS_CHANNEL_VALID))
{
freeCh = ch;
}
else
{
printf("!!!there is no free DMA channel.!!!\n");
freeCh = 0;
}
}
//if(freeCh != 0)
{
channels.channels[freeCh] = flags | TLS_DMA_FLAGS_CHANNEL_VALID;
DMA_MODE_REG(freeCh) = flags;
}
if (dma_used_bit == 0)
{
tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_DMA);
}
dma_used_bit |= (1<<freeCh);
return freeCh;
}
/**
* @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)
{
if(ch < 8)
{
tls_dma_stop(ch);
DMA_SRCADDR_REG(ch) = 0;
DMA_DESTADDR_REG(ch) = 0;
DMA_MODE_REG(ch) = 0;
DMA_CTRL_REG(ch) = 0;
// DMA_INTSRC_REG = 0xffff;
DMA_INTSRC_REG |= 0x03<<(ch*2);
channels.channels[ch] = 0x00;
dma_used_bit &= ~(1<<ch);
if (dma_used_bit == 0)
{
tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_DMA);
}
}
}
/**
* @brief This function is used to Initialize DMA Control
*
* @param[in] None
*
* @return None
*
* @note None
*/
void tls_dma_init(void)
{
DMA_INTMASK_REG = 0xffff;
DMA_INTSRC_REG = 0xffff;
}
+644
View File
@@ -0,0 +1,644 @@
/**************************************************************************
* File Name : tls_efuse.c
* Author :
* Version :
* Date :
* Description : Use Flash Addr as virtual efuse
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
* All rights reserved.
*
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "wm_debug.h"
#include "wm_regs.h"
#include "wm_efuse.h"
#include "wm_config.h"
#include "list.h"
#include "wm_internal_flash.h"
#include "wm_crypto_hard.h"
#include "wm_timer.h"
#include "wm_cpu.h"
#include "wm_irq.h"
#include "wm_flash_map.h"
#include "wm_mem.h"
extern void flashSRRW(unsigned long offset,unsigned char *buf,unsigned long sz, unsigned char *backbuf, unsigned int backlen, unsigned int rd);
#define FT_MAGICNUM_ADDR (FLASH_BASE_ADDR)
#define MAGICNUM_LEN (4)
#define FT_CHECKSUM_ADDR (FT_MAGICNUM_ADDR + MAGICNUM_LEN)
#define CHECKSUM_LEN (4)
#define FT_DATALEN_ADDR (FT_CHECKSUM_ADDR + CHECKSUM_LEN)
#define FT_DATALEN_LEN (4)
#define FT_MAC_ADDR (FT_DATALEN_ADDR + FT_DATALEN_LEN)
#define MAC_ADDR_LEN (8)
#define FT_TX_DC_OFFSET_ADDR (FT_MAC_ADDR + MAC_ADDR_LEN)
#define TX_DC_OFFSET_LEN (4)
#define FT_RX_DC_OFFSET_ADDR (FT_TX_DC_OFFSET_ADDR + TX_DC_OFFSET_LEN)
#define RX_DC_OFFSET_LEN (4)
#define FT_TX_IQ_GAIN_ADDR (FT_RX_DC_OFFSET_ADDR + RX_DC_OFFSET_LEN)
#define TX_IQ_GAIN_LEN (4)
#define FT_RX_IQ_GAIN_ADDR (FT_TX_IQ_GAIN_ADDR + TX_IQ_GAIN_LEN)
#define RX_IQ_GAIN_LEN (4)
#define FT_TX_IQ_PHASE_ADDR (FT_RX_IQ_GAIN_ADDR + RX_IQ_GAIN_LEN)
#define TX_IQ_PHASE_LEN (4)
#define FT_RX_IQ_PHASE_ADDR (FT_TX_IQ_PHASE_ADDR + TX_IQ_PHASE_LEN)
#define RX_IQ_PHASE_LEN (4)
#define FT_GAIN_ADDR (FT_RX_IQ_PHASE_ADDR + RX_IQ_PHASE_LEN)
#define FT_GAIN_LEN (84)
#define FT_FIX_DATA_LEN (MAC_ADDR_LEN + TX_DC_OFFSET_LEN + RX_DC_OFFSET_LEN + TX_IQ_GAIN_LEN + RX_IQ_GAIN_LEN \
+ TX_IQ_PHASE_LEN \
+ RX_IQ_PHASE_LEN)
/* key paramater area -- begin -- */
/** PHY parameter area **/
#define PHY_BASE_ADDR (FLASH_BASE_ADDR)
#define PHY_AREA_LEN (0x1000)
/** QFlash parameter area **/
#define QFLASH_BASE_ADDR (PHY_BASE_ADDR + PHY_AREA_LEN)
#define QFLASH_AREA_LEN (0x1000)
#define QFLASH_HDR_BASE_ADDR (QFLASH_BASE_ADDR)
#define QFLASH_HDR_LEN (12)
#define QFLASH_Sec_Level_BASE_ADDR (QFLASH_HDR_BASE_ADDR + QFLASH_HDR_LEN)
#define QFLASH_Sec_Level_LEN (4)
#define QFLASH_CHIP_ID_BASE_ADDR (QFLASH_Sec_Level_BASE_ADDR + QFLASH_Sec_Level_LEN)
#define QFLASH_CHIP_ID_LEN (16)
/* key parameter area -- end -- */
typedef struct FT_PARAM
{
unsigned int magic_no;
unsigned int checksum;
unsigned int data_len;
unsigned char mac_addr[MAC_ADDR_LEN];
unsigned int tx_dcoffset;
unsigned int rx_dcoffset;
unsigned int tx_iq_gain;
unsigned int rx_iq_gain;
unsigned int tx_iq_phase;
unsigned int rx_iq_phase;
unsigned char tx_gain[FT_GAIN_LEN];
}FT_PARAM_ST;
static u8 default_mac[6] = {0x00,0x25,0x08,0x09,0x01,0x0F};
FT_PARAM_ST gftParam;
int tls_ft_param_init(void)
{
int i = 0;
int usedcnt[2] = {0, 0};
u32 crcvalue = 0;
psCrcContext_t ctx;
u8 *pmem = NULL;
FT_PARAM_ST *pft = NULL;
if (gftParam.magic_no == SIGNATURE_WORD)
{
return TRUE;
}
pmem = tls_mem_alloc(512);
if (pmem == NULL)
{
return FALSE;
}
pft = tls_mem_alloc(sizeof(FT_PARAM_ST));
if (pft == NULL)
{
return FALSE;
}
for (i = 0; i < 2; i++)
{
if (i == 0)
{
tls_fls_read(FT_MAGICNUM_ADDR, (unsigned char *)pft, sizeof(FT_PARAM_ST));
}else{
flashSRRW(0, (unsigned char *)pft, sizeof(FT_PARAM_ST), pmem, 256, 1);
}
if (pft->magic_no == SIGNATURE_WORD)
{
tls_crypto_init();
tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
tls_crypto_crc_update(&ctx, (unsigned char *)pft + 12, sizeof(FT_PARAM_ST) - 12);
tls_crypto_crc_final(&ctx, &crcvalue);
if ((pft->checksum != crcvalue))
{
usedcnt[i] = -1;
continue;
}
if (gftParam.magic_no != SIGNATURE_WORD)
{
memcpy(&gftParam, pft, sizeof(FT_PARAM_ST));
}
}else{
usedcnt[i] = -1;
}
}
if ((usedcnt[0] + usedcnt[1]) == -2)
{
/*Use default ft param*/
}
else if (usedcnt[0] < 0) /*flash param destroyed*/
{
tls_flash_unlock();
tls_fls_write(FT_MAGICNUM_ADDR, (unsigned char *)&gftParam, sizeof(gftParam));
tls_flash_lock();
}
else if (usedcnt[1] < 0) /*SR param destroyed*/
{
flashSRRW(0, (unsigned char *)&gftParam, sizeof(FT_PARAM_ST), pmem, 256, 0);
}
else
{
if (gftParam.checksum != pft->checksum)
{
flashSRRW(0, (unsigned char *)&gftParam, sizeof(FT_PARAM_ST), pmem, 256, 0);
}
}
tls_mem_free(pmem);
tls_mem_free(pft);
return TRUE;
}
int tls_ft_param_get(unsigned int opnum, void *data, unsigned int rdlen)
{
//FT_PARAM_ST ft;
//tls_fls_read(FT_MAGICNUM_ADDR, (unsigned char *)&ft, sizeof(ft));
switch (opnum)
{
case CMD_MAC: /*MAC*/
if ((gftParam.mac_addr[0]&0x1)
||(0 == (gftParam.mac_addr[0]|gftParam.mac_addr[1]|gftParam.mac_addr[2]|gftParam.mac_addr[3]|gftParam.mac_addr[4]|gftParam.mac_addr[5])))
{
memcpy(data, default_mac, rdlen);
}
else
{
memcpy(data, gftParam.mac_addr, rdlen);
}
break;
case CMD_TX_DC: /*tx_dcoffset*/
*(unsigned int *)data = gftParam.tx_dcoffset;
break;
case CMD_RX_DC: /*rx_dcoffset*/
*(unsigned int *)data = gftParam.rx_dcoffset;
break;
case CMD_TX_IQ_GAIN:
*(unsigned int *)data = gftParam.tx_iq_gain;
break;
case CMD_RX_IQ_GAIN:
*(unsigned int *)data = gftParam.rx_iq_gain;
break;
case CMD_TX_IQ_PHASE:
*(unsigned int *)data = gftParam.tx_iq_phase;
break;
case CMD_RX_IQ_PHASE:
*(unsigned int *)data = gftParam.rx_iq_phase;
break;
case CMD_TX_GAIN: /*gain*/
if (rdlen < FT_GAIN_LEN)
{
memcpy(data, gftParam.tx_gain, rdlen);
}
else
{
memcpy(data, gftParam.tx_gain, FT_GAIN_LEN);
}
break;
default:
return -1;
}
return 0;
}
int tls_ft_param_set(unsigned int opnum, void *data, unsigned int len)
{
psCrcContext_t ctx;
unsigned int writelen = 0;
u8 *pmem = NULL;
if (!data || !len)
{
return -1;
}
//tls_fls_read(FT_MAGICNUM_ADDR, (unsigned char *)&gftParam, sizeof(gftParam));
switch (opnum)
{
case CMD_MAC: /*MAC*/
memcpy(gftParam.mac_addr, (unsigned char *)data, len);
break;
case CMD_TX_DC: /*tx_dcoffset*/
gftParam.tx_dcoffset = *(unsigned int *)data;
break;
case CMD_RX_DC: /*rx_dcoffset*/
gftParam.rx_dcoffset = *(unsigned int *)data;
break;
case CMD_TX_IQ_GAIN:
gftParam.tx_iq_gain = *(unsigned int *)data;
break;
case CMD_RX_IQ_GAIN:
gftParam.rx_iq_gain = *(unsigned int *) data;
break;
case CMD_TX_IQ_PHASE:
gftParam.tx_iq_phase = *(unsigned int *)data;
break;
case CMD_RX_IQ_PHASE:
gftParam.rx_iq_phase = *(unsigned int *) data;
break;
case CMD_TX_GAIN: /*gain*/
if (len >= FT_GAIN_LEN)
{
writelen = FT_GAIN_LEN;
}
else
{
writelen = len;
}
memcpy(gftParam.tx_gain, data, writelen);
break;
default:
return -1;
}
tls_crypto_init();
tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
gftParam.magic_no = SIGNATURE_WORD;
tls_crypto_crc_update(&ctx, (unsigned char *)&gftParam + 12, sizeof(gftParam) -12);
tls_crypto_crc_final(&ctx, &gftParam.checksum);
tls_flash_unlock();
tls_fls_write(FT_MAGICNUM_ADDR, (unsigned char *)&gftParam, sizeof(gftParam));
tls_flash_lock();
pmem = tls_mem_alloc(512);
if (pmem)
{
flashSRRW(0, (unsigned char *)&gftParam, sizeof(gftParam), pmem, 512, 0);
tls_mem_free(pmem);
}
return 0;
}
/**********************************************************************************************************
* Description: This function is used to get mac addr.
*
* Arguments : mac mac addr,6 byte
*
* Returns : TLS_EFUSE_STATUS_OK get success
* TLS_EFUSE_STATUS_EIO get failed
**********************************************************************************************************/
int tls_get_mac_addr(u8 *mac)
{
return tls_ft_param_get(CMD_MAC, mac, 6);
}
/**********************************************************************************************************
* Description: This function is used to set mac addr.
*
* Arguments : mac mac addr,6 byte
*
* Returns : TLS_EFUSE_STATUS_OK get success
* TLS_EFUSE_STATUS_EIO get failed
**********************************************************************************************************/
int tls_set_mac_addr(u8 *mac)
{
return tls_ft_param_set(CMD_MAC, mac, 6);
}
/**********************************************************************************************************
* Description: This function is used to get tx lod.
*
* Arguments : *txlo
*
* Returns : 0 get success
* -1 get failed
**********************************************************************************************************/
int tls_get_tx_lo(u8 *txlo)
{
return tls_ft_param_get(CMD_TX_DC, txlo, 4);
}
/**********************************************************************************************************
* Description: This function is used to set tx lo.
*
* Arguments : txlo
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_tx_lo(u8 *txlo)
{
return tls_ft_param_set(CMD_TX_DC, txlo, 4);
}
/**********************************************************************************************************
* Description: This function is used to get tx iq gain.
*
* Arguments : txGain
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_get_tx_iq_gain(u8 *txGain)
{
return tls_ft_param_get(CMD_TX_IQ_GAIN, txGain, 4);
}
/**********************************************************************************************************
* Description: This function is used to set tx iq gain.
*
* Arguments : txGain
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_tx_iq_gain(u8 *txGain)
{
return tls_ft_param_set(CMD_TX_IQ_GAIN, txGain, 4);
}
/**********************************************************************************************************
* Description: This function is used to get rx iq gain.
*
* Arguments : rxGain
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_get_rx_iq_gain(u8 *rxGain)
{
return tls_ft_param_get(CMD_RX_IQ_GAIN, rxGain, 4);
}
/**********************************************************************************************************
* Description: This function is used to set rx iq gain.
*
* Arguments : rxGain
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_rx_iq_gain(u8 *rxGain)
{
return tls_ft_param_set(CMD_RX_IQ_GAIN, rxGain, 4);
}
/**********************************************************************************************************
* Description: This function is used to get tx iq phase.
*
* Arguments : txPhase
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_get_tx_iq_phase(u8 *txPhase)
{
return tls_ft_param_get(CMD_TX_IQ_PHASE, txPhase, 4);
}
/**********************************************************************************************************
* Description: This function is used to set tx iq phase.
*
* Arguments : txPhase
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_tx_iq_phase(u8 *txPhase)
{
return tls_ft_param_set(CMD_TX_IQ_PHASE, txPhase, 4);
}
/**********************************************************************************************************
* Description: This function is used to get rx iq phase.
*
* Arguments : rxPhase
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_get_rx_iq_phase(u8 *rxPhase)
{
return tls_ft_param_get(CMD_RX_IQ_PHASE, rxPhase, 4);
}
/**********************************************************************************************************
* Description: This function is used to set tx iq phase.
*
* Arguments : rxPhase
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_rx_iq_phase(u8 *rxPhase)
{
return tls_ft_param_set(CMD_RX_IQ_PHASE, rxPhase, 4);
}
int tls_freq_err_op(u8 *freqerr, u8 flag)
{
tls_flash_unlock();
if (flag){
tls_fls_write(FT_MAGICNUM_ADDR + sizeof(FT_PARAM_ST), freqerr, 4);
}
else
{
tls_fls_read(FT_MAGICNUM_ADDR + sizeof(FT_PARAM_ST), freqerr, 4);
}
tls_flash_lock();
return TLS_EFUSE_STATUS_OK;
}
int tls_rf_vcg_ctrl_op(u8 *vcg, u8 flag)
{
tls_flash_unlock();
if (flag){
tls_fls_write(VCG_ADDR, vcg, VCG_LEN);
}
else
{
tls_fls_read(VCG_ADDR, vcg, VCG_LEN);
}
tls_flash_lock();
return TLS_EFUSE_STATUS_OK;
}
/**********************************************************************************************************
* Description: This function is used to get tx gain.
*
* Arguments : txgain tx gain
*
* Returns : 0 get success
* -1 get failed
**********************************************************************************************************/
int tls_get_tx_gain(u8 *txgain)
{
return tls_ft_param_get(CMD_TX_GAIN, txgain, TX_GAIN_LEN);
}
/**********************************************************************************************************
* Description: This function is used to set tx gain.
*
* Arguments : txgain tx gain
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_tx_gain(u8 *txgain)
{
return tls_ft_param_set(CMD_TX_GAIN, txgain, TX_GAIN_LEN);
}
/**********************************************************************************************************
* Description: This function is used to get uuid
*
* Arguments : *uuid
*
* Returns : 0 get success
* -1 get failed
**********************************************************************************************************/
int tls_get_uuid(u8 *uuid, u8 len)
{
u8 *pmem = NULL;
if (uuid)
{
pmem = tls_mem_alloc(512);
if (pmem == NULL)
{
return TLS_EFUSE_STATUS_ERR;
}
flashSRRW(256, (unsigned char *)pmem, len, pmem, 512, 1);
memcpy(uuid, &pmem[0], len);
tls_mem_free(pmem);
pmem = NULL;
return TLS_EFUSE_STATUS_OK;
}
return TLS_EFUSE_STATUS_ERR;
}
/**********************************************************************************************************
* Description: This function is used to get uuid
*
* Arguments : *uuid :data to be written to otp area
* len : data len to be written
* iflock : if lock the otp area,1-lock, once lock,can not unlock!!!
*
* Returns : 0 get success
* -1 get failed
**********************************************************************************************************/
int tls_set_uuid(u8 *uuid, u8 len, u8 iflock)
{
u8 *pmem = NULL;
if (uuid)
{
pmem = tls_mem_alloc(512);
if (pmem == NULL)
{
return TLS_EFUSE_STATUS_ERR;
}
flashSRRW(256, (unsigned char *)uuid, len, pmem, 512, 0);
if (iflock)
{
writeSRLockBit(2);
}
tls_mem_free(pmem);
pmem = NULL;
return TLS_EFUSE_STATUS_OK;
}
return TLS_EFUSE_STATUS_ERR;
}
#define FF_n16 0xff, 0xff, 0xff, 0xff, \
0xff, 0xff, 0xff, 0xff, \
0xff, 0xff, 0xff, 0xff, \
0xff, 0xff, 0xff, 0xff
int tls_get_chipid(u8 chip_id[QFLASH_CHIP_ID_LEN])
{
int ret = 0;
static u8 _chip_id[QFLASH_CHIP_ID_LEN] = { FF_n16 };
u8 zero[QFLASH_CHIP_ID_LEN] = { FF_n16 };
if (!memcmp(_chip_id, zero, QFLASH_CHIP_ID_LEN))
{
ret = tls_fls_read(QFLASH_CHIP_ID_BASE_ADDR, _chip_id, QFLASH_CHIP_ID_LEN);
}
if (0 == ret)
{
memcpy(chip_id, _chip_id, QFLASH_CHIP_ID_LEN);
}
return ret;
}
#undef FF_n16
unsigned int tls_sleep(unsigned int seconds)
{
int ret = 0;
ret = tls_msleep(seconds * 1000);
return ret;
}
int tls_msleep(unsigned int msec)
{
int ret = 0;
ret = tls_delay_via_timer(msec, TIMER_MS_UNIT_FLAG);
return ret;
}
int tls_usleep(unsigned int /*useconds_t*/ usec)
{
int ret = 0;
ret = tls_delay_via_timer(usec, TIMER_US_UNIT_FLAG);
return ret;
}
+577
View File
@@ -0,0 +1,577 @@
/**
* @file wm_fls.c
*
* @brief flash Driver Module
*
* @author dave
*
* Copyright (c) 2015 Winner Microelectronics Co., Ltd.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "list.h"
#include "wm_hostspi.h"
#include "wm_flash.h"
#include "wm_dbg.h"
#include "wm_mem.h"
#include "wm_fls_gd25qxx.h"
static struct tls_fls *spi_fls = NULL;
int tls_spifls_read_id(u32 * id)
{
u32 cmd;
int err;
cmd = FLS_CMD_READ_DEV_ID;
*id = 0;
err = tls_spi_read_with_cmd((const u8 *) &cmd, 4, (u8 *) id, 3);
if (err != TLS_SPI_STATUS_OK)
{
TLS_DBGPRT_ERR("flash read ID fail(%d)!\n", err);
return TLS_FLS_STATUS_EIO;
}
TLS_DBGPRT_FLASH_INFO("flash ID - 0x%x.\n", *id);
return TLS_FLS_STATUS_OK;
}
/**
* @brief This function is used to read data from the flash.
*
* @param[in] addr is byte offset addr for read from the flash.
* @param[in] buf is user for data buffer of flash read
* @param[in] len is byte length for read.
*
* @retval TLS_FLS_STATUS_OK if read sucsess
* @retval TLS_FLS_STATUS_EIO if read fail
* @retval TLS_FLS_STATUS_EPERM if flash driver module not beed installed
* @retval TLS_FLS_STATUS_ENODRV if the current spi flash driver not installed
* @retval TLS_FLS_STATUS_EINVAL if parameter error
*
* @note None
*/
int tls_spifls_read(u32 addr, u8 * buf, u32 len)
{
int err;
u32 read_bytes;
struct tls_fls_drv *drv;
if (spi_fls == NULL)
{
TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
return TLS_FLS_STATUS_EPERM;
}
if (spi_fls->current_drv == NULL)
{
TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
return TLS_FLS_STATUS_ENODRV;
}
if ((addr >= spi_fls->current_drv->total_size) || (len == 0)
|| (buf == NULL))
{
return TLS_FLS_STATUS_EINVAL;
}
tls_os_sem_acquire(spi_fls->fls_lock, 0);
drv = spi_fls->current_drv;
read_bytes =
((addr + len) > drv->total_size) ? (drv->total_size - addr) : len;
err = TLS_FLS_STATUS_OK;
err = drv->read(addr, buf, read_bytes);
tls_os_sem_release(spi_fls->fls_lock);
return err;
}
int tls_spifls_fast_read(u32 addr, u8 * buf, u32 len)
{
int err;
u32 read_bytes;
struct tls_fls_drv *drv;
if (spi_fls == NULL)
{
TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
return TLS_FLS_STATUS_EPERM;
}
if (spi_fls->current_drv == NULL)
{
TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
return TLS_FLS_STATUS_ENODRV;
}
if ((addr >= spi_fls->current_drv->total_size) || (len == 0)
|| (buf == NULL))
{
return TLS_FLS_STATUS_EINVAL;
}
if ((spi_fls->current_drv->flags & TLS_FLS_FLAG_FAST_READ) !=
TLS_FLS_FLAG_FAST_READ)
{
return TLS_FLS_STATUS_ENOSUPPORT;
}
drv = spi_fls->current_drv;
read_bytes =
((addr + len) > drv->total_size) ? (drv->total_size - addr) : len;
err = TLS_FLS_STATUS_OK;
err = drv->fast_read(addr, buf, read_bytes);
return err;
}
int tls_spifls_page_write(u32 page, u8 * buf, u32 page_cnt)
{
int err;
u32 write_pages;
u32 i;
struct tls_fls_drv *drv;
if (spi_fls == NULL)
{
TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
return TLS_FLS_STATUS_EPERM;
}
if (spi_fls->current_drv == NULL)
{
TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
return TLS_FLS_STATUS_ENODRV;
}
if ((page >= (spi_fls->current_drv->total_size / spi_fls->current_drv->page_size))
|| (page_cnt == 0) || (buf == NULL))
{
return TLS_FLS_STATUS_EINVAL;
}
drv = spi_fls->current_drv;
write_pages = ((page + page_cnt) > (drv->total_size / drv->page_size)) ?
((drv->total_size / drv->page_size) -page) : page_cnt;
err = TLS_FLS_STATUS_OK;
for (i = 0; i < write_pages; i++)
{
err = drv->page_write(page + i, buf + i * drv->page_size);
if (err != TLS_FLS_STATUS_OK)
{
TLS_DBGPRT_ERR("flash page write fail(page %d)!\n", (page + i));
break;
}
}
return err;
}
/**
* @brief This function is used to write data to the flash.
*
* @param[in] addr is byte offset addr for write to the flash
* @param[in] buf is the data buffer want to write to flash
* @param[in] len is the byte length want 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
* @retval TLS_FLS_STATUS_ENOMEM if memory allocation fail
*
* @note None
*/
int tls_spifls_write(u32 addr, u8 * buf, u32 len)
{
u8 *cache;
int err;
u32 sector_addr;
u32 sector_off;
u32 sector_remain;
u32 cntforFF;
u32 write_bytes;
u32 write_page = 0;
u32 i;
struct tls_fls_drv *drv;
if (spi_fls == NULL)
{
TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
return TLS_FLS_STATUS_EPERM;
}
if (spi_fls->current_drv == NULL)
{
TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
return TLS_FLS_STATUS_ENODRV;
}
if ((addr >= spi_fls->current_drv->total_size) || (len == 0)
|| (buf == NULL))
{
return TLS_FLS_STATUS_EINVAL;
}
tls_os_sem_acquire(spi_fls->fls_lock, 0);
drv = spi_fls->current_drv;
err = TLS_FLS_STATUS_OK;
cache = tls_mem_alloc(drv->sector_size);
if (cache == NULL)
{
tls_os_sem_release(spi_fls->fls_lock);
TLS_DBGPRT_ERR("allocate sector cache memory(%dB) fail!\n",
drv->sector_size);
return TLS_FLS_STATUS_ENOMEM;
}
sector_addr = addr / drv->sector_size; //Section addr
sector_off = (addr % drv->sector_size); //Offset in section
sector_remain = drv->sector_size - sector_off;
write_bytes = len;
TLS_DBGPRT_FLASH_INFO("write to flash: sector address - %d, sector off - %x.\n", sector_addr,
sector_off);
if(write_bytes <= sector_remain)
{
sector_remain = write_bytes; //Not bigger with remain size in section
}
while (1)
{
TLS_DBGPRT_FLASH_INFO("firstly, read the sector - %d to cache.\n", sector_addr);
err = drv->read(sector_addr * drv->sector_size, cache, drv->sector_size);
if (err != TLS_FLS_STATUS_OK)
{
TLS_DBGPRT_ERR("flash read fail(sector %d)!\n", sector_addr);
break;
}
cntforFF = 0;
for(i = 0; i < sector_remain; i++)
{
if(cache[i + sector_off] == 0xFF)
{
cntforFF++;
}
cache[i + sector_off] = buf[i];
}
//If the flash address to be written is all 0xFF, then erase sector is not necessary;
if( cntforFF != sector_remain)
{
TLS_DBGPRT_FLASH_INFO("second, erase the sector - %d.\n", sector_addr);
err = drv->erase(sector_addr);
if (err != TLS_FLS_STATUS_OK)
{
TLS_DBGPRT_ERR("flash erase fail(sector %d)!\n", sector_addr);
break;
}
}
if( (cntforFF != sector_remain ) || ((sector_off == 0) && (sector_remain == drv->sector_size)))
{
for(i = 0; i < (drv->sector_size / drv->page_size); i++)
{
err = drv->page_write(sector_addr * drv->sector_size / drv->page_size + i, &cache[i * drv->page_size]);
if (err != TLS_FLS_STATUS_OK)
{
TLS_DBGPRT_ERR("flash page write fail(page %d)!\n", i);
tls_mem_free(cache);
tls_os_sem_release(spi_fls->fls_lock);
return err;
}
}
}
else
{
write_page = (sector_off / drv->page_size) == 15 ? 16 : (sector_off + sector_remain) / drv->page_size + 1;
//As long as this sector is not erased in this round, we only program the changed pages instead of all of them.
for(i = (sector_off / drv->page_size); i < write_page; i++)
{
err = drv->page_write(sector_addr * drv->sector_size / drv->page_size + i, &cache[i * drv->page_size]);
if (err != TLS_FLS_STATUS_OK)
{
TLS_DBGPRT_ERR("flash page write fail(page %d)!\n", i);
tls_mem_free(cache);
tls_os_sem_release(spi_fls->fls_lock);
return err;
}
}
}
if(write_bytes == sector_remain)
{
break;
}
else
{
sector_addr++;
sector_off = 0;
buf += sector_remain;
write_bytes -= sector_remain;
if(write_bytes > (drv->sector_size))
sector_remain = drv->sector_size;
else
sector_remain = write_bytes; //Next section will finish
}
}
tls_mem_free(cache);
tls_os_sem_release(spi_fls->fls_lock);
return err;
}
int tls_spifls_erase(u32 sector)
{
int err;
struct tls_fls_drv *drv;
if (spi_fls == NULL)
{
TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
return TLS_FLS_STATUS_EPERM;
}
if (spi_fls->current_drv == NULL)
{
TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
return TLS_FLS_STATUS_ENODRV;
}
if (sector >= (spi_fls->current_drv->total_size / spi_fls->current_drv->sector_size))
{
TLS_DBGPRT_ERR("the sector to be erase overflow!\n");
return TLS_FLS_STATUS_EINVAL;
}
tls_os_sem_acquire(spi_fls->fls_lock, 0);
drv = spi_fls->current_drv;
err = TLS_FLS_STATUS_OK;
err = drv->erase(sector);
tls_os_sem_release(spi_fls->fls_lock);
return err;
}
int tls_spifls_chip_erase(void)
{
int err;
struct tls_fls_drv *drv;
if (spi_fls == NULL)
{
TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
return TLS_FLS_STATUS_EPERM;
}
if (spi_fls->current_drv == NULL)
{
TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
return TLS_FLS_STATUS_ENODRV;
}
drv = spi_fls->current_drv;
err = TLS_FLS_STATUS_OK;
err = drv->chip_erase();
return err;
}
int tls_spifls_get_param(u8 type, void *param)
{
int err;
struct tls_fls_drv *drv;
if (spi_fls == NULL)
{
TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
return TLS_FLS_STATUS_EPERM;
}
if (spi_fls->current_drv == NULL)
{
TLS_DBGPRT_ERR("the current spi flash driver not installed!\n");
return TLS_FLS_STATUS_ENODRV;
}
if (param == NULL)
{
return TLS_FLS_STATUS_EINVAL;
}
tls_os_sem_acquire(spi_fls->fls_lock, 0);
drv = spi_fls->current_drv;
err = TLS_FLS_STATUS_OK;
switch (type)
{
case TLS_FLS_PARAM_TYPE_ID:
*((u32 *) param) = drv->id;
break;
case TLS_FLS_PARAM_TYPE_SIZE:
*((u32 *) param) = drv->total_size;
break;
case TLS_FLS_PARAM_TYPE_PAGE_SIZE:
*((u32 *) param) = drv->page_size;
break;
case TLS_FLS_PARAM_TYPE_PROG_SIZE:
*((u32 *) param) = drv->program_size;
break;
case TLS_FLS_PARAM_TYPE_SECTOR_SIZE:
*((u32 *) param) = drv->sector_size;
break;
default:
TLS_DBGPRT_WARNING("invalid parameter ID!\n");
err = TLS_FLS_STATUS_EINVAL;
break;
}
tls_os_sem_release(spi_fls->fls_lock);
return err;
}
int tls_spifls_drv_register(struct tls_fls_drv *fls_drv)
{
u32 cpu_sr;
struct tls_fls_drv *drv;
if (fls_drv == NULL)
{
TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
return TLS_FLS_STATUS_EINVAL;
}
dl_list_for_each(drv, &spi_fls->fls_drvs, struct tls_fls_drv, drv_list)
{
if (drv->id == fls_drv->id)
{
TLS_DBGPRT_WARNING
("corresponding spi flash driver has registered!\n");
return TLS_FLS_STATUS_EEXIST;
}
}
cpu_sr = tls_os_set_critical();
dl_list_add_tail((struct dl_list *) &spi_fls->fls_drvs,
(struct dl_list *) &fls_drv->drv_list);
tls_os_release_critical(cpu_sr);
TLS_DBGPRT_FLASH_INFO("the spi flash driver is registered successfully!\n");
return TLS_FLS_STATUS_OK;
}
int tls_spifls_drv_unregister(struct tls_fls_drv *fls_drv)
{
TLS_DBGPRT_WARNING
("unregister spi flash driver operation is not supported!\n");
return TLS_FLS_STATUS_EPERM;
}
int tls_spifls_probe(void)
{
int err;
u32 id;
struct tls_fls_drv *drv;
if (spi_fls == NULL)
{
TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
return TLS_FLS_STATUS_EPERM;
}
if (spi_fls->current_drv != NULL)
{
TLS_DBGPRT_ERR("the current spi flash has fount the matched driver!\n");
return TLS_FLS_STATUS_EBUSY;
}
TLS_DBGPRT_FLASH_INFO("try to read the current spi flash ID.\n");
err = tls_spifls_read_id(&id);
if (err != TLS_FLS_STATUS_OK)
{
return err;
}
TLS_DBGPRT_FLASH_INFO("current spi flash ID - 0x%x.\n", id);
dl_list_for_each(drv, &spi_fls->fls_drvs, struct tls_fls_drv, drv_list)
{
err = drv->probe(id);
if (err != TLS_FLS_STATUS_OK)
{
return err;
}
tls_spi_setup(drv->mode, drv->cs_active, drv->clock);
TLS_DBGPRT_FLASH_INFO("matched the spi flash driver.\n");
spi_fls->current_drv = drv;
break;
}
if (spi_fls->current_drv == NULL)
{
TLS_DBGPRT_WARNING("not found the matched spi flash driver!\n");
return TLS_FLS_STATUS_ENODRV;
}
return TLS_FLS_STATUS_OK;
}
int tls_spifls_init(void)
{
struct tls_fls *fls;
int err;
if (spi_fls != NULL)
{
TLS_DBGPRT_ERR("flash driver module has been installed!\n");
return TLS_FLS_STATUS_EBUSY;
}
fls = (struct tls_fls *) tls_mem_alloc(sizeof(struct tls_fls));
if (fls == NULL)
{
TLS_DBGPRT_ERR("allocate @spi_fls fail!\n");
return TLS_FLS_STATUS_ENOMEM;
}
memset(fls, 0, sizeof(*fls));
dl_list_init((struct dl_list *) &fls->fls_drvs);
err = tls_os_sem_create(&fls->fls_lock, 1);
if (err != TLS_OS_SUCCESS)
{
tls_mem_free(fls);
TLS_DBGPRT_ERR("create semaphore @fls_lock fail!\n");
return TLS_FLS_STATUS_ENOMEM;
}
spi_fls = fls;
tls_spifls_drv_install();
return TLS_FLS_STATUS_OK;
}
int tls_spifls_exit(void)
{
TLS_DBGPRT_FLASH_INFO("Not support flash driver module uninstalled!\n");
return TLS_FLS_STATUS_EPERM;
}
+307
View File
@@ -0,0 +1,307 @@
/**
* @file wm_fls_gd25qxx.c
*
* @brief gd25qxx flash Driver Module
*
* @author dave
*
* Copyright (c) 2015 Winner Microelectronics Co., Ltd.
*/
#include <stdio.h>
#include <stdlib.h>
#include "wm_type_def.h"
#include "wm_flash.h"
#include "wm_hostspi.h"
#include "wm_fls_gd25qxx.h"
#include "wm_debug.h"
#include "wm_gpio.h"
static int tls_spifls_drv_read(u32 addr, u8 * buf, u32 len);
static int tls_spifls_drv_fast_read(u32 addr, u8 * buf, u32 len);
static int tls_spifls_drv_page_write(u32 page, u8 * buf);
static int tls_spifls_drv_erase(u32 sector);
static int tls_spifls_drv_chip_erase(void);
static int tls_spifls_drv_probe(u32 id);
static void tls_spifls_drv_remove(void);
static struct tls_fls_drv exspi_fls = {
.drv_list = {NULL, NULL},
.clock = SPI_SCLK,
.mode = TLS_SPI_MODE_0,
.cs_active = TLS_SPI_CS_LOW,
.flags = 0,
.read = tls_spifls_drv_read,
.fast_read = tls_spifls_drv_fast_read,
.page_write = tls_spifls_drv_page_write,
.erase = tls_spifls_drv_erase,
.chip_erase = tls_spifls_drv_chip_erase,
.probe = tls_spifls_drv_probe,
.remove = tls_spifls_drv_remove
};
static struct tls_fls_drv *exspifls_drv = NULL;
static unsigned int swap32(unsigned int v)
{
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
((v & 0xff0000) >> 8) | (v >> 24);
}
static int tls_spifls_drv_write_enable(void)
{
u8 cmd;
int err;
cmd = EXSPIFLASH_WRITE_ENABLE;
err = tls_spi_write((const u8 *) &cmd, 1);
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
return TLS_FLS_STATUS_OK;
}
static int tls_spifls_drv_wait_write_enable(void)
{
u8 cmd;
u8 sr;
int err;
cmd = EXSPIFLASH_READ_SR1;
sr = 0;
do
{
err = tls_spi_read_with_cmd((const u8 *) &cmd, 1, &sr, 1);
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
if (sr & FLASH_STATUS_WEL)
{
break;
}
}
while (1);
return TLS_FLS_STATUS_OK;
}
static int tls_spifls_drv_wait_flash_ready(void)
{
u8 cmd;
u8 sr;
int err;
cmd = EXSPIFLASH_READ_SR1;
sr = 0;
do
{
err = tls_spi_read_with_cmd((const u8 *) &cmd, 1, &sr, 1);
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
if ((sr & FLASH_STATUS_BUSY) == 0x00)
{
break;
}
}
while (1);
return TLS_FLS_STATUS_OK;
}
static int tls_spifls_drv_read(u32 addr, u8 * buf, u32 len)
{
u32 cmd;
int err;
cmd = 0;
cmd |= EXSPIFLASH_DATA_READ;
cmd |= swap32(addr) & 0xffffff00;
err = tls_spi_read_with_cmd((const u8 *) &cmd, 4, buf, len);
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
return TLS_FLS_STATUS_OK;
}
static int tls_spifls_drv_fast_read(u32 addr, u8 * buf, u32 len)
{
return TLS_FLS_STATUS_ENOSUPPORT;
}
static int tls_spifls_drv_page_write(u32 page, u8 * buf)
{
u32 cmd;
int err;
err = tls_spifls_drv_write_enable();
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
err = tls_spifls_drv_wait_write_enable();
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
cmd = 0;
cmd |= EXSPIFLASH_PAGE_PROGRAM;
cmd |= swap32(page * exspifls_drv->page_size) & 0xffffff00;
err = tls_spi_write_with_cmd((const u8 *) &cmd, 4, (const u8 *) buf,
exspifls_drv->page_size);
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
err = tls_spifls_drv_wait_flash_ready();
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
return TLS_FLS_STATUS_OK;
}
static int tls_spifls_drv_erase(u32 sector)
{
u32 cmd;
int err;
err = tls_spifls_drv_write_enable();
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
err = tls_spifls_drv_wait_write_enable();
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
cmd = 0;
cmd |= EXSPIFLASH_SECTOR_ERASE;
cmd |= swap32(sector * exspifls_drv->sector_size) & 0xffffff00;
err = tls_spi_write((const u8 *) &cmd, 4);
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
tls_os_time_delay(6);
err = tls_spifls_drv_wait_flash_ready();
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
return TLS_FLS_STATUS_OK;
}
static int tls_spifls_drv_chip_erase(void)
{
u8 cmd;
int err;
err = tls_spifls_drv_write_enable();
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
err = tls_spifls_drv_wait_write_enable();
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
cmd = EXSPIFLASH_CHIP_ERASE;
err = tls_spi_write((const u8 *) &cmd, 1);
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
err = tls_spifls_drv_wait_flash_ready();
if (err != TLS_SPI_STATUS_OK)
{
return TLS_FLS_STATUS_EIO;
}
return TLS_FLS_STATUS_OK;
}
static int tls_spifls_drv_probe(u32 id)
{
// int i = 0;
if (!id)
{
return TLS_FLS_STATUS_EINVAL;
}
exspi_fls.id = id;
if ((id>>16)&0xFF)
{
exspi_fls.total_size = 1 << (id>>16);
}else{
exspi_fls.total_size = FLASH_TOTAL_SIZE; /*1MByte*/
}
exspi_fls.page_size = PAGE_SIZE;
exspi_fls.program_size = PROGRAM_SIZE;
exspi_fls.sector_size = SECTOR_SIZE;
exspifls_drv = &exspi_fls;
return TLS_FLS_STATUS_OK;
}
static void tls_spifls_drv_remove(void)
{
exspifls_drv = NULL;
}
/**
* @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)
{
int err;
extern int tls_spifls_probe(void);
extern int tls_spifls_drv_register(struct tls_fls_drv *fls_drv);␍
err = tls_spifls_drv_register((struct tls_fls_drv *) &exspi_fls);
if (err == TLS_FLS_STATUS_EEXIST)
{
return err;
}
TLS_DBGPRT_INFO("register the spi flash driver - %d.\n", err);
err = tls_spifls_probe();
TLS_DBGPRT_INFO("probe spi flash - %d.\n", err);
return err;
}
+411
View File
@@ -0,0 +1,411 @@
/**
* @file wm_gpio.c
*
* @brief GPIO Driver Module
*
* @author dave
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
*/
#include "wm_gpio.h"
#include "wm_regs.h"
#include "wm_irq.h"
#include "wm_osal.h"
#include "tls_common.h"
struct gpio_irq_context{
tls_gpio_irq_callback callback;
void *arg;
};
static struct gpio_irq_context gpio_context[WM_IO_PB_30 - WM_IO_PA_00 + 1] = {{0,0}};
void GPIOA_IRQHandler(void)
{
u8 i = 0;
u8 found = 0;
u32 reg = 0;
reg = tls_reg_read32(HR_GPIO_MIS);
for (i = 0; i <= WM_IO_PA_15; i++)
{
if (reg & BIT(i))
{
found = 1;
break;
}
}
if (found)
{
if (NULL != gpio_context[i].callback)
gpio_context[i].callback(gpio_context[i].arg);
}
return;
}
void GPIOB_IRQHandler(void)
{
u8 i = 0;
u8 found = 0;
u32 reg = 0;
reg = tls_reg_read32(HR_GPIO_MIS + TLS_IO_AB_OFFSET);
for (i = WM_IO_PB_00; i <= WM_IO_PB_31; i++)
{
if (reg & BIT(i - WM_IO_PB_00))
{
found = 1;
break;
}
}
if (found)
{
if (NULL != gpio_context[i].callback)
gpio_context[i].callback(gpio_context[i].arg);
}
return;
}
/**
* @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
* All gpio's attribute can only be set as WM_GPIO_ATTR_FLOATING or WM_GPIO_ATTR_PULLHIGH on W600/W60X.
*/
void tls_gpio_cfg(enum tls_io_name gpio_pin, enum tls_gpio_dir dir, enum tls_gpio_attr attr)
{
u8 pin;
u16 offset;
if (gpio_pin >= WM_IO_PB_00)
{
pin = gpio_pin - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = gpio_pin;
offset = 0;
}
/* enable gpio function */
tls_io_cfg_set(gpio_pin, WM_IO_OPT5_GPIO);
/* gpio direction */
if (WM_GPIO_DIR_OUTPUT == dir)
{
tls_reg_write32(HR_GPIO_DIR + offset, tls_reg_read32(HR_GPIO_DIR + offset) | BIT(pin)); /* 1 set output */
}
else if (WM_GPIO_DIR_INPUT == dir)
{
tls_reg_write32(HR_GPIO_DIR + offset, tls_reg_read32(HR_GPIO_DIR + offset) & (~BIT(pin))); /* 0 set input */
}
/* gpio pull attribute */
if (WM_GPIO_ATTR_FLOATING == attr)
{
tls_reg_write32(HR_GPIO_PULL_EN + offset, tls_reg_read32(HR_GPIO_PULL_EN + offset) | BIT(pin)); /* 1 disable pull */
}
else if (WM_GPIO_ATTR_PULLHIGH == attr)
{
tls_reg_write32(HR_GPIO_PULL_EN + offset, tls_reg_read32(HR_GPIO_PULL_EN + offset) & (~BIT(pin))); /* 0 enable pull */
}
}
/**
* @brief This function is used to read gpio status
*
* @param[in] gpio_pin gpio pin num
*
* @retval 0 low level
* @retval 1 high level
*
* @note None
*/
u8 tls_gpio_read(enum tls_io_name gpio_pin)
{
u32 reg_en;
u32 reg;
u8 pin;
u16 offset;
if (gpio_pin >= WM_IO_PB_00)
{
pin = gpio_pin - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = gpio_pin;
offset = 0;
}
reg_en = tls_reg_read32(HR_GPIO_DATA_EN + offset);
tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en | (1 << pin));
reg = tls_reg_read32(HR_GPIO_DATA + offset);
tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en);
if(reg & (0x1 << pin))
return 1;
else
return 0;
}
/**
* @brief This function is used to modify gpio status
*
* @param[in] gpio_pin gpio pin num
* @param[in] value power level
* 0: low level
* 1: high level
*
* @return None
*
* @note None
*/
void tls_gpio_write(enum tls_io_name gpio_pin, u8 value)
{
u32 cpu_sr = 0;
u32 reg;
u32 reg_en;
u8 pin;
u16 offset;
if (gpio_pin >= WM_IO_PB_00)
{
pin = gpio_pin - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = gpio_pin;
offset = 0;
}
cpu_sr = tls_os_set_critical();
reg_en = tls_reg_read32(HR_GPIO_DATA_EN + offset);
tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en | (1 << pin));
reg = tls_reg_read32(HR_GPIO_DATA + offset);
if(value)
tls_reg_write32(HR_GPIO_DATA + offset, reg | (1 << pin)); /* write high */
else
tls_reg_write32(HR_GPIO_DATA + offset, reg & (~(1 << pin)));/* write low */
tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en);
tls_os_release_critical(cpu_sr);
}
/**
* @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)
{
u32 reg;
u8 pin;
u16 offset;
u8 vec_no;
if (gpio_pin >= WM_IO_PB_00)
{
pin = gpio_pin - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
vec_no = GPIOB_INT;
}
else
{
pin = gpio_pin;
offset = 0;
vec_no = GPIO_INT;
}
switch(mode)
{
case WM_GPIO_IRQ_TRIG_RISING_EDGE:
reg = tls_reg_read32(HR_GPIO_IS + offset);
reg &= (~(0x1 << pin));
tls_reg_write32(HR_GPIO_IS + offset, reg); /* 0 edge trigger */
reg = tls_reg_read32(HR_GPIO_IBE + offset);
reg &= (~(0x1 << pin));
tls_reg_write32(HR_GPIO_IBE + offset, reg); /* 0 edge trigger */
reg = tls_reg_read32(HR_GPIO_IEV + offset);
reg |= (0x1 << pin);
tls_reg_write32(HR_GPIO_IEV + offset, reg); /* 1 rising edge trigger */
break;
case WM_GPIO_IRQ_TRIG_FALLING_EDGE:
reg = tls_reg_read32(HR_GPIO_IS + offset);
reg &= (~(0x1 << pin));
tls_reg_write32(HR_GPIO_IS + offset, reg); /* 0 edge trigger */
reg = tls_reg_read32(HR_GPIO_IBE + offset);
reg &= (~(0x1 << pin));
tls_reg_write32(HR_GPIO_IBE + offset, reg); /* 0 edge trigger */
reg = tls_reg_read32(HR_GPIO_IEV + offset);
reg &= (~(0x1 << pin));
tls_reg_write32(HR_GPIO_IEV + offset, reg); /* 0 falling edge trigger */
break;
case WM_GPIO_IRQ_TRIG_DOUBLE_EDGE:
reg = tls_reg_read32(HR_GPIO_IS + offset);
tls_reg_write32(HR_GPIO_IS + offset, reg & (~(0x1 << pin))); /* 0 edge trigger */
reg = tls_reg_read32(HR_GPIO_IBE + offset);
tls_reg_write32(HR_GPIO_IBE + offset, reg | (0x1 << pin)); /* 1 double edge trigger */
break;
case WM_GPIO_IRQ_TRIG_HIGH_LEVEL:
reg = tls_reg_read32(HR_GPIO_IS + offset);
tls_reg_write32(HR_GPIO_IS + offset, reg | (0x1 << pin)); /* 1 level trigger */
reg = tls_reg_read32(HR_GPIO_IEV + offset);
tls_reg_write32(HR_GPIO_IEV + offset, reg | (0x1 << pin)); /* 1 high level trigger */
break;
case WM_GPIO_IRQ_TRIG_LOW_LEVEL:
reg = tls_reg_read32(HR_GPIO_IS + offset);
tls_reg_write32(HR_GPIO_IS + offset, reg | (0x1 << pin)); /* 1 level trigger */
reg = tls_reg_read32(HR_GPIO_IEV + offset);
tls_reg_write32(HR_GPIO_IEV + offset, reg & (~(0x1 << pin))); /* 0 low level trigger */
break;
}
reg = tls_reg_read32(HR_GPIO_IE + offset);
reg |= (0x1 << pin);
tls_reg_write32(HR_GPIO_IE + offset, reg); /* enable interrupt */
tls_irq_enable(vec_no);
}
/**
* @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)
{
u32 reg;
u8 pin;
u16 offset;
if (gpio_pin >= WM_IO_PB_00)
{
pin = gpio_pin - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = gpio_pin;
offset = 0;
}
reg = tls_reg_read32(HR_GPIO_IE + offset);
tls_reg_write32(HR_GPIO_IE + offset, reg & (~(0x1 << pin))); /* disable interrupt */
tls_irq_disable(GPIO_INT);
}
/**
* @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)
{
u32 reg;
u8 pin;
u16 offset;
if (gpio_pin >= WM_IO_PB_00)
{
pin = gpio_pin - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = gpio_pin;
offset = 0;
}
reg = tls_reg_read32(HR_GPIO_RIS + offset);
if(reg & (0x1 << pin))
return 1;
else
return 0;
}
/**
* @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)
{
u32 reg;
u8 pin;
u16 offset;
if (gpio_pin >= WM_IO_PB_00)
{
pin = gpio_pin - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = gpio_pin;
offset = 0;
}
reg = tls_reg_read32(HR_GPIO_IC + offset);
tls_reg_write32(HR_GPIO_IC + offset, reg | (0x1 << pin)); /* 1 clear interrupt status */
}
/**
* @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)
{
gpio_context[gpio_pin].callback = callback;
gpio_context[gpio_pin].arg = arg;
}
File diff suppressed because it is too large Load Diff
+493
View File
@@ -0,0 +1,493 @@
/**
* @file wm_hspi.c
*
* @brief High speed spi slave Module
*
* @author dave
*
* Copyright (c) 2015 Winner Microelectronics Co., Ltd.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wm_hspi.h"
#include "wm_regs.h"
#include "wm_config.h"
#include "wm_mem.h"
#include "wm_osal.h"
#include "wm_irq.h"
#include "lwip/mem.h"
#include "wm_io.h"
#if TLS_CONFIG_HS_SPI
struct tls_slave_hspi g_slave_hspi;
#define SET_BIT(x) (1UL << (x))
void hspi_free_rxdesc(struct tls_hspi_rx_desc *rx_desc);
void hspi_rx_init(struct tls_slave_hspi *hspi)
{
struct tls_hspi_rx_desc *hspi_rx_desc;
int i;
/* set current availble rx desc pointer */
hspi_rx_desc = (struct tls_hspi_rx_desc *) HSPI_RX_DESC_BASE_ADDR;
hspi->curr_rx_desc = hspi_rx_desc;
/* initialize rx descriptor content */
for (i = 0; i < HSPI_RX_DESC_NUM; i++)
{
/* initialize tx descriptors */
if (i < HSPI_RXBUF_NUM)
{
hspi_rx_desc->valid_ctrl = SET_BIT(31);
hspi_rx_desc->buf_addr = HSPI_RXBUF_BASE_ADDR + i * HSPI_RXBUF_SIZE;
}
else
{
/* indicate this descriptor is can't use by hspi */
hspi_rx_desc->valid_ctrl = 0;
/* point to null */
hspi_rx_desc->buf_addr = 0x0;
}
if (i == (HSPI_RX_DESC_NUM - 1))
{
hspi_rx_desc->next_desc_addr = (u32) HSPI_RX_DESC_BASE_ADDR;
}
else
{
hspi_rx_desc->next_desc_addr = (u32) (hspi_rx_desc + 1);
}
hspi_rx_desc++;
}
}
void hspi_tx_init(struct tls_slave_hspi *hspi)
{
struct tls_hspi_tx_desc *hspi_tx_desc;
int i;
hspi_tx_desc = (struct tls_hspi_tx_desc *) HSPI_TX_DESC_BASE_ADDR;
hspi->curr_tx_desc = hspi_tx_desc;
for (i = 0; i < HSPI_TX_DESC_NUM; i++)
{
hspi_tx_desc->valid_ctrl = 0;
hspi_tx_desc->buf_info = 0;
#if HSPI_TX_MEM_MALLOC
hspi_tx_desc->txbuf_addr = NULL;
hspi_tx_desc->buf_addr[0] = 0;
#else
hspi_tx_desc->buf_addr[0] = HSPI_TXBUF_BASE_ADDR + i * HSPI_TXBUF_SIZE;
#endif
hspi_tx_desc->buf_addr[1] = 0;
hspi_tx_desc->buf_addr[2] = 0;
if (i == (HSPI_TX_DESC_NUM - 1))
{
hspi_tx_desc->next_desc_addr = (u32) HSPI_TX_DESC_BASE_ADDR;
}
else
{
hspi_tx_desc->next_desc_addr = (u32) (hspi_tx_desc + 1);
}
hspi_tx_desc++;
}
}
static int slave_spi_rx_data(struct tls_slave_hspi *hspi)
{
struct tls_hspi_rx_desc *rx_desc;
/* get rx descriptor */
rx_desc = hspi->curr_rx_desc;
while (!(rx_desc->valid_ctrl & SET_BIT(31)))
{
if (hspi->rx_data_callback)
hspi->rx_data_callback((char *) rx_desc->buf_addr);
hspi_free_rxdesc(rx_desc);
rx_desc = (struct tls_hspi_rx_desc *) rx_desc->next_desc_addr;
hspi->curr_rx_desc = rx_desc;
}
return 0;
}
void SDIO_RX_IRQHandler(void)
{
struct tls_slave_hspi *hspi = (struct tls_slave_hspi *) &g_slave_hspi;
#if HSPI_TX_MEM_MALLOC
hspi->txdoneflag = 1;
#endif
if (hspi->tx_data_callback)
hspi->tx_data_callback((char *) hspi->curr_tx_desc->buf_addr);
/* clear interrupt */
tls_reg_write32(HR_SDIO_INT_SRC, SDIO_WP_INT_SRC_DATA_UP);
}
void SDIO_TX_IRQHandler(void)
{
struct tls_slave_hspi *hspi = (struct tls_slave_hspi *) &g_slave_hspi;
//用户模式下,直接给出数据,链表的操作不对外开放,避免造成链表操作错误
if (hspi->ifusermode)
{
slave_spi_rx_data(hspi);
}
else
{
if (hspi->rx_data_callback)
hspi->rx_data_callback((char *) hspi->curr_rx_desc->buf_addr);
}
/* clear interrupt */
tls_reg_write32(HR_SDIO_INT_SRC, SDIO_WP_INT_SRC_DATA_DOWN);
}
void SDIO_TX_CMD_IRQHandler(void)
{
struct tls_slave_hspi *hspi = (struct tls_slave_hspi *) &g_slave_hspi;
if (hspi->rx_cmd_callback)
hspi->rx_cmd_callback((char *) SDIO_CMD_RXBUF_ADDR);
if (hspi->ifusermode) // 用户模式下,数据给出去之后,寄存器由驱动自己操作
{
tls_reg_write32(HR_SDIO_DOWNCMDVALID, 0x1);
}
/* clear interrupt */
tls_reg_write32(HR_SDIO_INT_SRC, SDIO_WP_INT_SRC_CMD_DOWN);
}
void SPI_HS_IRQHandler(void)
{
printf("spi HS irqhandle\n");
}
void hspi_free_rxdesc(struct tls_hspi_rx_desc *rx_desc)
{
rx_desc->valid_ctrl = SET_BIT(31);
/* 设置hspi/sdio tx enable寄存器,让sdio硬件知道有可用的tx descriptor */
tls_reg_write32(HR_SDIO_TXEN, SET_BIT(0));
}
void hspi_regs_cfg(void)
{
tls_reg_write32(HR_HSPI_CLEAR_FIFO, 0x1); /* Clear data up&down interrput
*/
tls_reg_write32(HR_HSPI_SPI_CFG, 0); /* CPOL=0, CPHA=0, Small-Endian */
tls_reg_write32(HR_HSPI_MODE_CFG, 0x0);
tls_reg_write32(HR_HSPI_INT_MASK, 0x03);
tls_reg_write32(HR_HSPI_INT_STTS, 0x03);
}
void sdio_init_cis(void)
{
tls_reg_write32(FN0_TPL_FUNCID, 0x000C0221);
tls_reg_write32(FN0_TPL_FUNCE, 0x00000422);
tls_reg_write32(FN0_TPL_FUNCE_MAXBLK, 0x04203208);
tls_reg_write32(FN0_TPL_MANFID_MID, 0x53470296);
tls_reg_write32(FN0_TPL_END, 0x000000ff);
tls_reg_write32(FN1_TPL_FUNCID, 0x000C0221);
tls_reg_write32(FN1_TPL_FUNCE, 0x01012a22);
tls_reg_write32(FN1_TPL_FUNCE_VER, 0x00000011);
tls_reg_write32(FN1_TPL_FUNCE_NSN, 0x02000000);
tls_reg_write32(FN1_TPL_FUNCE_CSASIZE, 0x08000300);
tls_reg_write32(FN1_TPL_FUNCE_OCR, 0x00FF8000);
tls_reg_write32(FN1_TPL_FUNCE_MINPWR, 0x010f0a08);
tls_reg_write32(FN1_TPL_FUNCE_STANDBY, 0x00000101);
tls_reg_write32(FN1_TPL_FUNCE_OPTBW, 0x00000000);
tls_reg_write32(FN1_TPL_FUNCE_NTIMEOUT, 0x00000000);
tls_reg_write32(FN1_TPL_FUNCE_AVGPWR, 0x00000000);
tls_reg_write32(FN1_TPL_FUNCE_AVGPWR + 4, 0x00000000);
tls_reg_write32(FN1_TPL_END, 0x000000ff);
}
void hsdio_regs_cfg(void)
{
u32 v;
sdio_init_cis();
tls_reg_write32(HR_SDIO_CIS0, SDIO_CIS0_ADDR - 0x1000);
tls_reg_write32(HR_SDIO_CIS1, SDIO_CIS1_ADDR - 0x2000);
v = tls_reg_read32(HR_SDIO_CIA);
tls_reg_write32(HR_SDIO_CIA, (v & 0xFFFFF000) | 0x232);
/* set sdio ready */
tls_reg_write32(HR_SDIO_PROG, 0x02FD);
}
/**
* @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 the function.
*/
int tls_slave_spi_init(void)
{
struct tls_slave_hspi *hspi;
hspi = &g_slave_hspi;
memset(hspi, 0, sizeof(struct tls_slave_hspi));
hspi_rx_init(hspi);
hspi_tx_init(hspi);
// tls_set_high_speed_interface_type(HSPI_INTERFACE_SPI);
/* regiseter hspi tx rx cmd interrupt handler */
/* setting hw interrupt module isr enable regiset */
tls_irq_enable(SDIO_TX_DATA_INT);
tls_irq_enable(SDIO_RX_DATA_INT);
tls_irq_enable(SDIO_TX_CMD_INT);
tls_irq_enable(SPI1_INT);
/********************************************
* setting hspi wrapper registers
*********************************************/
/* hspi data down(rx) */
tls_reg_write32(HR_SDIO_TXBD_ADDR, HSPI_RX_DESC_BASE_ADDR);
tls_reg_write32(HR_SDIO_TXBD_LINKEN, 1);
tls_reg_write32(HR_SDIO_TXEN, 1);
/* hspi data up (tx) */
tls_reg_write32(HR_SDIO_RXBD_ADDR, HSPI_TX_DESC_BASE_ADDR);
tls_reg_write32(HR_SDIO_RXBD_LINKEN, 1);
/* hspi cmd down */
tls_reg_write32(HR_SDIO_CMD_ADDR, SDIO_CMD_RXBUF_ADDR);
tls_reg_write32(HR_SDIO_CMD_SIZE, SDIO_CMD_RXBUF_SIZE);
tls_reg_write32(HR_SDIO_DOWNCMDVALID, 0x1);
/* enable sdio module register */
tls_reg_write32(HR_SDIO_INT_MASK, 0x00);
return 0;
}
/**
* @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)
{
if (HSPI_INTERFACE_SPI == type)
{
#if 0
#if (HSPI_IO_REUSE_NUM == 0)
tls_io_cfg_set(WM_IO_PB_14, WM_IO_OPTION1);
tls_io_cfg_set(WM_IO_PB_15, WM_IO_OPTION1);
tls_io_cfg_set(WM_IO_PB_16, WM_IO_OPTION1);
tls_io_cfg_set(WM_IO_PB_17, WM_IO_OPTION1);
tls_io_cfg_set(WM_IO_PB_18, WM_IO_OPTION1);
#else
if(WM_IO_OPTION1 == tls_io_cfg_get(WM_IO_PB_14))
tls_io_cfg_set(WM_IO_PB_14, WM_IO_OPTION5);
if(WM_IO_OPTION1 == tls_io_cfg_get(WM_IO_PB_15))
tls_io_cfg_set(WM_IO_PB_15, WM_IO_OPTION5);
if(WM_IO_OPTION1 == tls_io_cfg_get(WM_IO_PB_16))
tls_io_cfg_set(WM_IO_PB_16, WM_IO_OPTION5);
if(WM_IO_OPTION1 == tls_io_cfg_get(WM_IO_PB_17))
tls_io_cfg_set(WM_IO_PB_17, WM_IO_OPTION5);
if(WM_IO_OPTION1 == tls_io_cfg_get(WM_IO_PB_18))
tls_io_cfg_set(WM_IO_PB_18, WM_IO_OPTION5);
tls_io_cfg_set(WM_IO_PB_08, WM_IO_OPTION2);
tls_io_cfg_set(WM_IO_PB_09, WM_IO_OPTION2);
tls_io_cfg_set(WM_IO_PB_10, WM_IO_OPTION2);
tls_io_cfg_set(WM_IO_PB_11, WM_IO_OPTION2);
tls_io_cfg_set(WM_IO_PB_12, WM_IO_OPTION2);
#endif
#endif
hspi_regs_cfg();
}
else if (HSPI_INTERFACE_SDIO == type)
{
#if 0
if(WM_IO_OPTION1 == tls_io_cfg_get(WM_IO_PB_16)) //HSPI_CK,as sdio need close
tls_io_cfg_set(WM_IO_PB_16, WM_IO_OPTION5);
if(WM_IO_OPTION2 == tls_io_cfg_get(WM_IO_PB_08)) //HSPI_CK,as sdio need close
tls_io_cfg_set(WM_IO_PB_08, WM_IO_OPTION5);
tls_io_cfg_set(WM_IO_PB_08, WM_IO_OPTION3);
tls_io_cfg_set(WM_IO_PB_09, WM_IO_OPTION3);
tls_io_cfg_set(WM_IO_PB_10, WM_IO_OPTION3);
tls_io_cfg_set(WM_IO_PB_11, WM_IO_OPTION3);
tls_io_cfg_set(WM_IO_PB_12, WM_IO_OPTION3);
#if (SDIO_IO_REUSE_NUM == 0)
tls_io_cfg_set(WM_IO_PA_06, WM_IO_OPTION3);
#elif (SDIO_IO_REUSE_NUM == 1)
tls_io_cfg_set(WM_IO_PB_07, WM_IO_OPTION3);
#else
tls_io_cfg_set(WM_IO_PB_13, WM_IO_OPTION4);
#endif
#endif
hsdio_regs_cfg();
}
}
/**
* @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)
{
struct tls_slave_hspi *hspi = &g_slave_hspi;
hspi->ifusermode = ifenable;
if (ifenable)
{
hspi->rx_cmd_callback = NULL;
hspi->rx_data_callback = NULL;
hspi->tx_data_callback = NULL;
}
}
/**
* @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))
{
g_slave_hspi.rx_cmd_callback = rx_cmd_callback;
}
/**
* @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))
{
g_slave_hspi.rx_data_callback = rx_data_callback;
}
/**
* @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))
{
g_slave_hspi.tx_data_callback = tx_data_callback;
}
/**
* @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)
{
struct tls_hspi_tx_desc *tx_desc;
int totallen = len;
int txlen;
if (NULL == txbuf || len <= 0 || len > (HSPI_TXBUF_SIZE * HSPI_TX_DESC_NUM))
{
printf("\nhspi tx param error\n");
return 0;
}
tx_desc = g_slave_hspi.curr_tx_desc;
while (1)
{
// printf("---\n");
if ((tx_desc->valid_ctrl & SET_BIT(31)) == 0)
break;
tls_os_time_delay(1);
}
while (!(tx_desc->valid_ctrl & SET_BIT(31)))
{
txlen = (totallen > HSPI_TXBUF_SIZE) ? HSPI_TXBUF_SIZE : totallen;
#if HSPI_TX_MEM_MALLOC
if (tx_desc->txbuf_addr != NULL)
{
printf("\nhspi txbuf not null,error %x\n", tx_desc->txbuf_addr);
if (tx_desc->txbuf_addr == tx_desc->buf_addr[0])
{
mem_free((void *) tx_desc->txbuf_addr);
tx_desc->txbuf_addr = NULL;
}
else // 不应该出现
{
printf("\nhspi tx mem error\n");
break;
}
}
tx_desc->txbuf_addr = (u32) mem_malloc(txlen + 1);
if (NULL == tx_desc->txbuf_addr)
{
printf("\nhspi tx data malloc error\n");
break;
}
tx_desc->buf_addr[0] = tx_desc->txbuf_addr;
#endif
MEMCPY((char *) tx_desc->buf_addr[0], txbuf, txlen);
tx_desc->buf_info = txlen << 12;
tx_desc->valid_ctrl = SET_BIT(31);
tls_reg_write32(HR_SDIO_RXEN, 0x01);
tx_desc = (struct tls_hspi_tx_desc *) tx_desc->next_desc_addr;
g_slave_hspi.curr_tx_desc = tx_desc;
totallen -= txlen;
if (totallen <= 0)
break;
}
return (len - totallen);
}
#endif
+319
View File
@@ -0,0 +1,319 @@
/**************************************************************************//**
* @file wm_i2c.c
* @author
* @version
* @date
* @brief
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "wm_regs.h"
#include "wm_i2c.h"
#include "wm_cpu.h"
#include "wm_irq.h"
#define I2C_FREQ_MAX (400000)
#define I2C_FREQ_MIN (100000)
#define I2C_WRITE (0x80)
#define I2C_READ (0x00)
typedef struct {
uint8_t addr;
uint8_t dev_addr;
uint8_t state;
uint8_t *buf;
uint16_t len;
uint16_t cnt;
uint8_t cmd;
void (*transfer_done)(void);
} i2c_desc;
enum {
START,
RESTART,
TRANSMIT,
PRERECEIVE,
RECEIVE,
STOP,
DONE,
IDLE,
};
static i2c_desc i2c_transfer;
void tls_i2c_init(u32 freq)
{
u32 div = 0;
tls_sys_clk clk;
if (freq < I2C_FREQ_MIN)
{
freq = I2C_FREQ_MIN;
}
else if (freq > I2C_FREQ_MAX)
{
freq = I2C_FREQ_MAX;
}
tls_sys_clk_get(&clk);
div = (clk.apbclk * 1000000)/(5 * freq) - 1;
tls_reg_write32(HR_I2C_PRER_LO, div & 0xff);
tls_reg_write32(HR_I2C_PRER_HI, (div>>8) & 0xff);
/** enable I2C | Disable Int*/
tls_reg_write32(HR_I2C_CTRL, I2C_CTRL_INT_DISABLE | I2C_CTRL_ENABLE);
tls_irq_enable(I2C_IRQn);
}
/**
* @brief send stop signal
*
*/
void tls_i2c_stop(void)
{
tls_reg_write32(HR_I2C_CR_SR, I2C_CR_STO);
while(tls_reg_read32(HR_I2C_CR_SR) & I2C_SR_TIP);
}
/**
* @brief waiting for ack signal
* @retval
* - \ref WM_FAILED
* - \ref WM_SUCCESS
*/
int tls_i2c_wait_ack(void)
{
u16 errtime=0;
u32 value;
while(tls_reg_read32(HR_I2C_CR_SR) & I2C_SR_TIP);
value = tls_reg_read32(HR_I2C_CR_SR);
while(value & I2C_SR_NAK)
{
errtime ++;
if(errtime > 512)
{
printf("wait ack err\n");
tls_i2c_stop();
return WM_FAILED;
}
value = tls_reg_read32(HR_I2C_CR_SR);
}
return WM_SUCCESS;
}
/**
* @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)
{
tls_reg_write32(HR_I2C_TX_RX, data);
if(ifstart)
tls_reg_write32(HR_I2C_CR_SR, I2C_CR_STA | I2C_CR_WR);
else
tls_reg_write32(HR_I2C_CR_SR, I2C_CR_WR);
while(tls_reg_read32(HR_I2C_CR_SR) & I2C_SR_TIP);
}
/**
* @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)
{
u8 data;
u32 value = I2C_CR_RD;
if(!ifack)
value |= I2C_CR_NAK;
if(ifstop)
value |= I2C_CR_STO;
tls_reg_write32(HR_I2C_CR_SR, value);
/** Waiting finish */
while(tls_reg_read32(HR_I2C_CR_SR) & I2C_SR_TIP);
data = tls_reg_read32(HR_I2C_TX_RX);
return data;
}
/**
* @brief start write 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)
{
if (buf == NULL)
{
return WM_FAILED;
}
I2C->TX_RX = devaddr;
i2c_transfer.dev_addr = devaddr;
i2c_transfer.state = START;
i2c_transfer.cmd = I2C_WRITE;
i2c_transfer.buf = buf;
i2c_transfer.len = len;
i2c_transfer.cnt = 0;
i2c_transfer.addr = wordaddr;
I2C->CR_SR = I2C_CR_STA | I2C_CR_WR;
return WM_SUCCESS;
}
/**
* @brief start read 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_read_it(uint8_t devaddr, uint8_t wordaddr, uint8_t * buf, uint16_t len)
{
if (buf == NULL)
{
return WM_FAILED;
}
I2C->TX_RX = devaddr;
i2c_transfer.dev_addr = devaddr;
i2c_transfer.state = START;
i2c_transfer.cmd = I2C_READ;
i2c_transfer.buf = buf;
i2c_transfer.len = len;
i2c_transfer.cnt = 0;
i2c_transfer.addr = wordaddr;
I2C->CR_SR = I2C_CR_STA | I2C_CR_WR;
return WM_SUCCESS;
}
/**
* @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))
{
i2c_transfer.transfer_done = done;
}
void I2C_IRQHandler(void)
{
int i2c_sr;
i2c_sr = I2C->CR_SR;
I2C->CR_SR = 1;
if (i2c_sr & 0x20)
{
printf("I2C AL lost\r\n");
}
if (i2c_sr & 0x01)
{
if ((i2c_sr & 0x80) == 0)
{
switch(i2c_transfer.state)
{
case START:
I2C->TX_RX = i2c_transfer.addr;
I2C->CR_SR = I2C_CR_WR;
if ((i2c_transfer.cmd & I2C_WRITE) == I2C_WRITE)
{
i2c_transfer.state = TRANSMIT;
}
else
{
i2c_transfer.state = RESTART;
}
break;
case RESTART:
I2C->TX_RX = (i2c_transfer.dev_addr | 0x01);
I2C->CR_SR = (I2C_CR_STA | I2C_CR_WR);
i2c_transfer.state = PRERECEIVE;
break;
case TRANSMIT:
I2C->TX_RX = i2c_transfer.buf[i2c_transfer.cnt++];
I2C->CR_SR = I2C_CR_WR;
if (i2c_transfer.cnt == i2c_transfer.len)
{
i2c_transfer.state = STOP;
}
break;
case PRERECEIVE:
i2c_transfer.state = RECEIVE;
I2C->CR_SR = I2C_CR_RD;
break;
case RECEIVE:
i2c_transfer.buf[i2c_transfer.cnt++] = I2C->TX_RX;
if (i2c_transfer.cnt == (i2c_transfer.len - 1))
{
I2C->CR_SR = (I2C_CR_STO | I2C_CR_NAK | I2C_CR_RD);
i2c_transfer.state = STOP;
}
else if (i2c_transfer.len == 1)
{
I2C->CR_SR = (I2C_CR_STO | I2C_CR_NAK | I2C_CR_RD);
i2c_transfer.state = DONE;
if (i2c_transfer.transfer_done)
{
i2c_transfer.transfer_done();
}
}
else
{
I2C->CR_SR = I2C_CR_RD;
}
break;
case STOP:
I2C->CR_SR = I2C_CR_STO;
i2c_transfer.state = DONE;
if (i2c_transfer.transfer_done)
{
i2c_transfer.transfer_done();
}
break;
}
}
else
{
if ((i2c_transfer.state == STOP) && i2c_transfer.cmd != I2C_WRITE)
{
i2c_transfer.buf[i2c_transfer.cnt] = I2C->TX_RX;
i2c_transfer.state = DONE;
if (i2c_transfer.transfer_done)
{
i2c_transfer.transfer_done();
}
}
}
}
// if ((i2c_sr & 0x40) == 0)
// {
// i2c_transfer.state = IDLE;
// }
}
/*** (C) COPYRIGHT 2014 Winner Microelectronics Co., Ltd. ***/
+584
View File
@@ -0,0 +1,584 @@
/**************************************************************************//**
* @file wm_i2s.c
* @author
* @version
* @date
* @brief
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd. All rights reserved.
*****************************************************************************/
#define TLS_CONFIG_I2S 1
#if TLS_CONFIG_I2S
#include "wm_i2s.h"
#include "string.h"
#include "wm_debug.h"
#include "wm_irq.h"
#include "wm_config.h"
#include "wm_mem.h"
#define I2S_CLK (160000000)
#define WM_I2S_FIFO_LEN (8)
static tls_i2s_port_t tls_i2s_port;
static void tls_i2s_fill_txfifo(void);
/**
* @brief This function is used to initial i2s port.
* @param[in] opts the i2s setting options,if this param is NULL,this function will use the default options.
* @retval
* - \ref WM_SUCCESS
* - \ref WM_FAILED
*
*/
int tls_i2s_port_init(tls_i2s_options_t *opts)
{
tls_i2s_options_t opt;
tls_i2s_port.regs = I2S;
if(NULL == opts)
{
memset(&opt, 0, sizeof(tls_i2s_options_t));
opt.data_width = I2S_CTRL_DATABIT_16;
opt.format = I2S_CTRL_FORMAT_I2S;
opt.stereo_mono = I2S_CTRL_STERO;
opt.sample_rate = 8000;
opt.tx_en = 1;
tls_i2s_config(&opt);
}
else
{
tls_i2s_config(opts);
}
/* enable i2s interrupt */
NVIC_ClearPendingIRQ(I2S_IRQn);
tls_irq_enable(I2S_INT);
return WM_SUCCESS;
}
/**
* @brief This function is used to initial i2s port.
* @param[in] opts the i2s setting options,if this param is NULL,this function will use the default options.
*
* @retval
*
* @note
*/
void tls_i2s_config(tls_i2s_options_t *opts)
{
tls_i2s_port.regs->CTRL &= ~(I2S_CTRL_FORMAT_MASK | \
I2S_CTRL_DATABIT_MASK | \
I2S_CTRL_STEREO_MONO_MASK);
tls_i2s_port.regs->CTRL = opts->data_width | opts->format | opts->stereo_mono;
if (opts->rx_en)
{
TLS_I2S_RX_ENABLE();
TLS_I2S_RX_FIFO_CLEAR();
}
if (opts->tx_en)
{
TLS_I2S_TX_ENABLE();
TLS_I2S_TX_FIFO_CLEAR();
}
tls_i2s_set_freq(opts->sample_rate);
}
/**
* @brief
* set the frequency of the i2s port.
*
* @param[in] freq
* the required frequency of the i2s module
*
* @retval
*
*/
void tls_i2s_set_freq(uint32_t freq)
{
uint32_t div;
uint32_t reg;
uint8_t width, stereo;
reg = I2S->CTRL;
width = (((reg>>4)&0x03)+1)<<3;
stereo = tls_bitband_read(HR_I2S_CTRL, I2S_CTRL_STEREO_MONO_Pos) ? 1:2;
div = (I2S_CLK + freq * width * stereo)/(freq * width * stereo) - 1;
*(volatile uint32_t *)HR_CLK_I2S_CTL &= ~0xFF00;
*(volatile uint32_t *)HR_CLK_I2S_CTL |= (uint32_t)div<<8;
}
/**
* @brief
* set the frequency of the i2s port.
*
* @param[in] freq
* the required frequency of the i2s module
* @param[in] exclk
* the frequency of the ext clock
*
* @retval
*
* @note
* this function will be called after tls_i2s_port_init function
*/
void wm_i2s_set_freq_exclk(uint32_t freq, uint32_t exclk)
{
uint32_t div;
uint32_t temp;
uint8_t wdwidth, stereo;
temp = I2S->CTRL;
wdwidth = (((temp>>4)&0x03)+1)<<3;
stereo = tls_bitband_read(HR_I2S_CTRL, 22) ? 1:2;
div = (exclk * 2 + freq * wdwidth * stereo)/(2* freq * wdwidth * stereo) - 1;
*(volatile uint32_t *)0x40000718 &= ~0x3FF00;
*(volatile uint32_t *)0x40000718 |= (uint32_t)div<<8;
*(volatile uint32_t *)0x40000718 |= 0x01;
}
void I2S_IRQHandler(void)
{
uint8_t rx_fifocnt;
/** LZC */
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_LZC_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_LZC_Pos))
{
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_LZC);
}
/** RZC */
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_RZC_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_RZC_Pos))
{
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_RZC);
}
/** Tx Done*/
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_TXDONE_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_TXDONE_Pos))
{
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_TXDONE);
}
/** TxTH*/
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_TXTH_Pos)&& !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_TXTH_Pos))
{
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_TXTH);
tls_i2s_fill_txfifo();
}
/** TXOV*/
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_TXOV_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_TXOV_Pos))
{
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_TXOV);
}
/** TXUD*/
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_TXUD_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_TXUD_Pos))
{
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_TXUD);
}
/** Rx Done*/
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_RXDONE_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_RXDONE_Pos))
{
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_RXDONE);
}
/** RxTH */
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_RXTH_Pos)&& !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_RXTH_Pos))
{
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_RXTH);
rx_fifocnt = tls_i2s_port.regs->INT_STATUS & I2S_RX_FIFO_CNT_MASK;
if (tls_i2s_port.rx_buf.buf != NULL)
{
while(rx_fifocnt-- > 0)
{
tls_i2s_port.rx_buf.buf[tls_i2s_port.rx_buf.index] = tls_i2s_port.regs->RX;
tls_i2s_port.rx_buf.index++;
}
if (tls_i2s_port.rx_buf.index >= (tls_i2s_port.rx_buf.len))
{
tls_i2s_port.rx_buf.buf = NULL;
tls_i2s_int_config(I2S_INT_MASK_RXTH, 0);
if (tls_i2s_port.rx_callback != NULL)
{
tls_i2s_port.rx_callback(tls_i2s_port.rx_buf.len);
}
tls_i2s_port.rx_buf.index = 0;
}
}
}
/** RXOV*/
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_RXOV_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_RXOV_Pos))
{
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_RXOV);
}
/** RXUD*/
if (tls_bitband_read(HR_I2S_INT_SRC, I2S_FLAG_RXUD_Pos) && !tls_bitband_read(HR_I2S_INT_MASK, I2S_FLAG_RXUD_Pos))
{
tls_reg_write32(HR_I2S_INT_SRC, I2S_FLAG_RXUD);
}
}
/**
* @brief
* This function is used to register i2s rx interrupt.
*
* @param[in] rx_callback
* is the i2s interrupt call back function.
*
* @retval
*
*/
void tls_i2s_rx_register( void (*rx_callback)(u16 len))
{
tls_i2s_port.rx_callback = rx_callback;
}
/**
* @brief
* This function is used to register i2s tx interrupt.
*
* @param[in] tx_callback
* is the i2s interrupt call back function.
*
* @retval
*
*/
void tls_i2s_tx_register(void (* tx_callback)(u16 len))
{
tls_i2s_port.tx_callback = tx_callback;
}
static void tls_i2s_fill_txfifo()
{
s8 fifo_left = 0;
if (tls_i2s_port.tx_buf.index < tls_i2s_port.tx_buf.len)
{
fifo_left = I2S_MAX_RXTXFIFO_LEVEL - ((tls_i2s_port.regs->INT_STATUS & I2S_TX_FIFO_CNT_MASK)>>4);
while (fifo_left--)
{
tls_i2s_port.regs->TX = *(uint32_t *)(tls_i2s_port.tx_buf.buf + tls_i2s_port.tx_buf.index);
tls_i2s_port.tx_buf.index ++;
}
if(tls_i2s_port.tx_buf.index >= tls_i2s_port.tx_buf.len)
{
while((tls_i2s_port.regs->INT_STATUS & I2S_TX_FIFO_CNT_MASK)>>4);
if(tls_i2s_port.tx_sem)
{
memset(&tls_i2s_port.tx_buf, 0, sizeof(tls_i2s_buf));
tls_os_sem_release(tls_i2s_port.tx_sem);
return;
}
if (tls_i2s_port.tx_callback)
{
tls_i2s_port.tx_callback(tls_i2s_port.tx_buf.len);
}
}
}
}
/**
* @brief
* This function is used to transfer data in blocking mode.
*
* @param[in] buf
* pointer to the transfering data.
*
* @param[in] len
* is the data length.
*
* @retval
*
*/
int tls_i2s_tx_block(uint32_t *buf, uint16_t len)
{
uint8_t err;
err = tls_os_sem_create(&tls_i2s_port.tx_sem, 0);
if (err != TLS_OS_SUCCESS)
{
TLS_DBGPRT_ERR("\ni2s tx sem create fail\n");
return WM_FAILED;
}
TLS_I2S_TX_FIFO_CLEAR();
tls_reg_write32(HR_I2S_INT_SRC, 0x1FF);
NVIC_ClearPendingIRQ(I2S_IRQn);
tls_i2s_port.tx_buf.buf = buf;
tls_i2s_port.tx_buf.len = len;
tls_i2s_port.tx_buf.index = 0;
tls_i2s_set_txth(5);
tls_i2s_int_config(I2S_INT_MASK_TXTH, 1);
TLS_I2S_TX_ENABLE();
TLS_I2S_ENABLE();
tls_os_sem_acquire(tls_i2s_port.tx_sem, 0);
tls_os_sem_delete(tls_i2s_port.tx_sem);
tls_i2s_port.tx_sem = NULL;
TLS_I2S_TX_DISABLE();
return WM_SUCCESS;
}
/**
* @brief
* This function is used to transfer data in non blocking mode.
*
* @param[in] buf
* is a buf for user data.
*
* @param[in] len
* is the data length.
*
* @param[in] tx_callback
* a function pointer,which will be called when the designated data sent
*
* @retval
*
* @note the \ref len in words
*/
int tls_i2s_tx_nonblock(uint32_t *buf, uint16_t len, void (*tx_callback)(u16 len))
{
tls_i2s_port.tx_buf.buf = (uint32_t *)buf;
tls_i2s_port.tx_buf.len = len;
tls_i2s_port.tx_buf.index = 0;
tls_i2s_set_txth(5);
tls_i2s_int_config(I2S_INT_MASK_TXTH, 1);
tls_i2s_tx_register( tx_callback);
TLS_I2S_TX_FIFO_CLEAR();
TLS_I2S_TX_ENABLE();
TLS_I2S_ENABLE();
return WM_SUCCESS;
}
/**
* @brief
* This function is used to receiver data in non blocking mode.
*
* @param[in] buf
* the buffer for storing the received data.
*
* @param[in] len
* the length of the data will be receiving
*
* @param[in] rx_callback
* a function pointer,which will be called when the demanded data have been received
*
* @retval
*
*/
int tls_i2s_rx_nonblock(uint32_t *buf, uint16_t len, void (*rx_callback)(u16 len))
{
tls_i2s_port.rx_buf.buf = buf;
tls_i2s_port.rx_buf.len = len;
tls_i2s_port.rx_buf.index = 0;
tls_i2s_set_rxth(5);
tls_i2s_int_config(I2S_INT_MASK_RXTH, 1);
tls_i2s_rx_register( rx_callback);
TLS_I2S_RX_FIFO_CLEAR();
NVIC_ClearPendingIRQ(I2S_IRQn);
TLS_I2S_RX_ENABLE();
TLS_I2S_ENABLE();
return WM_SUCCESS;
}
/**
* @brief
* This function is used to the tx DMA configuration of the I2S module.
*
* @param[in] dma_channel
* the free dma channel number which returned by calling function tls_dma_request()
*
* @param[in] addr
* point to the data buffer will be sent
*
* @param[in] len
* length of the data to be transfered in bytes
*
* @retval
*/
void tls_i2s_tx_dma_config(uint8_t dma_channel, uint32_t * addr, uint16_t len)
{
struct tls_dma_descriptor DmaDesc;
TLS_I2S_TX_DISABLE();
TLS_I2S_TX_FIFO_CLEAR();
/** Mask i2s txth interrupt*/
tls_i2s_set_txth(4);
tls_i2s_int_config(I2S_INT_MASK_TXTH, 0);
DmaDesc.src_addr = (unsigned int) addr;
DmaDesc.dest_addr = (unsigned int)HR_I2S_TX;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_SRC_ADD_INC | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD |
(len << 7);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dma_channel, &DmaDesc, 0);
}
/**
* @brief
* datas transmit throuth DMA
*
* @param[in] addr
* point to the data buffer will be sent
* @param[in] len
* length of the data to be transfered in bytes
* @param[in] callback
* the callback function when datas transfer finished
*
* @retval
*
* @note the \ref len in bytes
*/
int tls_i2s_tx_dma(uint32_t * addr, uint16_t len, tls_i2s_callback callback)
{
uint8_t tx_channel;
TLS_I2S_TX_FIFO_CLEAR();
tls_reg_write32(HR_I2S_INT_SRC, 0x1FF);
NVIC_ClearPendingIRQ(I2S_IRQn);
TLS_I2S_TX_FIFO_CLEAR();
tx_channel = tls_dma_request(WM_I2S_TX_DMA_CHANNEL, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_I2S_TX) | TLS_DMA_FLAGS_HARD_MODE);
if (tx_channel == 0)
{
return WM_FAILED;
}
if (tls_dma_stop(tx_channel))
{
return WM_FAILED;
}
tls_i2s_tx_dma_config(tx_channel, addr, len);
tls_dma_irq_register(tx_channel, callback, NULL, TLS_DMA_IRQ_TRANSFER_DONE);
TLS_I2S_TXDMA_ENABLE();
TLS_I2S_TX_ENABLE();
TLS_I2S_ENABLE();
return WM_SUCCESS;
}
/**
* @brief
* This function is used to the rx DMA configuration of the I2S module.
*
* @param[in] addr
* point to the storge buffer of the received data
*
* @param[in] len
* the storge buffer length in bytes
*
* @retval
*/
void tls_i2s_rx_dma_config(uint8_t dma_channel, uint32_t * addr, uint16_t len)
{
struct tls_dma_descriptor DmaDesc;
tls_i2s_int_config(I2S_INT_MASK_RXTH, 0);
TLS_I2S_RX_DISABLE();
TLS_I2S_RXDMA_DISABLE();
TLS_I2S_RX_FIFO_CLEAR();
/** Mask i2s rxth interrupt*/
tls_i2s_set_rxth(4);
tls_i2s_int_config(I2S_INT_MASK_RXTH, 0);
DmaDesc.src_addr = (int)HR_I2S_RX;
DmaDesc.dest_addr = (int)addr;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD |
(len << 7);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dma_channel, &DmaDesc, 0);
}
int tls_i2s_rx_dma(uint32_t * addr, uint16_t len, tls_i2s_callback callback)
{
uint8_t rx_channel;
rx_channel = tls_dma_request(WM_I2S_RX_DMA_CHANNEL, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_I2S_RX) | TLS_DMA_FLAGS_HARD_MODE);
if (rx_channel == 0)
{
return WM_FAILED;
}
if (tls_dma_stop(rx_channel))
{
return WM_FAILED;
}
tls_i2s_rx_dma_config(rx_channel, addr, len);
tls_dma_irq_register(rx_channel, callback, NULL, TLS_DMA_IRQ_TRANSFER_DONE);
TLS_I2S_RXDMA_ENABLE();
NVIC_ClearPendingIRQ(I2S_IRQn);
TLS_I2S_RX_ENABLE();
TLS_I2S_ENABLE();
return WM_SUCCESS;
}
#if 1
uint8_t tst_flag = 0;
void tls_i2s_tx_dma_callback()
{
I2S->TX = 0x00;
while(!tls_bitband_read(HR_I2S_INT_SRC, 7));
TLS_I2S_TX_DISABLE();
DMA_CHNLCTRL_REG(WM_I2S_TX_DMA_CHANNEL) |= DMA_CHNL_CTRL_CHNL_OFF;
tls_dma_free(WM_I2S_TX_DMA_CHANNEL);
tst_flag = 1;
}
void tls_i2s_rx_dma_callback()
{
TLS_I2S_RX_DISABLE();
DMA_CHNLCTRL_REG(WM_I2S_RX_DMA_CHANNEL) |= DMA_CHNL_CTRL_CHNL_OFF;
tls_dma_free(WM_I2S_RX_DMA_CHANNEL);
tst_flag = 1;
}
void tls_i2s_rx_callback()
{
TLS_I2S_RX_DISABLE();
tst_flag = 1;
}
void tls_i2s_test()
{
uint32_t *ptr = NULL;
uint32_t len;
uint32_t * i2s_tx_test = tls_mem_alloc(1024);
tls_i2s_port.opts.data_width = I2S_CTRL_DATABIT_16;
tls_i2s_port.opts.format = I2S_CTRL_FORMAT_I2S;
tls_i2s_port.opts.tx_en = 1;
tls_i2s_port.opts.sample_rate = 8000;
tls_i2s_port.opts.stereo_mono = I2S_CTRL_STERO;
tls_i2s_port_init(&tls_i2s_port.opts);
if (i2s_tx_test == NULL)
{
return;
}
ptr = i2s_tx_test;
for (len = 0; len < 256; len++)
{
*ptr++ = 0xABCD0200 + len;
}
i2s_tx_test[255] = 0xABCD02FA;
tls_i2s_tx_dma(i2s_tx_test, 1024,tls_i2s_tx_dma_callback);
while(!tst_flag);
tst_flag = 0;
tls_i2s_tx_dma(i2s_tx_test, 1024,tls_i2s_tx_dma_callback);
while(!tst_flag);
tst_flag = 0;
}
#endif
#endif /** TLS_CONFIG_I2S */
/*** (C) COPYRIGHT 2014 Winner Microelectronics Co., Ltd. ***/
File diff suppressed because it is too large Load Diff
+277
View File
@@ -0,0 +1,277 @@
/**
* @file wm_io.c
*
* @brief IO Driver Module
*
* @author lilm
*
* Copyright (c) 2015 Winner Microelectronics Co., Ltd.
*/
#include "wm_regs.h"
#include "wm_osal.h"
#include "wm_io.h"
#include "wm_dbg.h"
#include "tls_common.h"
static void io_cfg_option1(enum tls_io_name name)
{
u8 pin;
u16 offset;
if ( (WM_IO_PB_25 == name) || (WM_IO_PB_26 == name) || (WM_IO_PB_29 == name) )
{
TLS_DBGPRT_IO_ERR("io %u have no option1.\r\n", name);
return;
}
if (name >= WM_IO_PB_00)
{
pin = name - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = name;
offset = 0;
}
tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */
tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) & (~BIT(pin)));
tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) & (~BIT(pin)));
return;
}
static void io_cfg_option2(enum tls_io_name name)
{
u8 pin;
u16 offset;
if ( (WM_IO_PB_13 == name) || (WM_IO_PB_27 == name) ||
(WM_IO_PB_31 == name) )
{
TLS_DBGPRT_IO_ERR("io %u have no option2.\r\n", name);
return;
}
if (name >= WM_IO_PB_00)
{
pin = name - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = name;
offset = 0;
}
tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */
tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) & (~BIT(pin)));
tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) | BIT(pin));
return;
}
static void io_cfg_option3(enum tls_io_name name)
{
u8 pin;
u16 offset;
if ( (name == WM_IO_PB_19) || (name == WM_IO_PB_20) ||
(name >= WM_IO_PB_23) || (name == WM_IO_PA_00) ||
(name == WM_IO_PA_07) ||
((name >= WM_IO_PA_13) && (name <= WM_IO_PA_15)) )
{
TLS_DBGPRT_IO_ERR("io %u have no option3.\r\n", name);
return;
}
if (name >= WM_IO_PB_00)
{
pin = name - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = name;
offset = 0;
}
tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */
tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) | BIT(pin));
tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) & (~BIT(pin)));
return;
}
static void io_cfg_option4(enum tls_io_name name)
{
u8 pin;
u16 offset;
if( (name == WM_IO_PA_00) || (name == WM_IO_PA_01) ||
(name == WM_IO_PA_06) ||
((name >= WM_IO_PA_13) && (name <= WM_IO_PA_15)) ||
((name >= WM_IO_PB_00) && (name <= WM_IO_PB_02)) ||
(name >= WM_IO_PB_19) )
{
TLS_DBGPRT_IO_ERR("io %u have no option4.\r\n", name);
return;
}
if (name >= WM_IO_PB_00)
{
pin = name - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = name;
offset = 0;
}
tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */
tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) | BIT(pin));
tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) | BIT(pin));
return;
}
static void io_cfg_option5(enum tls_io_name name)
{
u8 pin;
u16 offset;
if (name >= WM_IO_PB_00)
{
pin = name - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = name;
offset = 0;
}
tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) & (~BIT(pin))); /* disable gpio function */
return;
}
static void io_cfg_option6(enum tls_io_name name)
{
u8 pin;
u16 offset;
if( ((name >= WM_IO_PB_06)&&(name <= WM_IO_PB_18)) ||
((name >= WM_IO_PB_29)&&(name <= WM_IO_PB_31)))
{
TLS_DBGPRT_IO_ERR("io %u have no option6.\r\n", name);
return;
}
if (name >= WM_IO_PB_00)
{
pin = name - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = name;
offset = 0;
}
tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) & (~BIT(pin))); /* disable gpio function */
tls_reg_write32(HR_GPIO_DIR + offset, tls_reg_read32(HR_GPIO_DIR + offset) & (~BIT(pin)));
tls_reg_write32(HR_GPIO_PULL_EN + offset, tls_reg_read32(HR_GPIO_PULL_EN + offset) & (~BIT(pin)));
return;
}
/**
* @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)
{
if (WM_IO_OPTION1 == option)
io_cfg_option1(name);
else if (WM_IO_OPTION2 == option)
io_cfg_option2(name);
else if (WM_IO_OPTION3 == option)
io_cfg_option3(name);
else if (WM_IO_OPTION4 == option)
io_cfg_option4(name);
else if (WM_IO_OPTION5 == option)
io_cfg_option5(name);
else if (WM_IO_OPTION6 == option)
io_cfg_option6(name);
else
TLS_DBGPRT_IO_ERR("invalid io option.\r\n");
return;
}
/**
* @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)
{
u8 pin;
u16 offset;
u32 afsel,afs1,afs0,dir,pullen;
if (name >= WM_IO_PB_00)
{
pin = name - WM_IO_PB_00;
offset = TLS_IO_AB_OFFSET;
}
else
{
pin = name;
offset = 0;
}
afsel = tls_reg_read32(HR_GPIO_AF_SEL + offset);
afs1 = tls_reg_read32(HR_GPIO_AF_S1 + offset);
afs0 = tls_reg_read32(HR_GPIO_AF_S0 + offset);
dir = tls_reg_read32(HR_GPIO_DIR + offset);
pullen = tls_reg_read32(HR_GPIO_PULL_EN + offset);
if(afsel&BIT(pin))
{
if((0==(afs1&BIT(pin))) && (0==(afs0&BIT(pin))))
return WM_IO_OPTION1;
else if((0==(afs1&BIT(pin))) && (afs0&BIT(pin)))
return WM_IO_OPTION2;
else if((afs1&BIT(pin)) && (0==(afs0&BIT(pin))))
return WM_IO_OPTION3;
else if((afs1&BIT(pin)) && (afs0&BIT(pin)))
return WM_IO_OPTION4;
}
else
{
if((!(dir&BIT(pin))) && (pullen&BIT(pin)))
return WM_IO_OPTION6;
else
return WM_IO_OPTION5;
}
return 0;
}
+270
View File
@@ -0,0 +1,270 @@
/**
* @file wm_iouart.c
*
* @brief IO uart Driver Module
*
* @author dave
*
* Copyright (c) 2015 Winner Microelectronics Co., Ltd.
*/
#include <string.h>
#include "wm_iouart.h"
#include "wm_debug.h"
#include "wm_irq.h"
#include "wm_config.h"
#include "wm_mem.h"
#include "wm_gpio.h"
#include "wm_timer.h"
#if 1//TLS_CONFIG_IOUART
struct tls_io_uart io_uart;
#if !IO_UART_FOR_PRINT
void iouart0_timer_cb(void)
{
int i = 0;
static u8 ch = 0;
// if(io_uart.ifrx)
{
if (0 == io_uart.bitnum) // 起始位
{
io_uart.bit[io_uart.bitcnt] = tls_gpio_read(IO_UART_RX);
if (io_uart.bit[io_uart.bitcnt++] != 0)
{
io_uart.bitcnt = 0;
tls_timer_stop(io_uart.timerid);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
return;
}
// if(io_uart.bitcnt == IO_UART_ONEBITE_SAMPLE_NUM)
{
io_uart.bitcnt = 0;
io_uart.bitnum ++;
ch = 0;
}
}
else if (io_uart.bitnum >= 1 && io_uart.bitnum <= 8) // 数据位
{
io_uart.bit[io_uart.bitcnt++] = tls_gpio_read(IO_UART_RX);
if(io_uart.bitcnt == IO_UART_ONEBITE_SAMPLE_NUM)
{
for(i=0; i<(IO_UART_ONEBITE_SAMPLE_NUM-1); i++)
{
if(io_uart.bit[i] != io_uart.bit[i+1])
{
io_uart.bitcnt = 0;
io_uart.bitnum = 0;
tls_timer_stop(io_uart.timerid);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
return;
}
}
if(io_uart.bit[0])
{
ch |= (1 << (io_uart.bitnum - 1));
}
io_uart.bitnum ++;
io_uart.bitcnt = 0;
}
}
else if (9 == io_uart.bitnum) // 停止位
{
io_uart.bit[io_uart.bitcnt++] = tls_gpio_read(IO_UART_RX);
if(io_uart.bitcnt == IO_UART_ONEBITE_SAMPLE_NUM)
{
if(io_uart.bit[i] != io_uart.bit[i+1])
{
io_uart.bitcnt = 0;
io_uart.bitnum = 0;
tls_timer_stop(io_uart.timerid);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
return;
}
}
if(io_uart.bit[0] == 0)
{
io_uart.bitcnt = 0;
io_uart.bitnum = 0;
tls_timer_stop(io_uart.timerid);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
return;
}
io_uart.recv.buf[io_uart.recv.head] = ch;
io_uart.recv.head =(io_uart.recv.head + 1) & (TLS_IO_UART_RX_BUF_SIZE -1);
io_uart.bitnum = 0;
io_uart.bitcnt = 0;
ch = 0;
io_uart.ifrx = 0;
tls_timer_stop(io_uart.timerid);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
}
}
}
void iouart0_gpio_isr_callback(void *context)
{
u16 ret;
ret = tls_get_gpio_irq_status(IO_UART_RX);
if(ret)
{
tls_clr_gpio_irq_status(IO_UART_RX);
ret = tls_gpio_read(IO_UART_RX);
if(ret == 0)
{
io_uart.ifrx = 1;
tls_gpio_irq_disable(IO_UART_RX);
tls_timer_start(io_uart.timerid);
}
}
}
#endif
void iouart_tx_byte(u8 datatoSend)
{
u8 i, tmp;
u32 cpu_sr = 0;
cpu_sr = tls_os_set_critical(); // 发送一个byte的过程中不能被打断,否则可能会有错误码
/* Start bit */
tls_gpio_write(IO_UART_TX, 0);
tls_delay_via_timer(io_uart.timercnt+1, 0);
for (i = 0; i < 8; i++)
{
tmp = (datatoSend >> i) & 0x01;
if (tmp == 0)
{
tls_gpio_write(IO_UART_TX, 0);
}
else
{
tls_gpio_write(IO_UART_TX, 1);
}
tls_delay_via_timer(io_uart.timercnt+1, 0);
}
tls_gpio_write(IO_UART_TX, 1);
tls_delay_via_timer(io_uart.timercnt+1, 0);
tls_os_release_critical(cpu_sr);
}
int tls_iouart_init(int bandrate)
{
char *bufrx;
memset(&io_uart, 0, sizeof(struct tls_io_uart));
#if !IO_UART_FOR_PRINT
bufrx = tls_mem_alloc(TLS_IO_UART_RX_BUF_SIZE);
if (!bufrx)
return WM_FAILED;
memset(bufrx, 0, TLS_IO_UART_RX_BUF_SIZE);
io_uart.recv.buf = (u8 *) bufrx;
io_uart.recv.head = 0;
io_uart.recv.tail = 0;
#endif
tls_gpio_cfg(IO_UART_TX, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING);
tls_gpio_write(IO_UART_TX, 1);
tls_gpio_cfg(IO_UART_RX, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_PULLHIGH);
tls_gpio_isr_register(IO_UART_RX, iouart0_gpio_isr_callback, NULL);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
io_uart.timercnt = 1000000 / bandrate;
#if !IO_UART_FOR_PRINT
struct tls_timer_cfg timer_cfg;
timer_cfg.unit = TLS_TIMER_UNIT_US;
timer_cfg.timeout = io_uart.timercnt/IO_UART_ONEBITE_SAMPLE_NUM;
timer_cfg.is_repeat = 1;
timer_cfg.callback = (tls_timer_irq_callback)iouart0_timer_cb;
timer_cfg.arg = NULL;
io_uart.timerid = tls_timer_create(&timer_cfg);
#endif
return WM_SUCCESS;
}
int tls_iouart_destroy(void)
{
tls_gpio_irq_disable(IO_UART_RX);
tls_timer_destroy(io_uart.timerid);
io_uart.timerid = 0xFF;
tls_mem_free(io_uart.recv.buf);
return WM_SUCCESS;
}
int tls_iouart_read(u8 * buf, int bufsize)
{
int data_cnt, buflen, bufcopylen;
if (NULL == buf)
return WM_FAILED;
data_cnt =
CIRC_CNT(io_uart.recv.head, io_uart.recv.tail, TLS_IO_UART_RX_BUF_SIZE);
if (data_cnt >= bufsize)
{
buflen = bufsize;
}
else
{
buflen = data_cnt;
}
if ((io_uart.recv.tail + buflen) > TLS_IO_UART_RX_BUF_SIZE)
{
bufcopylen = (TLS_IO_UART_RX_BUF_SIZE - io_uart.recv.tail);
MEMCPY(buf, io_uart.recv.buf + io_uart.recv.tail, bufcopylen);
MEMCPY(buf + bufcopylen, io_uart.recv.buf, buflen - bufcopylen);
}
else
{
MEMCPY(buf, io_uart.recv.buf + io_uart.recv.tail, buflen);
}
io_uart.recv.tail = (io_uart.recv.tail + buflen) & (TLS_IO_UART_RX_BUF_SIZE - 1);
return buflen;
}
int tls_iouart_write(u8 * buf, int bufsize)
{
if (NULL == buf || bufsize <= 0 || 1 == io_uart.ifrx)
return WM_FAILED;
io_uart.iftx = 1;
while (bufsize)
{
iouart_tx_byte(*buf);
bufsize--;
buf++;
}
io_uart.iftx = 0;
return WM_SUCCESS;
}
int tls_iouart_output_char(int ch)
{
if(ch == '\n')
iouart_tx_byte('\r');
iouart_tx_byte((char)ch);
return ch;
}
#endif //TLS_CONFIG_IOUART
+149
View File
@@ -0,0 +1,149 @@
/**
* @file wm_irq.c
*
* @brief interupt driver module
*
* @author dave
*
* Copyright (c) 2015 Winner Microelectronics Co., Ltd.
*/
#include <stdio.h>
#include "wm_regs.h"
#include "wm_irq.h"
#include "wm_config.h"
#include "wm_mem.h"
void tls_irq_handler_dummy(void *data)
{
}
tls_irq_handler_t *intr_handler_vect[INTR_CNT];
u8 intr_counter;
/**
* @brief This function is used to initial system interrupt.
*
* @param[in] None
*
* @return None
*
* @note None
*/
void tls_irq_init(void)
{
#if 0
int i;
for (i = 0; i < INTR_CNT; i++)
{
intr_handler_vect[i].handler = tls_irq_handler_dummy;
intr_handler_vect[i].data = NULL;
intr_handler_vect[i].name = "intr_dummy";
intr_handler_vect[i].counter = 0;
}
#endif
intr_counter = 0;
/* initailize VIC */
tls_reg_write32(HR_VIC_INT_SELECT, 0);
tls_reg_write32(HR_VIC_VECT_ENABLE, 0); /* disable vector interrupt */
tls_reg_write32(HR_VIC_INT_EN_CLR, 0xFFFFFFFF);
}
/**
* @brief This function is used to register interrupt.
*
* @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)
{
// ASSERT (vec_no >= 0 && vec_no <= 0x1f);
if (NULL == intr_handler_vect[vec_no])
{
intr_handler_vect[vec_no] = tls_mem_alloc(sizeof(tls_irq_handler_t));
}
if (intr_handler_vect[vec_no])
{
intr_handler_vect[vec_no]->handler = handler;
intr_handler_vect[vec_no]->data = data;
// intr_handler_vect[vec_no].name = NULL;
intr_handler_vect[vec_no]->counter = 0;
}
}
extern void NVIC_Configration(int irqno, FunctionalState irqstatus);
/**
* @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)
{
NVIC_ClearPendingIRQ((IRQn_Type)vec_no);
NVIC_Configration(vec_no, ENABLE);
}
/**
* @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)
{
NVIC_Configration(vec_no, DISABLE);
NVIC_ClearPendingIRQ((IRQn_Type)vec_no);
}
/**
* @brief This function is used to set interrupt priority.
*
* @param[in] vec_no interrupt no
* @param[in] priority priority
*
* @return None
*
* @note None
*/
void tls_irq_set_priority(u8 vec_no, u8 priority)
{
NVIC_SetPriority(vec_no, priority);
}
void OS_CPU_IRQ_ISR_Handler(void)
{
u32 irq_status = tls_reg_read32(HR_VIC_IRQ_STATUS);
int i = 0;
intr_counter++;
for (i = 0; i < INTR_CNT; i++)
{
if (irq_status & (1UL << i))
{
intr_handler_vect[i]->handler((void *) intr_handler_vect[i]->data);
intr_handler_vect[i]->counter++;
}
}
intr_counter--;
/* clear interrupt */
tls_reg_write32(HR_VIC_VECT_ADDR, 0);
}
+187
View File
@@ -0,0 +1,187 @@
/**************************************************************************//**
* @file wm_lcd.c
* @author
* @version
* @date
* @brief
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd. All rights reserved.
*****************************************************************************/
#include "wm_lcd.h"
#define RTC_CLK (32000UL)
/**
* @brief Initialize LCD Frame Counter
* @param[in] freq LCD reference refresh frequency in Hz that will be used
*/
void tls_lcd_fresh_ratio(uint16_t freq)
{
uint8_t com_num;
if (freq == 0)
{
freq = 60;
}
com_num = tls_bitband_read(HR_LCD_CR, LCD_CR_MODE_Pos) ? 4 : 8;
LCD->FRAMECNT = RTC_CLK/(com_num * 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
*
* @param[in] mode
* when one max configuration is 4x20, when zero max configuration is 8x16
*
*/
void tls_lcd_seg_set(int com, int bit, int on_off)
{
int mode;
/** get the mode congfig when one max configuration is 4x20, when zero max configuration is 8x16 */
mode = tls_bitband_read(HR_LCD_CR, LCD_CR_MODE_Pos);
if (!mode && (com < 0 || com > 7) && (bit < 0 || bit > 15))
{
return ;
}
if (mode && (com < 0 || com > 3) && (bit < 0 || bit > 19))
{
return ;
}
switch(com)
{
/** COM0 */
case 0:
tls_bitband_write(HR_LCD_COM0_1_SEG, bit, on_off);
break;
/** COM1 */
case 1:
if (mode)
tls_bitband_write(HR_LCD_COM2_3_SEG, bit, on_off);
else
{
bit += 16;
tls_bitband_write(HR_LCD_COM0_1_SEG, bit, on_off);
}
break;
/** COM2 */
case 2:
if (mode)
tls_bitband_write(HR_LCD_COM4_5_SEG, bit, on_off);
else
tls_bitband_write(HR_LCD_COM2_3_SEG, bit, on_off);
break;
/** COM3 */
case 3:
if (mode)
tls_bitband_write(HR_LCD_COM6_7_SEG, bit, on_off);
else
{
bit += 16;
tls_bitband_write(HR_LCD_COM2_3_SEG, bit, on_off);
}
break;
/** COM4 */
case 4:
tls_bitband_write(HR_LCD_COM4_5_SEG, bit, on_off);
break;
/** COM5 */
case 5:
bit += 16;
tls_bitband_write(HR_LCD_COM4_5_SEG, bit, on_off);
break;
/** COM6 */
case 6:
tls_bitband_write(HR_LCD_COM6_7_SEG, bit, on_off);
break;
/** COM7 */
case 7:
bit += 16;
tls_bitband_write(HR_LCD_COM6_7_SEG, bit, on_off);
break;
default:
break;
}
}
/**
* @brief enable or disable the LCD module gpio
*
* @param[in] the config value per bit for one of LCD gpios, set 1 gpio output enable ,0 output disabled
*
*/
void tls_lcd_io_config(unsigned int val)
{
tls_reg_write32(HR_LCD_IO_EN, val);
}
/**
* @brief
* select the voltage of LCD module
*
*/
void tls_lcd_vlcd_sel(LCD_VlcdDef vlcd)
{
LCD->CTRL &= ~LCD_VLCD_MASK;
LCD->CTRL |= vlcd;
}
/**
* @brief
* set the duty of LCD module
*
*/
void tls_lcd_duty_set(LCD_DutyDef duty)
{
LCD->CTRL &= ~LCD_DUTY_MASK;
LCD->CTRL |= duty;
}
/**
* @brief
* set the bias of LCD module
*
*/
void tls_lcd_bias_set(LCD_BiasDef bias)
{
LCD->CTRL &= ~LCD_BIAS_MASK;
LCD->CTRL |= bias;
}
/**
* @brief
* initialize the lcd module
*
*/
void tls_lcd_init(tls_lcd_options_t *opts)
{
LCD->CTRL = 0;
LCD->CTRL = opts->mode | opts->bias | opts->duty | opts->vlcd | (1 << 12);
tls_lcd_fresh_ratio(opts->fresh_rate);
TLS_LCD_ENABLE(opts->enable);
TLS_LCD_POWERDOWM(0);
}
+332
View File
@@ -0,0 +1,332 @@
#include <string.h>
#include "wm_debug.h"
#include "wm_regs.h"
#include "wm_irq.h"
#include "wm_pwm.h"
#include "wm_gpio.h"
#include "wm_timer.h"
#include "wm_cpu.h"
#include "tls_common.h"
#include "wm_pmu.h"
#include "wm_wifi.h"
struct pmu_irq_context {
tls_pmu_irq_callback callback;
void *arg;
};
static struct pmu_irq_context pmu_timer1_context = {0};
static struct pmu_irq_context pmu_timer0_context = {0};
static struct pmu_irq_context pmu_gpio_wake_context = {0};
static struct pmu_irq_context pmu_sdio_wake_context = {0};
void PMU_TIMER1_IRQHandler(void)
{
if (tls_reg_read32(HR_PMU_INTERRUPT_SRC) & BIT(1)) /* timer1 interrupt */
{
tls_reg_write32(HR_PMU_INTERRUPT_SRC, tls_reg_read32(HR_PMU_INTERRUPT_SRC) | BIT(1)); /* clear timer1 interrupt */
if (NULL != pmu_timer1_context.callback)
pmu_timer1_context.callback(pmu_timer1_context.arg);
}
return;
}
void PMU_TIMER0_IRQHandler(void)
{
if (tls_reg_read32(HR_PMU_INTERRUPT_SRC) & BIT(0)) /* timer0 interrupt */
{
tls_reg_write32(HR_PMU_INTERRUPT_SRC, tls_reg_read32(HR_PMU_INTERRUPT_SRC) | BIT(0)); /* clear timer0 interrupt */
tls_reg_write32(HR_PMU_TIMER0, tls_reg_read32(HR_PMU_TIMER0) & (~BIT(16)));
if (NULL != pmu_timer0_context.callback)
pmu_timer0_context.callback(pmu_timer0_context.arg);
}
return;
}
void PMU_GPIO_WAKE_IRQHandler(void)
{
if (tls_reg_read32(HR_PMU_INTERRUPT_SRC) & BIT(2)) /* gpio wake interrupt */
{
tls_reg_write32(HR_PMU_INTERRUPT_SRC, tls_reg_read32(HR_PMU_INTERRUPT_SRC) | BIT(2)); /* clear gpio wake interrupt */
if (NULL != pmu_gpio_wake_context.callback)
pmu_gpio_wake_context.callback(pmu_gpio_wake_context.arg);
}
return;
}
void PMU_SDIO_WAKE_IRQHandler(void)
{
if (tls_reg_read32(HR_PMU_INTERRUPT_SRC) & BIT(3)) /* sdio wake interrupt */
{
tls_reg_write32(HR_PMU_INTERRUPT_SRC, tls_reg_read32(HR_PMU_INTERRUPT_SRC) | BIT(3)); /* clear sdio wake interrupt */
if (NULL != pmu_sdio_wake_context.callback)
pmu_sdio_wake_context.callback(pmu_sdio_wake_context.arg);
}
return;
}
/**
* @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)
{
pmu_timer1_context.callback = callback;
pmu_timer1_context.arg = arg;
tls_irq_enable(PMU_TIMER1_INT);
return;
}
/**
* @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)
{
pmu_timer0_context.callback = callback;
pmu_timer0_context.arg = arg;
tls_irq_enable(PMU_TIMER0_INT);
return;
}
/**
* @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)
{
pmu_gpio_wake_context.callback = callback;
pmu_gpio_wake_context.arg = arg;
tls_irq_enable(PMU_GPIO_WAKEUP_INT);
return;
}
/**
* @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)
{
pmu_sdio_wake_context.callback = callback;
pmu_sdio_wake_context.arg = arg;
tls_irq_enable(PMU_SDIO_WAKEUP_INT);
return;
}
/**
* @brief This function is used to select pmu clk
*
* @param[in] bypass pmu clk whether or not use bypass mode
* ohter pmu clk use 32K by 40MHZ
* 0 pmu clk 32K by calibration circuit
*
* @return None
*
* @note None
*/
void tls_pmu_clk_select(u8 bypass)
{
u32 val;
val = tls_reg_read32(HR_PMU_PS_CR);
if(bypass)
{
val |= BIT(3);
}
else
{
val &= ~BIT(3);
}
val |= BIT(2);
tls_reg_write32(HR_PMU_PS_CR, val);
}
/**
* @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)
{
u32 val;
val = second;
val |= BIT(16);
tls_reg_write32(HR_PMU_TIMER0, val);
}
/**
* @brief This function is used to stop pmu timer0
*
* @param None
*
* @return None
*
* @note None
*/
void tls_pmu_timer0_stop(void)
{
u32 val;
val = tls_reg_read32(HR_PMU_TIMER0);
val &= ~BIT(16);
tls_reg_write32(HR_PMU_TIMER0, val);
}
/**
* @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)
{
u32 val;
//默认采用最小单位1ms
val = (msec-1) | (1<<16) | (1<<17) | (0<<20) | (0<<24);
tls_reg_write32(HR_PMU_TIMER1, val);
}
/**
* @brief This function is used to stop pmu timer1
*
* @param None
*
* @return None
*
* @note None
*/
void tls_pmu_timer1_stop(void)
{
u32 val;
val = tls_reg_read32(HR_PMU_TIMER1);
val &= ~BIT(16);
val &= ~BIT(17);
tls_reg_write32(HR_PMU_TIMER1, val);
}
/**
* @brief This function is used to start pmu goto standby
*
* @param None
*
* @return None
*
* @note None
*/
void tls_pmu_standby_start(void)
{
u32 val;
tls_irq_enable(PMU_GPIO_WAKEUP_INT); //默认打开中断为了清楚IO唤醒的中断标记
val = tls_reg_read32(HR_PMU_PS_CR);
TLS_DBGPRT_INFO("goto standby here\n");
val |= BIT(0);
tls_reg_write32(HR_PMU_PS_CR, val);
}
/**
* @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)
{
tls_reg_write32(HR_CLK_BASE_ADDR, tls_reg_read32(HR_CLK_BASE_ADDR) & ~(devices));
return;
}
/**
* @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)
{
tls_reg_write32(HR_CLK_BASE_ADDR, tls_reg_read32(HR_CLK_BASE_ADDR) | devices);
return;
}
+919
View File
@@ -0,0 +1,919 @@
/**
* @file wm_pwm.c
*
* @brief pwm driver module
*
* @author dave
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
*/
#include <string.h>
#include "wm_debug.h"
#include "wm_regs.h"
#include "wm_irq.h"
#include "wm_pwm.h"
#include "wm_gpio.h"
#include "wm_cpu.h"
#include "tls_common.h"
typedef void (*pwm_irq_callback)(void);
static pwm_irq_callback pwm_callback;
void PWM_IRQHandler(void)
{
if (pwm_callback)
pwm_callback();
}
/**
* @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))
{
pwm_callback = callback;
tls_irq_enable(PWM_INT);
}
/**
* @brief This function is used to set duty ratio
*
* @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)
{
u32 temp = 0;
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
{
TLS_DBGPRT_ERR("duty param err\n");
return WM_FAILED;
}
if (duty == 0)
{
tls_pwm_stop(channel);
return WM_SUCCESS;
}
if (4 == channel)
{
temp = tls_reg_read32(HR_PWM_CH4_REG2) & ~0x0000FF00;
temp |= (duty << 8);
tls_reg_write32(HR_PWM_CH4_REG2, temp); /* duty radio */
}
else
{
temp = tls_reg_read32(HR_PWM_CMPDAT) & ~(0xFF << channel * 8);
temp |= (duty << (channel * 8));
tls_reg_write32(HR_PWM_CMPDAT, temp); /* duty radio */
}
return WM_SUCCESS;
}
/**
* @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)
{
u32 temp = 0;
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
{
TLS_DBGPRT_ERR("freq param err\n");
return WM_FAILED;
}
if (4 == channel)
{
temp = tls_reg_read32(HR_PWM_CH4_REG1) & ~0xFFFF0000;
temp |= (clkdiv << 16);
tls_reg_write32(HR_PWM_CH4_REG1, temp);/* clock divider */
temp = tls_reg_read32(HR_PWM_CH4_REG1) & ~0x0000FF00;
temp |= (period << 8);
tls_reg_write32(HR_PWM_CH4_REG1, temp); /* the number of the counting clock cycle */
}
else
{
temp = tls_reg_read32(HR_PWM_CLKDIV01 + (channel / 2) * 4) & ~(0xFFFF << ((channel % 2) * 16));
temp |= (clkdiv << ((channel % 2) * 16));
tls_reg_write32(HR_PWM_CLKDIV01 + (channel / 2) * 4, temp);/* clock divider */
temp = tls_reg_read32(HR_PWM_PERIOD) & ~(0xFF << channel * 8);
temp |= (period << (channel * 8));
tls_reg_write32(HR_PWM_PERIOD, temp);/* the number of the counting clock cycle */
}
return WM_SUCCESS;
}
/**
* @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)
{
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
return WM_FAILED;
if (WM_PWM_OUT_MODE_BRAKE == mode)
tls_reg_write32(HR_PWM_BRKCTL, tls_reg_read32(HR_PWM_BRKCTL) | BIT(11 + channel));/* the brake mode */
else if (WM_PWM_OUT_MODE_ALLSYC == mode)
{
if (channel != 0)
return WM_FAILED;
tls_reg_write32(HR_PWM_BRKCTL, tls_reg_read32(HR_PWM_BRKCTL) & ~0xF800); /* disable the brake mode */
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) | BIT(6)); /* enable the all synchronous mode mode */
}
else if (WM_PWM_OUT_MODE_2SYC == mode)
{
if (channel != 0 && channel != 2)
return WM_FAILED;
tls_reg_write32(HR_PWM_BRKCTL, tls_reg_read32(HR_PWM_BRKCTL) & ~(0x1800<<channel)); /* disable the brake mode */
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & ~BIT(6)); /* disable the all synchronous mode mode */
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) | BIT(14 + channel / 2)); /* enable the two channel synchronous mode */
}
else if (WM_PWM_OUT_MODE_MC == mode)
{
if (channel != 0 && channel != 2)
return WM_FAILED;
tls_reg_write32(HR_PWM_BRKCTL, tls_reg_read32(HR_PWM_BRKCTL) & ~(0x1800<<channel));/* disable the brake mode */
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & ~BIT(6)); /* disable the all synchronous mode mode */
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & ~BIT(14 + channel / 2)); /* disable the two channel synchronous mode */
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) | BIT(0 + channel / 2)); /* enable the complementary mode */
}
else if(WM_PWM_OUT_MODE_INDPT == mode)
{
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(6)));
if (channel != 4 )
{
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(0 + channel / 2)));
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(14 + channel / 2)));
}
tls_reg_write32(HR_PWM_BRKCTL, tls_reg_read32(HR_PWM_BRKCTL) & (~BIT(11 + channel))); /* enable the independent mode */
}
else
return WM_FAILED;
return WM_SUCCESS;
}
/**
* @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)
{
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
return WM_FAILED;
if (4 == channel)
{
if (WM_PWM_CNT_TYPE_EDGE_ALLGN_CAP == cnt_type)
{
tls_reg_write32(HR_PWM_CH4_REG2, tls_reg_read32(HR_PWM_CH4_REG2) & (~BIT(4)));
tls_reg_write32(HR_PWM_CH4_REG2, tls_reg_read32(HR_PWM_CH4_REG2) & (~BIT(3)));
}
if (WM_PWM_CNT_TYPE_EDGE_ALIGN_OUT == cnt_type)
{
tls_reg_write32(HR_PWM_CH4_REG2, tls_reg_read32(HR_PWM_CH4_REG2) & (~BIT(4)));
tls_reg_write32(HR_PWM_CH4_REG2, tls_reg_read32(HR_PWM_CH4_REG2) | BIT(3));
}
else if (WM_PWM_CNT_TYPE_CENTER_ALIGN == cnt_type)
{
tls_reg_write32(HR_PWM_CH4_REG2, tls_reg_read32(HR_PWM_CH4_REG2) | BIT(4));
tls_reg_write32(HR_PWM_CH4_REG2, tls_reg_read32(HR_PWM_CH4_REG2) & (~BIT(3)));
}
}
else
{
if (WM_PWM_CNT_TYPE_EDGE_ALLGN_CAP == cnt_type && channel == 0)
{
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(17)));
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(16)));
}
if (WM_PWM_CNT_TYPE_EDGE_ALIGN_OUT == cnt_type)
{
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(17 + channel * 2)));
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) | BIT(16 + channel * 2));
}
else if (WM_PWM_CNT_TYPE_CENTER_ALIGN == cnt_type)
{
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) | BIT(17 + channel * 2));
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(16 + channel * 2)));
}
else
return WM_FAILED;
}
return WM_SUCCESS;
}
/**
* @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)
{
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
return WM_FAILED;
if (4 == channel)
{
if (WM_PWM_LOOP_TYPE_LOOP == loop_mode)
tls_reg_write32(HR_PWM_CH4_REG2, tls_reg_read32(HR_PWM_CH4_REG2) | BIT(1));
else
tls_reg_write32(HR_PWM_CH4_REG2, tls_reg_read32(HR_PWM_CH4_REG2) & (~BIT(1)));
}
else
{
if (WM_PWM_LOOP_TYPE_LOOP == loop_mode)
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) | BIT(8 + channel));
else
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(8 + channel)));
}
return WM_SUCCESS;
}
/**
* @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)
{
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
return WM_FAILED;
if (4 == channel)
{
if (ENABLE == en)
tls_reg_write32(HR_PWM_CH4_REG2, tls_reg_read32(HR_PWM_CH4_REG2) | BIT(0));
else
tls_reg_write32(HR_PWM_CH4_REG2, tls_reg_read32(HR_PWM_CH4_REG2) & (~BIT(0)));
}
else
{
if (ENABLE == en)
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) | BIT(2 + channel));
else
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(2 + channel)));
}
return WM_SUCCESS;
}
/**
* @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)
{
u32 temp = 0;
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
return WM_FAILED;
if (4 == channel)
{
temp = tls_reg_read32(HR_PWM_CH4_REG1) & ~0x000000FF;
temp |= pnum;
tls_reg_write32(HR_PWM_CH4_REG1, temp);
}
else
{
temp = tls_reg_read32(HR_PWM_PNUM) & ~(0xFF << channel * 8);
temp |= (pnum << (channel * 8));
tls_reg_write32(HR_PWM_PNUM, temp);
}
return WM_SUCCESS;
}
/**
* @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)
{
if(channel != 0 && channel != 4)
return WM_FAILED;
if (4 == channel)
{
if (ENABLE == en)
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) & (~BIT(2)));
else
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) | BIT(2));
}
else
{
if (ENABLE == en)
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(12)));
else
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) | BIT(12));
}
return WM_SUCCESS;
}
/**
* @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)
{
u32 temp = 0;
if ((channel !=0 && channel != 2) || dtclkdiv > 3)
return WM_FAILED;
if(ENABLE == dten)
{
temp = tls_reg_read32(HR_PWM_DTCTL) & ~0x00030000;
temp |= (dtclkdiv<<16);
tls_reg_write32(HR_PWM_DTCTL, temp);/* dead zone clock divider */
if (channel == 0 || channel == 1)
{
temp = tls_reg_read32(HR_PWM_DTCTL) & ~0x000000FF;
temp |= dtcnt;
tls_reg_write32(HR_PWM_DTCTL, temp);/* the number of the counting clock cycle */
tls_reg_write32(HR_PWM_DTCTL, tls_reg_read32(HR_PWM_CTL) | BIT(20)); /* whether enalbe the deat time */
}
else if (channel == 2 || channel == 3)
{
temp = tls_reg_read32(HR_PWM_DTCTL) & ~0x0000FF00;
temp |= (dtcnt<<8);
tls_reg_write32(HR_PWM_DTCTL, temp);/* the number of the counting clock cycle */
tls_reg_write32(HR_PWM_DTCTL, tls_reg_read32(HR_PWM_CTL) | BIT(21)); /* whether enalbe the deat time */
}
}
else
{
if (channel == 0 || channel == 1)
{
tls_reg_write32(HR_PWM_DTCTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(20))); /* whether enalbe the deat time */
}
else if (channel == 2 || channel == 3)
{
tls_reg_write32(HR_PWM_DTCTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(21))); /* whether enalbe the deat time */
}
}
return WM_SUCCESS;
}
/**
* @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)
{
if (channel != 0 && channel != 4)
return WM_FAILED;
if (channel == 0)
{
if (ENABLE == en)
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) | BIT(25));
else
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(25)));
}
else
{
if (ENABLE == en)
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) | BIT(0));
else
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) & (~BIT(0)));
}
return WM_SUCCESS;
}
/**
* @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)
{
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
return WM_FAILED;
if (ENABLE == en)
{
if (WM_PWM_BRAKE_OUT_HIGH == brok)
tls_reg_write32(HR_PWM_BRKCTL, tls_reg_read32(HR_PWM_BRKCTL) | BIT(3+channel));
else
tls_reg_write32(HR_PWM_BRKCTL, tls_reg_read32(HR_PWM_BRKCTL) & (~BIT(3+channel)));
tls_reg_write32(HR_PWM_BRKCTL, tls_reg_read32(HR_PWM_BRKCTL) | BIT(11+channel));
}
else
{
tls_reg_write32(HR_PWM_BRKCTL, tls_reg_read32(HR_PWM_BRKCTL) & (~BIT(11+channel)));
}
return WM_SUCCESS;
}
/**
* @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)
{
if (channel != 0 && channel != 4)
return WM_FAILED;
if (channel == 0)
{
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) | BIT(24));
}
else
{
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) | BIT(1));
}
return WM_SUCCESS;
}
/**
* @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)
{
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
return WM_FAILED;
if (4 == channel)
{
if (en)
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) | BIT(4));
else
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) & (~BIT(4)));
}
else
{
if (en)
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) | BIT(channel));
else
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) & (~BIT(channel)));
}
return WM_SUCCESS;
}
/**
* @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)
{
if (channel != 0 && channel != 4)
return WM_FAILED;
if (0 == channel)
{
if (WM_PWM_CAP_RISING_FALLING_EDGE_INT == int_type)
{
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) | BIT(5));
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) | BIT(6));
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) & (~BIT(7)));
}
else if (WM_PWM_CAP_RISING_EDGE_INT == int_type)
{
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) | BIT(5));
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) & (~BIT(6)));
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) & (~BIT(7)));
}
else if (WM_PWM_CAP_FALLING_EDGE_INT == int_type)
{
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) | BIT(6));
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) & (~BIT(5)));
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) & (~BIT(7)));
}
else if(WM_PWM_CAP_DMA_INT == int_type)
{
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) | BIT(7));
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) & (~BIT(5)));
tls_reg_write32(HR_PWM_INTEN, tls_reg_read32(HR_PWM_INTEN) & (~BIT(6)));
}
}
else if (4 == channel)
{
if (WM_PWM_CAP_RISING_FALLING_EDGE_INT == int_type)
{
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) | BIT(8));
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) | BIT(9));
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) & (~BIT(10)));
}
else if (WM_PWM_CAP_RISING_EDGE_INT == int_type)
{
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) | BIT(8));
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) & (~BIT(9)));
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) & (~BIT(10)));
}
else if (WM_PWM_CAP_FALLING_EDGE_INT == int_type)
{
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) | BIT(9));
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) & (~BIT(8)));
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) & (~BIT(10)));
}
else if(WM_PWM_CAP_DMA_INT == int_type)
{
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) | BIT(10));
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) & (~BIT(8)));
tls_reg_write32(HR_PWM_CAP2CTL, tls_reg_read32(HR_PWM_CAP2CTL) & (~BIT(9)));
}
}
return WM_SUCCESS;
}
/**
* @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)
{
int ret=0;
int pwm_status = 0;
if (pwm_param.channel > (PWM_CHANNEL_MAX_NUM - 1))
return WM_FAILED;
if(tls_reg_read32(HR_PWM_CTL) & BIT(27 + pwm_param.channel))
{
tls_pwm_stop(pwm_param.channel);
pwm_status = 1;
}
/* set output mode */
ret = tls_pwm_out_mode_config(pwm_param.channel, pwm_param.mode);
if (ret!=WM_SUCCESS)
return WM_FAILED;
if (WM_PWM_OUT_MODE_MC == pwm_param.mode)
{
/* set dead time */
ret = tls_pwm_deadzone_config(pwm_param.channel, pwm_param.dten, pwm_param.dtclkdiv, pwm_param.dtcnt);
if (ret!=WM_SUCCESS)
return WM_FAILED;
}
/* set count type */
tls_pwm_cnt_type_config(pwm_param.channel, pwm_param.cnt_type);
/* set period value and duty radio */
tls_pwm_freq_config(pwm_param.channel, pwm_param.clkdiv, pwm_param.period);
tls_pwm_duty_config(pwm_param.channel, pwm_param.duty);
/* set cycle type */
tls_pwm_loop_mode_config(pwm_param.channel, pwm_param.loop_type);
/* set output whether is inverse */
tls_pwm_out_inverse_cmd(pwm_param.channel, pwm_param.inverse_en);
/* set period number of generating */
tls_pwm_stoptime_by_period_config(pwm_param.channel, pwm_param.pnum);
/* set interrupt of period number whether is enable */
tls_pwm_stoptime_irq_cmd(pwm_param.channel, pwm_param.pnum_int);
/* set output status */
if (pwm_param.channel == 0 || pwm_param.channel == 4)
tls_pwm_output_en_cmd(pwm_param.channel, WM_PWM_OUT_EN_STATE_OUT);
if (pwm_param.mode == WM_PWM_OUT_MODE_ALLSYC && pwm_param.channel == 0)
tls_pwm_output_en_cmd(4, WM_PWM_OUT_EN_STATE_OUT);
if(pwm_status)
{
tls_pwm_start(pwm_param.channel);
}
return WM_SUCCESS;
}
/**
* @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)
{
if (channel != 0 && channel != 4)
return WM_FAILED;
/* set clock divider and period value */
tls_pwm_freq_config(channel, clkdiv, 0xFF);
/* set input of capture mode whether is inverse */
tls_pwm_capture_inverse_cmd(channel, inverse_en);
/* set the capture mode */
tls_pwm_capture_mode_config(channel);
/* set count type (only edge alignment in the capture mode) */
tls_pwm_cnt_type_config(channel, WM_PWM_CNT_TYPE_EDGE_ALLGN_CAP);
/* set output status */
tls_pwm_output_en_cmd(channel, WM_PWM_OUT_EN_STATE_TRI);
/* set cycle mode (must be set int the capture mode) */
tls_pwm_loop_mode_config(channel, WM_PWM_LOOP_TYPE_LOOP);
/* set interrupt type */
tls_pwm_capture_irq_type_config(channel, int_type);
return WM_SUCCESS;
}
/**
* @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)
{
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
return WM_FAILED;
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) | BIT(27 + channel)); /* start counter */
return WM_SUCCESS;
}
/**
* @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)
{
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
return WM_FAILED;
tls_reg_write32(HR_PWM_CTL, tls_reg_read32(HR_PWM_CTL) & (~BIT(27 + channel)));/* stop counter */
return WM_SUCCESS;
}
/**
* @brief This function is used to set pwm's frequency
*
* @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)
{
u16 clkdiv=0;
tls_sys_clk sysclk;
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
return;
tls_sys_clk_get(&sysclk);
clkdiv = sysclk.apbclk*UNIT_MHZ/256/freq;
tls_pwm_stop(channel);
tls_pwm_freq_config(channel, clkdiv, 255);
tls_pwm_start(channel);
}
/**
* @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)
{
if(channel > (PWM_CHANNEL_MAX_NUM - 1))
return;
tls_pwm_duty_config(channel, duty);
}
/**
* @brief This function is used to initial pwm
*
* @param[in] channel pwm channel, range from 0 to 4
* @param[in] freq freq range from 1 to 156250
* @param[in] duty duty range from 0 to 255
* @param[in] pnum period num,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)
{
pwm_init_param pwm_param;
int ret=-1;
tls_sys_clk sysclk;
tls_sys_clk_get(&sysclk);
memset(&pwm_param, 0, sizeof(pwm_init_param));
pwm_param.period = 255;
pwm_param.cnt_type = WM_PWM_CNT_TYPE_EDGE_ALIGN_OUT;
pwm_param.loop_type = WM_PWM_LOOP_TYPE_LOOP;
pwm_param.mode = WM_PWM_OUT_MODE_INDPT;
pwm_param.inverse_en = DISABLE;
pwm_param.pnum = pnum;
pwm_param.pnum_int = DISABLE;
pwm_param.duty = duty;
pwm_param.channel = channel;
pwm_param.clkdiv = sysclk.apbclk*UNIT_MHZ/256/freq;
// printf("clkdiv:%d\n", pwm_param.clkdiv);
ret = tls_pwm_out_init(pwm_param);
// tls_pwm_start(channel);
return ret;
}
/**
* @brief This function is used to initial pwm
*
* @param[in] channel pwm channel, range from 0 to 4
* @param[in] freq freq range from 1 to 156250
* @param[in] duty duty range from 0 to 255
* @param[in] pnum period num,range from 0 to 255
*
* @retval WM_SUCCESS success
* @retval WM_FAILED failed
*
* @note None
*/
int tls_pwm_ineverse_init(u8 channel,u32 freq, u8 duty, u8 pnum)
{
pwm_init_param pwm_param;
int ret=-1;
tls_sys_clk sysclk;
tls_sys_clk_get(&sysclk);
memset(&pwm_param, 0, sizeof(pwm_init_param));
pwm_param.period = 255;
pwm_param.cnt_type = WM_PWM_CNT_TYPE_EDGE_ALIGN_OUT;
pwm_param.loop_type = WM_PWM_LOOP_TYPE_LOOP;
pwm_param.mode = WM_PWM_OUT_MODE_INDPT;
pwm_param.inverse_en = ENABLE;
pwm_param.pnum = pnum;
pwm_param.pnum_int = DISABLE;
pwm_param.duty = duty;
pwm_param.channel = channel;
pwm_param.clkdiv = sysclk.apbclk*UNIT_MHZ/256/freq;
// printf("clkdiv:%d\n", pwm_param.clkdiv);
ret = tls_pwm_out_init(pwm_param);
// tls_pwm_start(channel);
return ret;
}
+170
View File
@@ -0,0 +1,170 @@
/**
* @file wm_rtc.c
*
* @brief rtc Driver Module
*
* @author dave
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "wm_regs.h"
#include "wm_rtc.h"
#include "wm_irq.h"
#include "tls_common.h"
struct rtc_irq_context {
tls_rtc_irq_callback callback;
void *arg;
};
static struct rtc_irq_context rtc_context = {0};
/**
* @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)
{
int ctrl1 = 0;
int ctrl2 = 0;
ctrl2 = tls_reg_read32(HR_PMU_RTC_CTRL2); /* disable */
ctrl2 &= ~(1 << 16);
tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2);
ctrl1 |= tblock->tm_sec;
ctrl1 |= tblock->tm_min << 8;
ctrl1 |= tblock->tm_hour << 16;
ctrl1 |= tblock->tm_mday << 24;
tls_reg_write32(HR_PMU_RTC_CTRL1, ctrl1);
ctrl2 = 0;
ctrl2 |= tblock->tm_mon;
ctrl2 |= tblock->tm_year << 8;
tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2);
ctrl2 = tls_reg_read32(HR_PMU_RTC_CTRL2); /* enable */
ctrl2 |= (1 << 16);
tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2);
}
/**
* @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)
{
int ctrl1 = 0;
int ctrl2 = 0;
ctrl1 = tls_reg_read32(HR_PMU_RTC_CTRL1);
ctrl2 = tls_reg_read32(HR_PMU_RTC_CTRL2);
tblock->tm_year = ((int)((int)ctrl2 & 0x00007f00) >> 8);
tblock->tm_mon = (ctrl2 & 0x0000000f);
tblock->tm_mday = (ctrl1 & 0x1f000000) >> 24;
tblock->tm_hour = (ctrl1 & 0x001f0000) >> 16;
tblock->tm_min = (ctrl1 & 0x00003f00) >> 8;
tblock->tm_sec = ctrl1 & 0x0000003f;
}
void PMU_RTC_IRQHandler(void)
{
if (tls_reg_read32(HR_PMU_INTERRUPT_SRC) & BIT(5)) /* rtc interrupt */
{
tls_reg_write32(HR_PMU_INTERRUPT_SRC, BIT(5)); /* clear rtc interrupt */
if (NULL != rtc_context.callback)
rtc_context.callback(rtc_context.arg);
}
return;
}
/**
* @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 not need clear interrupt flag.
* rtc 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_rtc_isr_register(tls_rtc_irq_callback callback, void *arg)
{
rtc_context.callback = callback;
rtc_context.arg = arg;
// tls_reg_write32(HR_PMU_INTERRUPT_MASK, tls_reg_read32(HR_PMU_INTERRUPT_MASK) & (~BIT(4)));
tls_irq_enable(PMU_RTC_INT);
return;
}
/**
* @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)
{
int ctrl1 = 0;
int ctrl2 = 0;
tls_irq_enable(PMU_RTC_INT);
ctrl1 |= tblock->tm_sec;
ctrl1 |= tblock->tm_min << 8;
ctrl1 |= tblock->tm_hour << 16;
ctrl1 |= tblock->tm_mday << 24;
ctrl2 |= tblock->tm_mon;
ctrl2 |= tblock->tm_year << 8;
tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2 | BIT(16));
tls_reg_write32(HR_PMU_RTC_CTRL1, ctrl1 | BIT(31));/* must set the enable */
return;
}
/**
* @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)
{
tls_irq_disable(PMU_RTC_INT);
tls_reg_write32(HR_PMU_RTC_CTRL1, tls_reg_read32(HR_PMU_RTC_CTRL1) & (~BIT(31)));
return;
}
File diff suppressed because it is too large Load Diff
+303
View File
@@ -0,0 +1,303 @@
/*****************************************************************************
*
* File Name : wm_spi_hal.h
*
* Description: host spi Driver Module
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
* All rights reserved.
*
* Author : dave
*
* Date : 2014-6-6
*****************************************************************************/
#include "wm_regs.h"
#include "list.h"
#include "wm_hostspi.h"
#include "wm_cpu.h"
static __inline void spi_set_mode(u8 mode);
static __inline void spi_set_mode(u8 mode)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_SPICFG_REG);
switch (mode) {
case TLS_SPI_MODE_0:
reg_val &= ~(0x03U);
reg_val |= (SPI_SET_CPOL(0) | SPI_SET_CPHA(0));
break;
case TLS_SPI_MODE_1:
reg_val &= ~(0x03U);
reg_val |= (SPI_SET_CPOL(0) | SPI_SET_CPHA(1));
break;
case TLS_SPI_MODE_2:
reg_val &= ~(0x03U);
reg_val |= (SPI_SET_CPOL(1) | SPI_SET_CPHA(0));
break;
case TLS_SPI_MODE_3:
reg_val &= ~(0x03U);
reg_val |= (SPI_SET_CPOL(1) | SPI_SET_CPHA(1));
break;
default:
break;
}
tls_reg_write32(HR_SPI_SPICFG_REG, reg_val);
}
static __inline void spi_set_endian(u8 endian)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_SPICFG_REG);
if (endian == 0) {
reg_val &= ~(0x01U << 3);
reg_val |= SPI_LITTLE_ENDIAN;
} else if(endian == 1) {
reg_val &= ~(0x01U << 3);
reg_val |= SPI_BIG_ENDIAN;
}
tls_reg_write32(HR_SPI_SPICFG_REG, reg_val);
}
static __inline void spi_set_chipselect_mode(u8 cs_active)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_CHCFG_REG);
if (cs_active == 0) {
reg_val &= ~(0x01U << 2);
reg_val |= SPI_CS_LOW;
} else if(cs_active == 1) {
reg_val &= ~(0x01U << 2);
reg_val |= SPI_CS_HIGH;
}
tls_reg_write32(HR_SPI_CHCFG_REG, reg_val);
}
static __inline void spi_clear_fifo(void)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_CHCFG_REG);
reg_val |= SPI_CLEAR_FIFOS;
tls_reg_write32(HR_SPI_CHCFG_REG, reg_val);
}
static __inline void spi_set_rx_channel(u8 on_off)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_CHCFG_REG);
if (on_off == 0) {
reg_val &= ~(0x01U << 20);
reg_val |= SPI_RX_CHANNEL_OFF;
} else if(on_off == 1) {
reg_val &= ~(0x01U << 20);
reg_val |= SPI_RX_CHANNEL_ON;
}
tls_reg_write32(HR_SPI_CHCFG_REG, reg_val);
}
static __inline void spi_set_tx_channel(u8 on_off)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_CHCFG_REG);
if (on_off == 0) {
reg_val &= ~(0x01U << 19);
reg_val |= SPI_TX_CHANNEL_OFF;
} else if(on_off == 1) {
reg_val &= ~(0x01U << 19);
reg_val |= SPI_TX_CHANNEL_ON;
}
tls_reg_write32(HR_SPI_CHCFG_REG, reg_val);
}
static __inline void spi_set_sclk_length(u16 sclk_num, u8 invalid_rx_sclk_num)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_CHCFG_REG);
reg_val &= ~((0xffU << 23) | (0xffff << 3));
reg_val |= SPI_VALID_CLKS_NUM(sclk_num) | SPI_RX_INVALID_BITS(invalid_rx_sclk_num);
tls_reg_write32(HR_SPI_CHCFG_REG, reg_val);
}
static __inline void spi_force_cs_out(u8 enable)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_CHCFG_REG);
if (enable) {
reg_val |= SPI_FORCE_SPI_CS_OUT;
} else {
reg_val &= ~SPI_FORCE_SPI_CS_OUT;
}
tls_reg_write32(HR_SPI_CHCFG_REG, reg_val);
}
static __inline void spi_sclk_start(void)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_CHCFG_REG);
reg_val |= SPI_START;
tls_reg_write32(HR_SPI_CHCFG_REG, reg_val);
}
static __inline void spi_set_sclk(u32 fclk)
{
u32 reg_val;
tls_sys_clk sysclk;
tls_sys_clk_get(&sysclk);
reg_val = tls_reg_read32(HR_SPI_CLKCFG_REG);
reg_val &= ~(0xffffU);
reg_val |= sysclk.apbclk*UNIT_MHZ/(fclk*2) - 1;
tls_reg_write32(HR_SPI_CLKCFG_REG, reg_val);
}
static __inline void spi_set_tx_trigger_level(u8 level)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_MODECFG_REG);
reg_val &= ~(0x07U << 2);
reg_val |= SPI_TX_TRIGGER_LEVEL(level);
tls_reg_write32(HR_SPI_MODECFG_REG, reg_val);
}
static __inline void spi_set_rx_trigger_level(u8 level)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_MODECFG_REG);
reg_val &= ~(0x07U << 6);
reg_val |= SPI_RX_TRIGGER_LEVEL(level);
tls_reg_write32(HR_SPI_MODECFG_REG, reg_val);
}
static __inline void spi_set_timeout(u32 timeout, u8 enable)
{
u32 reg_val;
reg_val = SPI_TIME_OUT(timeout);
reg_val |= enable ? SPI_TIMER_EN : 0;
tls_reg_write32(HR_SPI_TIMEOUT_REG, reg_val);
}
static __inline void spi_get_status(u8 *busy, u8 *rx_fifo_level, u8 *tx_fifo_level)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_STATUS_REG);
if (busy) {*busy = SPI_IS_BUSY(reg_val);}
if (rx_fifo_level) {*rx_fifo_level = SPI_GET_RX_FIFO_CNT(reg_val);}
if (tx_fifo_level) {*tx_fifo_level = 32 - SPI_GET_TX_FIFO_CNT(reg_val);}
}
static __inline u32 spi_int_mask(void)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_INT_MASK_REG);
return reg_val & SPI_INT_MASK_ALL;
}
static __inline void spi_mask_int(u32 mask)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_INT_MASK_REG);
reg_val |= mask & SPI_INT_MASK_ALL;
tls_reg_write32(HR_SPI_INT_MASK_REG, reg_val);
}
static __inline void spi_unmask_int(u32 mask)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_INT_MASK_REG);
reg_val &= ~(mask & SPI_INT_MASK_ALL);
tls_reg_write32(HR_SPI_INT_MASK_REG, reg_val);
}
static __inline u32 spi_get_int_status(void)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_INT_STATUS_REG);
return reg_val;
}
static __inline uint8_t spi_i2s_get_busy_status(void)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_STATUS_REG);
return SPI_IS_BUSY(reg_val);
}
static __inline void spi_clear_int_status(u32 int_srcs)
{
u32 reg_val;
reg_val = tls_reg_read32(HR_SPI_INT_STATUS_REG);
reg_val &= ~(int_srcs & SPI_INT_CLEAR_ALL);
reg_val |= int_srcs & SPI_INT_CLEAR_ALL;
tls_reg_write32(HR_SPI_INT_STATUS_REG, reg_val);
}
static __inline void spi_data_put(u32 data)
{
tls_reg_write32(HR_SPI_TXDATA_REG, data);
}
static __inline u32 spi_data_get(void)
{
return tls_reg_read32(HR_SPI_RXDATA_REG);
}
+319
View File
@@ -0,0 +1,319 @@
/**
* @file wm_timer.c
*
* @brief Timer Driver Module
*
* @author dave
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
*/
#include "wm_type_def.h"
#include "wm_timer.h"
#include "wm_regs.h"
#include "wm_irq.h"
#include "wm_cpu.h"
#include "tls_common.h"
enum tls_timer_id{
TLS_TIMER_ID_0 = 0, // used by delay (sleep, msleep, usleep)
TLS_TIMER_ID_1,
TLS_TIMER_ID_2,
TLS_TIMER_ID_3,
TLS_TIMER_ID_4,
TLS_TIMER_ID_5,
TLS_TIMER_ID_MAX
};
#define TIM0_USED_BY_DELAY 0
#define WM_TIMER_IRQ_USE_LOOP 1
struct timer_irq_context {
tls_timer_irq_callback callback;
void *arg;
};
static struct timer_irq_context timer_context[TLS_TIMER_ID_MAX] = {{0,0}};
u8 wm_timer_bitmap = 0;
#if WM_TIMER_IRQ_USE_LOOP
static void timer_irq_callback(void *p)
{
u8 i;
u32 value;
value = tls_reg_read32(HR_TIMER0_5_CSR);
value &= ~(TLS_TIMER_INT_CLR(TLS_TIMER_ID_0));
for (i = TLS_TIMER_ID_1; i < TLS_TIMER_ID_MAX; i++)
{
if (value & TLS_TIMER_INT_CLR(i))
{
if (NULL != timer_context[i].callback)
timer_context[i].callback(timer_context[i].arg);
}
}
tls_reg_write32(HR_TIMER0_5_CSR, value);
return;
}
#else /* WM_TIMER_IRQ_USE_LOOP */
static void timer_clear_irq(int timer_id)
{
u8 i;
u32 value;
value = tls_reg_read32(HR_TIMER0_5_CSR);
for (i = TLS_TIMER_ID_0; i < TLS_TIMER_ID_MAX; i++)
{
value &= ~(TLS_TIMER_INT_CLR(i));
}
tls_reg_write32(HR_TIMER0_5_CSR, value | TLS_TIMER_INT_CLR(timer_id));
}
static void timer_irq_callback(void *p)
{
u8 timer_id;
timer_id = (u8)(u32)p;
if (NULL != timer_context[timer_id].callback)
timer_context[timer_id].callback(timer_context[timer_id].arg);
timer_clear_irq(timer_id);
return;
}
#endif /* WM_TIMER_IRQ_USE_LOOP */
void TIM0_IRQHandler(void)
{
timer_irq_callback((void *)TLS_TIMER_ID_0);
}
void TIM1_IRQHandler(void)
{
timer_irq_callback((void *)TLS_TIMER_ID_1);
}
void TIM2_IRQHandler(void)
{
timer_irq_callback((void *)TLS_TIMER_ID_2);
}
void TIM3_IRQHandler(void)
{
timer_irq_callback((void *)TLS_TIMER_ID_3);
}
void TIM4_IRQHandler(void)
{
timer_irq_callback((void *)TLS_TIMER_ID_4);
}
void TIM5_IRQHandler(void)
{
timer_irq_callback((void *)TLS_TIMER_ID_5);
}
/**
* @brief This function is used to create the timer
*
* @param[in] cfg timer configuration
*
* @retval WM_TIMER_ID_INVALID failed
* @retval other timer id[0~5]
*
* @note
* user not need clear interrupt flag.
* timer 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.
*/
u8 tls_timer_create(struct tls_timer_cfg *cfg)
{
u8 i;
int timer_csr;
for (i = TLS_TIMER_ID_1; i < TLS_TIMER_ID_MAX; i++)
{
if (!(wm_timer_bitmap & BIT(i)))
break;
}
if (TLS_TIMER_ID_MAX == i)
return WM_TIMER_ID_INVALID;
wm_timer_bitmap |= BIT(i);
timer_context[i].callback = cfg->callback;
timer_context[i].arg = cfg->arg;
tls_sys_clk sysclk;
tls_sys_clk_get(&sysclk);
tls_reg_write32(HR_TIMER_CFG, sysclk.apbclk-1);
timer_csr = tls_reg_read32(HR_TIMER0_5_CSR);
if (!cfg->is_repeat)
timer_csr |= TLS_TIMER_ONE_TIME(i);
else
timer_csr &= ~(TLS_TIMER_ONE_TIME(i));
if (TLS_TIMER_UNIT_MS == cfg->unit)
timer_csr |= TLS_TIMER_MS_UNIT(i);
else
timer_csr &= ~(TLS_TIMER_MS_UNIT(i));
tls_reg_write32(HR_TIMER0_5_CSR, timer_csr | TLS_TIMER_INT_CLR(i));
if(cfg->timeout){
tls_reg_write32(HR_TIMER0_PRD + 0x04 * i, cfg->timeout);
}
tls_irq_enable(TIMER0_INT + i);
return i;
}
/**
* @brief This function is used to start the timer
*
* @param[in] timer_id timer id[0~5]
*
* @return None
*
* @note None
*/
void tls_timer_start(u8 timer_id)
{
if (!(wm_timer_bitmap & BIT(timer_id)))
return;
tls_reg_write32(HR_TIMER0_5_CSR, tls_reg_read32(HR_TIMER0_5_CSR)|TLS_TIMER_INT_EN(timer_id)| TLS_TIMER_EN(timer_id));
return;
}
/**
* @brief This function is used to stop the timer
*
* @param[in] timer_id timer id[0~5]
*
* @return None
*
* @note None
*/
void tls_timer_stop(u8 timer_id)
{
if (!(wm_timer_bitmap & BIT(timer_id)))
return;
tls_reg_write32(HR_TIMER0_5_CSR, tls_reg_read32(HR_TIMER0_5_CSR)|TLS_TIMER_INT_CLR(timer_id));
tls_reg_write32(HR_TIMER0_5_CSR, tls_reg_read32(HR_TIMER0_5_CSR) &~ TLS_TIMER_EN(timer_id));
return;
}
/**
* @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)
{
if (!(wm_timer_bitmap & BIT(timer_id)))
return;
tls_timer_stop(timer_id);
if (newtime)
tls_reg_write32(HR_TIMER0_PRD + 0x04 * timer_id, newtime);
tls_timer_start(timer_id);
return;
}
/**
* @brief This function is used to delete the timer
*
* @param[in] timer_id timer id[0~5]
*
* @return None
*
* @note None
*/
void tls_timer_destroy(u8 timer_id)
{
if (!(wm_timer_bitmap & BIT(timer_id)))
return;
tls_timer_stop(timer_id);
timer_context[timer_id].callback = NULL;
timer_context[timer_id].arg = NULL;
wm_timer_bitmap &= ~BIT(timer_id);
return;
}
/**
* @brief This function is create a delay to elapse
*
* @param[in] timeout the value writed into TMR0_PRD
* @param[in] m_flag millisecond flag in TIMER0
*
* @return 0
*
* @note None
*/
int tls_delay_via_timer(unsigned int timeout, unsigned int m_flag)
{
int ret = 0;
tls_sys_clk sysclk;
int timer_csr = 0;
if (0 == timeout)
return ret;
/*
* no lock
*
*/
tls_irq_disable(TIMER0_INT + TIM0_USED_BY_DELAY);
tls_reg_write32(HR_TIMER0_PRD + 0x04 * TIM0_USED_BY_DELAY,
timeout);
tls_sys_clk_get(&sysclk);
tls_reg_write32(HR_TIMER_CFG, sysclk.apbclk-1);
timer_csr = tls_reg_read32(HR_TIMER0_5_CSR);
if (TIMER_MS_UNIT_FLAG == m_flag)
timer_csr |= TLS_TIMER_MS_UNIT(TIM0_USED_BY_DELAY);
else if (TIMER_US_UNIT_FLAG == m_flag)
timer_csr &= ~(TLS_TIMER_MS_UNIT(TIM0_USED_BY_DELAY));
timer_csr |= TLS_TIMER_ONE_TIME(TIM0_USED_BY_DELAY);
timer_csr |= TLS_TIMER_INT_CLR(TIM0_USED_BY_DELAY);
timer_csr |= (TLS_TIMER_INT_EN(TIM0_USED_BY_DELAY));
timer_csr |= TLS_TIMER_EN(TIM0_USED_BY_DELAY);
tls_reg_write32(HR_TIMER0_5_CSR, timer_csr);
while (!(tls_reg_read32(HR_TIMER0_5_CSR)
& (TLS_TIMER_INT_CLR(TIM0_USED_BY_DELAY))))
;
timer_csr |= TLS_TIMER_INT_CLR(TIM0_USED_BY_DELAY);
tls_reg_write32(HR_TIMER0_5_CSR, timer_csr);
tls_irq_enable(TIMER0_INT + TIM0_USED_BY_DELAY);
/*
* no unlock
*
*/
return ret;
}
File diff suppressed because it is too large Load Diff
+160
View File
@@ -0,0 +1,160 @@
/**
* @file wm_watchdog.c
*
* @brief watchdog Driver Module
*
* @author kevin
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
*/
#include "wm_debug.h"
#include "wm_regs.h"
#include "wm_irq.h"
#include "wm_cpu.h"
#include "wm_watchdog.h"
static u32 wdg_jumpclear_flag = 0; /*0:donot jump clear, 1: jump clear, 2:close wdg*/
// void WDG_IRQHandler(void)
// {
// printf("WDG IRQ\n"); while(1) {};
// }
/**
* @brief This function is used to clear watchdog irq in case watchdog reset
*
* @param None
*
* @return None
*
* @note None
*/
void tls_watchdog_clr(void)
{
if (0 == wdg_jumpclear_flag)
{
tls_reg_write32(HR_WDG_INT_CLR, 0x01);
}
}
/**
* @brief This function is used to init watchdog
*
* @param[in] usec microseconds
*
* @return None
*
* @note None
*/
void tls_watchdog_init(u32 usec)
{
// tls_sys_clk sysclk;
// u32 apbclkcoff = 0;
// tls_sys_clk_get(&sysclk);
tls_irq_enable(WATCHDOG_INT);
//apbclkcoff = 40/sysclk.apbclk;
tls_reg_write32(HR_WDG_LOAD_VALUE, 40 * usec); /* 40M dominant frequency: 40 * 10^6 * (usec / 10^6) */
tls_reg_write32(HR_WDG_CTRL, 0x3); /* enable irq & reset */
}
/**
* @brief This function is used to deinit watchdog
*
* @param[in] None
*
* @return None
*
* @note None
*/
void tls_watchdog_deinit(void)
{
tls_irq_disable(WATCHDOG_INT);
tls_reg_write32(HR_WDG_CTRL, 0);
tls_reg_write32(HR_WDG_INT_CLR, 0x01);
}
/**
* @brief This function is used to start calculating elapsed time.
*
* @param[in] None
*
* @return elapsed time, unit:millisecond
*
* @note None
*/
void tls_watchdog_start_cal_elapsed_time(void)
{
if (tls_reg_read32(HR_WDG_CTRL)&0x3)
{
wdg_jumpclear_flag = 1;
tls_reg_write32(HR_WDG_INT_CLR, 0x01);
}
else
{
wdg_jumpclear_flag = 2;
tls_watchdog_init(5*1000*1000);
}
}
/**
* @brief This function is used to stop calculating & return elapsed time.
*
* @param[in] none
*
* @return elapsed time, unit:millisecond
*
* @note None
*/
u32 tls_watchdog_stop_cal_elapsed_time(void)
{
#define RT_TIME_BASE (40)
u32 val = 0;
switch (wdg_jumpclear_flag)
{
case 1:
{
val = (tls_reg_read32(HR_WDG_LOAD_VALUE) - tls_reg_read32(HR_WDG_CUR_VALUE))/RT_TIME_BASE;
wdg_jumpclear_flag = 0;
}
break;
case 2:
{
val = (tls_reg_read32(HR_WDG_LOAD_VALUE) - tls_reg_read32(HR_WDG_CUR_VALUE))/RT_TIME_BASE;
wdg_jumpclear_flag = 0;
tls_watchdog_deinit();
}
break;
default:
wdg_jumpclear_flag = 0;
break;
}
return val;
}
/**
* @brief This function is used to reset system
*
* @param None
*
* @return None
*
* @note None
*/
void tls_sys_reset(void)
{
tls_sys_clk_set(CPU_CLK_40M);
tls_os_set_critical();
tls_reg_write32(HR_WDG_LOCK, 0x1ACCE551);
tls_reg_write32(HR_WDG_LOAD_VALUE, 0x100);
tls_reg_write32(HR_WDG_CTRL, 0x3);
tls_reg_write32(HR_WDG_LOCK, 1);
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef WM_DRIVER
#define WM_DRIVER
#include "../Platform/Drivers/uart/wm_uart.c"
#include "../Platform/Drivers/timer/wm_timer.c"
#include "../Platform/Drivers/spi/wm_hostspi.c"
#include "../Platform/Drivers/rtc/wm_rtc.c"
#include "../Platform/Drivers/pwm/wm_pwm.c"
#include "../Platform/Drivers/irq/wm_irq.c"
#include "../Platform/Drivers/i2c/wm_i2c.c"
#include "../Platform/Drivers/hspi/wm_hspi.c"
#include "../Platform/Drivers/gpio/wm_gpio.c"
#include "../Platform/Drivers/efuse/wm_efuse.c"
#include "../Platform/Drivers/dma/wm_dma.c"
#include "../Platform/Drivers/cpu/wm_cpu.c"
#include "../Platform/Drivers/adc/wm_adc.c"
#include "../Platform/Drivers/io/wm_io.c"
#include "../Platform/Drivers/i2s/wm_i2s.c"
#include "../Platform/Drivers/lcd/wm_lcd.c"
#include "../Platform/Drivers/pmu/wm_pmu.c"
#include "../Platform/Drivers/7816/wm_7816.c"
#include "../Platform/Drivers/internalflash/wm_internal_fls.c"
#include "../Platform/Drivers/flash/wm_fls.c"
#include "../Platform/Drivers/flash/wm_fls_gd25qxx.c"
#include "../Platform/Drivers/watchdog/wm_watchdog.c"
#include "../Platform/Drivers/gpio/wm_gpio_afsel.c"
#endif //WM_DRIVER
+116
View File
@@ -0,0 +1,116 @@
#ifndef BITOPS_H
#define BITOPS_H
#include "wm_osal.h"
/*
* These functions are the basis of our bit ops.
*
* First, the atomic bitops. These use native endian.
*/
static __inline void set_bit(unsigned int bit, volatile unsigned long *p)
{
u32 cpu_sr;
unsigned long mask = 1 << (bit & 31);
p += bit >> 5;
cpu_sr = tls_os_set_critical();
*p |= mask;
tls_os_release_critical(cpu_sr);
}
static __inline void clear_bit(unsigned int bit, volatile unsigned long *p)
{
u32 cpu_sr;
unsigned long mask = 1 << (bit & 31);
p += bit >> 5;
cpu_sr = tls_os_set_critical();
*p &= ~mask;
tls_os_release_critical(cpu_sr);
}
static __inline void change_bit(unsigned int bit, volatile unsigned long *p)
{
u32 cpu_sr;
unsigned long mask = 1 << (bit & 31);
p += bit >> 5;
cpu_sr = tls_os_set_critical();
*p ^= mask;
tls_os_release_critical(cpu_sr);
}
static __inline int
test_and_set_bit(unsigned int bit, volatile unsigned long *p)
{
u32 cpu_sr;
unsigned int res;
unsigned long mask = 1 << (bit & 31);
p += bit >> 5;
cpu_sr = tls_os_set_critical();
res = *p;
*p = res | mask;
tls_os_release_critical(cpu_sr);
return res & mask;
}
static __inline int
test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
{
u32 cpu_sr;
unsigned int res;
unsigned long mask = 1 << (bit & 31);
p += bit >> 5;
cpu_sr = tls_os_set_critical();
res = *p;
*p = res & ~mask;
tls_os_release_critical(cpu_sr);
return res & mask;
}
static __inline int
test_bit(unsigned int bit, volatile unsigned long *p)
{
u32 cpu_sr;
unsigned int res;
unsigned long mask = 1 << (bit & 31);
p += bit >> 5;
cpu_sr = tls_os_set_critical();
res = *p;
tls_os_release_critical(cpu_sr);
return res & mask;
}
static __inline int
test_and_change_bit(unsigned int bit, volatile unsigned long *p)
{
u32 cpu_sr;
unsigned int res;
unsigned long mask = 1 << (bit & 31);
p += bit >> 5;
cpu_sr = tls_os_set_critical();
res = *p;
*p = res ^ mask;
tls_os_release_critical(cpu_sr);
return res & mask;
}
#endif /* BITOPS_H */
+192
View File
@@ -0,0 +1,192 @@
#ifndef __LIBTOMMATH_H__
#define __LIBTOMMATH_H__
typedef signed short int16;
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
#ifndef NULL
#define NULL ((void *)0)
#endif
#define BN_MP_INVMOD_C
#define BN_S_MP_EXPTMOD_C /* Note: #undef in tommath_superclass.h; this would
* require BN_MP_EXPTMOD_FAST_C instead */
#define BN_S_MP_MUL_DIGS_C
#define BN_MP_INVMOD_SLOW_C
#define BN_S_MP_SQR_C
#define BN_S_MP_MUL_HIGH_DIGS_C /* Note: #undef in tommath_superclass.h; this
* would require other than mp_reduce */
#ifdef LTM_FAST
/* Use faster div at the cost of about 1 kB */
#define BN_MP_MUL_D_C
/* Include faster exptmod (Montgomery) at the cost of about 2.5 kB in code */
#define BN_MP_EXPTMOD_FAST_C
#define BN_MP_MONTGOMERY_SETUP_C
#define BN_FAST_MP_MONTGOMERY_REDUCE_C
#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
#define BN_MP_MUL_2_C
/* Include faster sqr at the cost of about 0.5 kB in code */
#define BN_FAST_S_MP_SQR_C
#else /* LTM_FAST */
#define BN_MP_DIV_SMALL
#define BN_MP_INIT_MULTI_C
#define BN_MP_CLEAR_MULTI_C
#define BN_MP_ABS_C
#endif /* LTM_FAST */
/* Current uses do not require support for negative exponent in exptmod, so we
* can save about 1.5 kB in leaving out invmod. */
#define LTM_NO_NEG_EXP
/* from tommath.h */
#ifndef MIN
#define MIN(x,y) ((x)<(y)?(x):(y))
#endif
#ifndef MAX
#define MAX(x,y) ((x)>(y)?(x):(y))
#endif
#define OPT_CAST(x)
typedef unsigned int mp_digit;
//typedef u64 mp_word;
typedef unsigned long long mp_word;
#define XMALLOC tls_mem_alloc
#define XFREE tls_mem_free
#define XREALLOC os_realloc
#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
#define MP_LT -1 /* less than */
#define MP_EQ 0 /* equal to */
#define MP_GT 1 /* greater than */
#define MP_ZPOS 0 /* positive integer */
#define MP_NEG 1 /* negative */
#define MP_OKAY 0 /* ok result */
#define MP_MEM -2 /* out of mem */
#define MP_VAL -3 /* invalid input */
#define MP_YES 1 /* yes response */
#define MP_NO 0 /* no response */
typedef int mp_err;
/* define this to use lower memory usage routines (exptmods mostly) */
#define MP_LOW_MEM
/* default precision */
#ifndef MP_PREC
#ifndef MP_LOW_MEM
#define MP_PREC 32 /* default digits of precision */
#else
#define MP_PREC 8 /* default digits of precision */
#endif
#endif
/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
/* the infamous mp_int structure */
typedef struct {
int16 used, alloc, sign;
mp_digit *dp;
} mp_int;
/* ---> Basic Manipulations <--- */
#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
void mp_reverse (unsigned char *s, int len);
#ifdef BN_MP_INIT_MULTI_C
int mp_init_multi(mp_int *mp, ...);
#endif
#ifdef BN_MP_CLEAR_MULTI_C
void mp_clear_multi(mp_int *mp, ...);
#endif
int mp_lshd(mp_int * a, int b);
void mp_set(mp_int * a, mp_digit b);
void mp_clamp(mp_int * a);
void mp_exch(mp_int * a, mp_int * b);
void mp_rshd(mp_int * a, int b);
void mp_zero(mp_int * a);
int mp_mod_2d(mp_int * a, int b, mp_int * c);
int mp_div_2d(mp_int * a, int b, mp_int * c, mp_int * d);
int mp_init_copy(mp_int * a, mp_int * b);
int mp_mul_2d(mp_int * a, int b, mp_int * c);
#ifndef LTM_NO_NEG_EXP
int mp_div_2(mp_int * a, mp_int * b);
int mp_invmod(mp_int * a, mp_int * b, mp_int * c);
int mp_invmod_slow(mp_int * a, mp_int * b, mp_int * c);
#endif /* LTM_NO_NEG_EXP */
int mp_copy(mp_int * a, mp_int * b);
int mp_count_bits(mp_int * a);
int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d);
int mp_mod(mp_int * a, mp_int * b, mp_int * c);
int mp_grow(mp_int * a, int size);
int mp_cmp_mag(mp_int * a, mp_int * b);
#ifdef BN_MP_ABS_C
int mp_abs(mp_int * a, mp_int * b);
#endif
int mp_sqr(mp_int * a, mp_int * b);
int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
int mp_2expt(mp_int * a, int b);
int mp_reduce_setup(mp_int * a, mp_int * b);
int mp_reduce(mp_int * x, mp_int * m, mp_int * mu);
int mp_init_size(mp_int * a, int size);
#ifdef BN_MP_EXPTMOD_FAST_C
int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode);
#endif /* BN_MP_EXPTMOD_FAST_C */
#ifdef BN_FAST_S_MP_SQR_C
int fast_s_mp_sqr (mp_int * a, mp_int * b);
#endif /* BN_FAST_S_MP_SQR_C */
#ifdef BN_MP_MUL_D_C
int mp_mul_d (mp_int * a, mp_digit b, mp_int * c);
#endif /* BN_MP_MUL_D_C */
#ifdef BN_MP_MUL_2_C
/* b = a*2 */
int mp_mul_2(mp_int * a, mp_int * b);
#endif
int mp_init_for_read_unsigned_bin(mp_int *a, mp_digit len);
void mp_clear (mp_int * a);
int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
int wpa_mp_init (mp_int * a);
int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);
int mp_to_unsigned_bin_nr (mp_int * a, unsigned char *b);
int mp_to_unsigned_bin (mp_int * a, unsigned char *b);
int mp_unsigned_bin_size (mp_int * a);
int mp_add (mp_int * a, mp_int * b, mp_int * c);
int mp_cmp (mp_int * a, mp_int * b);
int mp_sub (mp_int * a, mp_int * b, mp_int * c);
int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d);
int mp_cmp_d(mp_int * a, mp_digit b);
#ifdef BN_MP_MONTGOMERY_SETUP_C
int mp_montgomery_setup (mp_int * n, mp_digit * rho);
#endif
#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
int mp_montgomery_calc_normalization (mp_int * a, mp_int * b);
#endif
#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho);
#endif
#endif //__LIBTOMMATH_H__
+52
View File
@@ -0,0 +1,52 @@
/*
* MD5 hash implementation and interface functions
* Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
*
* 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 MD5_H
#define MD5_H
#include "wm_type_def.h"
//typedef unsigned int size_t;
#define MD5_MAC_LEN 16
struct MD5Context {
u32 buf[4];
u32 bits[2];
u8 in[64];
};
void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, unsigned char const *buf,
unsigned len);
void MD5Final(unsigned char digest[16], struct MD5Context *context);
int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac);
int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
u8 *mac);
int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
int md5(const u8 *addr, int len, u8 *mac);
#ifdef CONFIG_FIPS
int hmac_md5_vector_non_fips_allow(const u8 *key, size_t key_len,
size_t num_elem, const u8 *addr[],
const size_t *len, u8 *mac);
int hmac_md5_non_fips_allow(const u8 *key, size_t key_len, const u8 *data,
size_t data_len, u8 *mac);
#else /* CONFIG_FIPS */
#define hmac_md5_vector_non_fips_allow hmac_md5_vector
#define hmac_md5_non_fips_allow hmac_md5
#endif /* CONFIG_FIPS */
#endif /* MD5_H */
+206
View File
@@ -0,0 +1,206 @@
/**
******************************************************************************
* @file misc.h
* @author MCD Application Team
* @version V3.6.1
* @date 05-March-2012
* @brief This file contains all the functions prototypes for the miscellaneous
* firmware library functions (add-on to CMSIS functions).
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MISC_H
#define __MISC_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "wm_regs.h"
/** @addtogroup W600_Driver
* @{
*/
/** @addtogroup MISC
* @{
*/
/** @defgroup MISC_Exported_Types
* @{
*/
/**
* @brief NVIC Init Structure definition
*/
typedef struct
{
uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.
This parameter can be a value of @ref IRQn_Type */
uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel
specified in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified
in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
will be enabled or disabled.
This parameter can be set either to ENABLE or DISABLE */
} NVIC_InitTypeDef;
/**
* @}
*/
/** @defgroup NVIC_Priority_Table
* @{
*/
/**
@code
The table below gives the allowed values of the pre-emption priority and subpriority according
to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function
============================================================================================================================
NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description
============================================================================================================================
NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority
| | | 4 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority
| | | 3 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority
| | | 2 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority
| | | 1 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority
| | | 0 bits for subpriority
============================================================================================================================
@endcode
*/
/**
* @}
*/
/** @defgroup MISC_Exported_Constants
* @{
*/
/** @defgroup Vector_Table_Base
* @{
*/
#define NVIC_VectTab_RAM ((uint32_t)0x20000000)
#define NVIC_VectTab_FLASH ((uint32_t)0x08000000)
#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \
((VECTTAB) == NVIC_VectTab_FLASH))
/**
* @}
*/
/** @defgroup System_Low_Power
* @{
*/
#define NVIC_LP_SEVONPEND ((uint8_t)0x10)
#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04)
#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02)
#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \
((LP) == NVIC_LP_SLEEPDEEP) || \
((LP) == NVIC_LP_SLEEPONEXIT))
/**
* @}
*/
/** @defgroup Preemption_Priority_Group
* @{
*/
#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
4 bits for subpriority */
#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
3 bits for subpriority */
#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
2 bits for subpriority */
#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
1 bits for subpriority */
#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
0 bits for subpriority */
#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \
((GROUP) == NVIC_PriorityGroup_1) || \
((GROUP) == NVIC_PriorityGroup_2) || \
((GROUP) == NVIC_PriorityGroup_3) || \
((GROUP) == NVIC_PriorityGroup_4))
#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10)
#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10)
#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF)
/**
* @}
*/
/** @defgroup SysTick_clock_source
* @{
*/
#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)
#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
((SOURCE) == SysTick_CLKSource_HCLK_Div8))
/**
* @}
*/
/**
* @}
*/
/** @defgroup MISC_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup MISC_Exported_Functions
* @{
*/
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);
#ifdef __cplusplus
}
#endif
#endif /* __MISC_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT 2014 Winner Microelectronics Co., Ltd. *****END OF FILE****/
+47
View File
@@ -0,0 +1,47 @@
#ifndef OS_H
#define OS_H
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "wm_mem.h"
#ifndef os_strlen
#define os_strlen(s) strlen(s)
#endif
void * os_zalloc(u32 size);
void * os_realloc(void *ptr, size_t size);
char * os_strdup(const char *s);
#define os_time_after(a, b) ((long)(b) - (long)(a) < 0)
#ifndef os_memcpy
#define os_memcpy(d, s, n) MEMCPY((d), (s), (n))
#endif
#ifndef os_memmove
#define os_memmove(d, s, n) memmove((d), (s), (n))
#endif
#ifndef os_memset
#define os_memset(s, c, n) memset(s, c, n)
#endif
#ifndef os_memcmp
#define os_memcmp(s1, s2, n) memcmp((s1), (s2), (n))
#endif
#ifndef os_strstr
#define os_strstr(h, n) strstr((h), (n))
#endif
#ifndef os_strcmp
#define os_strcmp(s1, s2) strcmp((s1), (s2))
#endif
#ifndef os_strncmp
#define os_strncmp(s1, s2, n) strncmp((s1), (s2), (n))
#endif
#ifndef os_strchr
#define os_strchr(s, c) strchr((s), (c))
#endif
#ifndef os_strcpy
#define os_strcpy(s1,s2) strcpy((s1),(s2))
#endif
#endif
+38
View File
@@ -0,0 +1,38 @@
#ifndef RC4_H
#define RC4_H
#include "wm_crypto_hard.h"
void Arc4Init(psCipherContext_t *ctx, unsigned char *key, uint32 keylen);
int32 Arc4_skip(psCipherContext_t *ctx, unsigned char *in,
unsigned char *out, size_t skip, uint32 len);
/**
* rc4_skip - XOR RC4 stream to given data with skip-stream-start
* @key: RC4 key
* @keylen: RC4 key length
* @skip: number of bytes to skip from the beginning of the RC4 stream
* @data: data to be XOR'ed with RC4 stream
* @data_len: buf length
* Returns: 0 on success, -1 on failure
*
* Generate RC4 pseudo random stream for the given key, skip beginning of the
* stream, and XOR the end result with the data buffer to perform RC4
* encryption/decryption.
*/
int rc4_skip(const u8 *key, size_t keylen, size_t skip,
u8 *data, size_t data_len);
/**
* rc4 - XOR RC4 stream to given data with skip-stream-start
* @key: RC4 key
* @keylen: RC4 key length
* @data: data to be XOR'ed with RC4 stream
* @data_len: buf length
* Returns: 0 on success, -1 on failure
*
* Generate RC4 pseudo random stream for the given key, skip beginning of the
* stream, and XOR the end result with the data buffer to perform RC4
* encryption/decryption.
*/
int rc4(const u8 *key, size_t keylen, u8 *data, size_t data_len);
#endif /* end of RC4_H */
+46
View File
@@ -0,0 +1,46 @@
/*
* SHA1 hash implementation and interface functions
* Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
*
* 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 SHA1_H
#define SHA1_H
#include "tls_common.h"
#define SHA1_HASH_SIZE 20
#define SHA1_MAC_LEN 20
struct SHA1Context {
u32 state[5];
u32 count[2];
unsigned char buffer[64];
};
void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac);
int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
u8 *mac);
int sha1_prf(const u8 *key, size_t key_len, const char *label,
const u8 *data, size_t data_len, u8 *buf, size_t buf_len);
int sha1_t_prf(const u8 *key, size_t key_len, const char *label,
const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len);
int pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
int iterations, u8 *buf, size_t buflen);
int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
void SHA1Init(struct SHA1Context* context);
void SHA1Update(struct SHA1Context* context, const void *_data, u32 len);
void SHA1Final(unsigned char digest[20], struct SHA1Context* context);
int sha1(const u8 *addr, int len, u8 *mac);
#endif /* SHA1_H */
+53
View File
@@ -0,0 +1,53 @@
/*
* SHA256 hash implementation and interface functions
* Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
*
* 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 SHA256_H
#define SHA256_H
#include "common.h"
#include "os.h"
#define SHA256_MAC_LEN 32
#define SHA256_BLOCK_SIZE 64
struct sha256_state {
u64 length;
u32 state[8], curlen;
u8 buf[SHA256_BLOCK_SIZE];
};
void wpa_sha256_init(struct sha256_state *md);
int sha256_process(struct sha256_state *md, const unsigned char *in,
unsigned long inlen);
int sha256_done(struct sha256_state *md, unsigned char *out);
/**
* sha256_vector - SHA256 hash for data vector
* @num_elem: Number of elements in the data vector
* @addr: Pointers to the data areas
* @len: Lengths of the data blocks
* @mac: Buffer for the hash
* Returns: 0 on success, -1 on failure
*/
int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
u8 *mac);
void hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac);
void hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
size_t data_len, u8 *mac);
void sha256_prf(const u8 *key, size_t key_len, const char *label,
const u8 *data, size_t data_len, u8 *buf, size_t buf_len);
#endif /* SHA256_H */
+253
View File
@@ -0,0 +1,253 @@
#ifndef TLS_COMMON_H
#define TLS_COMMON_H
#include "wm_osal.h"
#include "wm_config.h"
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#define BIT(x) (1UL << (x))
#define time_after(a, b) ((long)(b) - (long)(a) < 0)
#define time_before(a,b) time_after(b,a)
/*
* These are the defined Ethernet Protocol ID's.
*/
#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
#define ETH_P_IP 0x0800 /* Internet Protocol packet */
#define ETH_P_X25 0x0805 /* CCITT X.25 */
#define ETH_P_ARP 0x0806 /* Address Resolution packet */
#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */
#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */
#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
#define ETH_P_LAT 0x6004 /* DEC LAT */
#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
#define ETH_P_CUST 0x6006 /* DEC Customer use */
#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
#define ETH_P_TEB 0x6558 /* Trans Ether Bridging */
#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
#define ETH_P_ATALK 0x809B /* Appletalk DDP */
#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
#define ETH_P_IPX 0x8137 /* IPX over DIX */
#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
#define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */
#define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */
#define ETH_P_WCCP 0x883E /* Web-cache coordination protocol
* defined in draft-wilson-wrec-wccp-v2-00.txt */
#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
#define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */
#define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */
#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
* over Ethernet
*/
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#define ETH_P_WAPI 0x88B4 /* WAPI authentication */
#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
#define ETH_P_TIPC 0x88CA /* TIPC */
#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
#define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_HLEN 14 /* Total octets in header. */
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif
#ifndef ETH_P_ALL
#define ETH_P_ALL 0x0003
#endif
#ifndef ETH_P_80211_ENCAP
#define ETH_P_80211_ENCAP 0x890d /* TDLS comes under this category */
#endif
#ifndef ETH_P_PAE
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#endif /* ETH_P_PAE */
#ifndef ETH_P_EAPOL
#define ETH_P_EAPOL ETH_P_PAE
#endif /* ETH_P_EAPOL */
#ifndef ETH_P_RSN_PREAUTH
#define ETH_P_RSN_PREAUTH 0x88c7
#endif /* ETH_P_RSN_PREAUTH */
#ifndef ETH_P_RRB
#define ETH_P_RRB 0x890D
#endif /* ETH_P_RRB */
#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
#define STRUCT_PACKED __attribute__ ((packed))
#define broadcast_ether_addr (const u8 *) "\xff\xff\xff\xff\xff\xff"
/**
* compare_ether_addr - Compare two Ethernet addresses
* @addr1: Pointer to a six-byte array containing the Ethernet address
* @addr2: Pointer other six-byte array containing the Ethernet address
*
* Compare two ethernet addresses, returns 0 if equal
*/
static __inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2)
{
return !((addr1[0] == addr2[0]) && (addr1[1] == addr2[1]) && (addr1[2] == addr2[2]) && \
(addr1[3] == addr2[3]) && (addr1[4] == addr2[4]) && (addr1[5] == addr2[5]));
}
static __inline int is_zero_ether_addr(const u8 *a)
{
return !(a[0] | a[1] | a[2] | a[3] | a[4] | a[5]);
}
static __inline int is_broadcast_ether_addr(const u8 *a)
{
return (a[0] & a[1] & a[2] & a[3] & a[4] & a[5]) == 0xff;
}
static __inline int is_multicast_ether_addr(const u8 *addr)
{
return (0x01 & addr[0]);
}
static __inline unsigned short swap_16(unsigned short v)
{
return ((v & 0xff) << 8) | (v >> 8);
}
static __inline unsigned int swap_32(unsigned int v)
{
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
((v & 0xff0000) >> 8) | (v >> 24);
}
#define le_to_host16(n) (n)
#define host_to_le16(n) (n)
#define be_to_host16(n) swap_16(n)
#define host_to_be16(n) swap_16(n)
#define le_to_host32(n) (n)
#define le_to_host64(n) (n)
#define be_to_host32(n) swap_32(n)
#define host_to_be32(n) swap_32(n)
static __inline u16 get_unaligned_le16(const u8 *p)
{
return p[0] | p[1] << 8;
}
static __inline u32 get_unaligned_le32(const u8 *p)
{
return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
}
static __inline void put_unaligned_le16(u16 val, u8 *p)
{
*p++ = val;
*p++ = val >> 8;
}
static __inline void put_unaligned_le32(u32 val, u8 *p)
{
put_unaligned_le16(val >> 16, p + 2);
put_unaligned_le16(val, p);
}
static __inline u16 get_unaligned_be16(const u8 *p)
{
return be_to_host16(get_unaligned_le16(p));
}
static __inline u32 get_unaligned_be32(const u8 *p)
{
return be_to_host32(get_unaligned_le32(p));
}
static __inline void put_unaligned_be16(u16 val, u8 *p)
{
*p++ = val >> 8;
*p++ = val;
}
static __inline void put_unaligned_be32(u32 val, u8 *p)
{
put_unaligned_be16(val >> 16, p);
put_unaligned_be16(val, p + 2);
}
#ifdef __CHECKER__
#define __force __attribute__((force))
#define __bitwise __attribute__((bitwise))
#else
#define __force
#define __bitwise
#endif
typedef u16 __bitwise be16;
typedef u16 __bitwise le16;
typedef u32 __bitwise be32;
typedef u32 __bitwise le32;
typedef u64 __bitwise be64;
typedef u64 __bitwise le64;
/*
* This is an Ethernet frame header.
*/
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
} __attribute__((packed));
typedef struct {
volatile int counter;
} atomic_t;
struct kref {
atomic_t refcount;
};
static __inline int atomic_sub_return(int i, atomic_t *v)
{
u32 cpu_sr;
int val;
cpu_sr = tls_os_set_critical();
val = v->counter;
v->counter = val -= i;
tls_os_release_critical(cpu_sr);
return val;
}
static __inline int atomic_add_return(int i, atomic_t *v)
{
u32 cpu_sr;
int val;
cpu_sr = tls_os_set_critical();
val = v->counter;
v->counter = val += i;
tls_os_release_critical(cpu_sr);
return val;
}
#define atomic_set(v,i) (((v)->counter) = (i))
#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
#define atomic_inc(v) (void) atomic_add_return(1, v)
#define atomic_dec(v) (void) atomic_sub_return(1, v)
#endif /* end of TLS_COMMON_H */
+12
View File
@@ -0,0 +1,12 @@
#ifndef TLS_IEEE80211_H
#define TLS_IEEE80211_H
#include "tls_common.h"
#if (GCC_COMPILE==1)
#include "wm_ieee80211_gcc.h"
#else
#include "wm_ieee80211.h"
#endif
#endif /* end of TLS_IEEE80211_H */
+434
View File
@@ -0,0 +1,434 @@
#ifndef TLS_WIRELESS_H
#define TLS_WIRELESS_H
#include "tls_common.h"
#include "wm_osal.h"
#include "list.h"
//#include "netif.h"
struct tls_wif;
struct wpa_supplicant;
/* Maximum size of the SSID */
#define IW_SSID_MAX_SIZE 32
#if 0
#define IEEE80211_MODE_INFRA 0
#define IEEE80211_MODE_IBSS 1
#define IEEE80211_MODE_AP 2
#endif
//#define IEEE80211_RATE_MODE_B BIT(0)
//#define IEEE80211_RATE_MODE_G BIT(1)
//#define IEEE80211_RATE_MODE_BG BIT(2)
//#define IEEE80211_RATE_MODE_N BIT(3)
//#define IEEE80211_RATE_MODE_BGN BIT(4)
enum ieee80211_wireless_mode {
IEEE80211_MODE_11B = 0,
IEEE80211_MODE_11G,
IEEE80211_MODE_11NG_HT20,
IEEE80211_MODE_11NG_HT40PLUS,
IEEE80211_MODE_11NG_HT40MINUS,
IEEE80211_MODE_MAX,
};
#define IW_AUTH_INDEX 0x0FFF
#define IW_AUTH_FLAGS 0xF000
#define IW_AUTH_WPA_VERSION 0
#define IW_AUTH_CIPHER_PAIRWISE 1
#define IW_AUTH_CIPHER_GROUP 2
#define IW_AUTH_KEY_MGMT 3
#define IW_AUTH_TKIP_COUNTERMEASURES 4
#define IW_AUTH_DROP_UNENCRYPTED 5
#define IW_AUTH_80211_AUTH_ALG 6
#define IW_AUTH_WPA_ENABLED 7
#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8
#define IW_AUTH_ROAMING_CONTROL 9
#define IW_AUTH_PRIVACY_INVOKED 10
#define IW_AUTH_CIPHER_GROUP_MGMT 11
#define IW_AUTH_MFP 12
/* IW_AUTH_WPA_VERSION values (bit field) */
#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001
#define IW_AUTH_WPA_VERSION_WPA 0x00000002
#define IW_AUTH_WPA_VERSION_WPA2 0x00000004
/* IW_AUTH_PAIRWISE_CIPHER, IW_AUTH_GROUP_CIPHER, and IW_AUTH_CIPHER_GROUP_MGMT
* values (bit field) */
#define IW_AUTH_CIPHER_NONE 0x00000001
#define IW_AUTH_CIPHER_WEP40 0x00000002
#define IW_AUTH_CIPHER_TKIP 0x00000004
#define IW_AUTH_CIPHER_CCMP 0x00000008
#define IW_AUTH_CIPHER_WEP104 0x00000010
#define IW_AUTH_CIPHER_AES_CMAC 0x00000020
/* IW_AUTH_KEY_MGMT values (bit field) */
#define IW_AUTH_KEY_MGMT_802_1X 1
#define IW_AUTH_KEY_MGMT_PSK 2
/* IW_AUTH_80211_AUTH_ALG values (bit field) */
#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001
#define IW_AUTH_ALG_SHARED_KEY 0x00000002
#define IW_AUTH_ALG_LEAP 0x00000004
#define IW_ENCODE_ALG_NONE 0
#define IW_ENCODE_ALG_WEP 1
#define IW_ENCODE_ALG_TKIP 2
#define IW_ENCODE_ALG_CCMP 3
#define IW_ENCODE_ALG_PMK 4
#define IW_ENCODE_ALG_AES_CMAC 5
#define IW_MAX_FREQUENCIES 32
#define IW_SCAN_TYPE_ACTIVE 0
#define IW_SCAN_TYPE_PASSIVE 1
struct iw_scan_req {
u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */
u8 ssid_len;
u8 num_channels; /* num entries in channel_list;
* 0 = scan all allowed channels */
u8 bssid[ETH_ALEN]; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or
* individual address of a specific BSS */
u8 ssid[IW_SSID_MAX_SIZE];
u32 extra_ies_len;
u8 extra_ies[0];
//struct iw_freq channel_list[IW_MAX_FREQUENCIES];
};
#if 0
struct iw_bssid_ex {
u32 length;
u8 bssid[ETH_ALEN];
u16 freq;
u32 ssid_len;
u8 ssid[IW_SSID_MAX_SIZE];
u32 privacy;
int rssi;
u8 tsf[8];
u16 beacon_int;
u16 capabilities;
u32 ie_len;
u8 ies[0];
} __attribute__ ((packed));
struct iw_bss_info {
u8 bssid[ETH_ALEN];
u8 mode;
u8 channel;
u8 privacy;
u8 ssid_len;
u8 rssi;
u8 ssid[32];
};
struct iw_scan_results {
u32 count;
struct iw_bssid_ex bssid[1];
};
struct iw_scan_bss {
u32 count;
u32 length; /* bss info total length */
struct iw_bss_info bss[1];
};
#endif
/**
* struct beacon_parameters - beacon parameters
*
* Used to configure the beacon for an interface.
*
* @head: head portion of beacon (before TIM IE)
* or %NULL if not changed
* @tail: tail portion of beacon (after TIM IE)
* or %NULL if not changed
* @interval: beacon interval or zero if not changed
* @dtim_period: DTIM period or zero if not changed
* @head_len: length of @head
* @tail_len: length of @tail
*/
struct iw_beacon_parameters {
u8 *head, *tail;
int interval, dtim_period;
int head_len, tail_len;
};
struct iw_ssid_params {
u8 ssid[IW_SSID_MAX_SIZE];
u8 ssid_len;
u32 ie_len;
u8 *ie;
};
struct iw_key_params {
u8 key[32];
u8 tsc[32];
u32 key_len;
u32 tsc_len;
u16 cipher;
bool pairwise;
bool default_key;
u32 key_idx;
u8 addr[ETH_ALEN];
};
struct iw_sta_add_params {
const u8 *addr;
u16 aid;
u16 capability;
u16 listen_interval;
u8 mode;
const u8 *supp_rates;
u32 supp_rates_len;
u32 flags; /* bitmask of WPA_STA_* flags */
};
/**
* struct beacon_parameters - beacon parameters
*
* Used to configure the beacon for an interface.
*
* @head: head portion of beacon (before TIM IE)
* or %NULL if not changed
* @tail: tail portion of beacon (after TIM IE)
* or %NULL if not changed
* @interval: beacon interval or zero if not changed
* @dtim_period: DTIM period or zero if not changed
* @head_len: length of @head
* @tail_len: length of @tail
*/
struct beacon_parameters {
u8 *head, *tail;
int interval, dtim_period;
int head_len, tail_len;
};
struct wl_event_reload {
bool reload;
};
struct wl_event_join_ibss_info {
u8 bssid[ETH_ALEN];
u32 freq;
};
struct wl_event_mic_err {
u8 bssid[ETH_ALEN];
u8 addr[ETH_ALEN];
bool group_mic_err; /* TRUE: group, FALSE: pairwise */
};
struct wl_event_rx_eapol {
u8 *src_addr;
u8 *eapol_body;
u32 eapol_body_len;
#if TLS_CONFIG_AP
u8 mode;
#endif
};
struct wl_event_rx_mgmt {
u8 *mgmt;
u32 mgmt_len;
};
struct wl_event_rx_from_unknown {
u8 addr[ETH_ALEN];
};
struct wl_event_assoc_info {
/**
* reassoc - Flag to indicate association or reassociation
*/
int reassoc;
/**
* req_ies - (Re)Association Request IEs
*
* If the driver generates WPA/RSN IE, this event data must be
* returned for WPA handshake to have needed information. If
* wpa_supplicant-generated WPA/RSN IE is used, this
* information event is optional.
*
* This should start with the first IE (fixed fields before IEs
* are not included).
*/
const u8 *req_ies;
/**
* req_ies_len - Length of req_ies in bytes
*/
u32 req_ies_len;
/**
* resp_ies - (Re)Association Response IEs
*
* Optional association data from the driver. This data is not
* required WPA, but may be useful for some protocols and as
* such, should be reported if this is available to the driver
* interface.
*
* This should start with the first IE (fixed fields before IEs
* are not included).
*/
u8 *resp_ies;
/**
* resp_ies_len - Length of resp_ies in bytes
*/
u32 resp_ies_len;
/**
* addr - Station address (for AP mode)
*/
u8 *addr;
u8 *bssid;
/**
* freq - Frequency of the operational channel in MHz
*/
unsigned int freq;
};
struct tls_wl_event_ops {
int (*ibss_joined)(struct tls_wif *wif,
struct wl_event_join_ibss_info *info);
int (*assoc)(struct tls_wif *wif,
struct wl_event_assoc_info *info);
int (*disassoc)(struct tls_wif *wif);
int (*scan_completed)(struct tls_wif *wif);
int (*mic_err)(struct tls_wif *wif,
struct wl_event_mic_err *info);
int (*rx_eapol)(struct tls_wif *wif,
struct wl_event_rx_eapol *eapol);
int (*rx_mgmt)(struct tls_wif *wif,
struct wl_event_rx_mgmt *mgmt);
int (*mac_wdg)(struct tls_wif *wif);
#if TLS_CONFIG_AP_OPT_PS
int (*beacon_done)(struct tls_wif *wif);
int (*rx_ps)(struct tls_wif *wif,
struct wl_event_rx_mgmt *mgmt);
int (*rx_pspoll)(struct tls_wif *wif,
struct wl_event_rx_from_unknown *rx_pspoll);
int (*sta_active)(struct tls_wif *wif,
struct wl_event_rx_from_unknown *rx_pspoll);
#endif
int (*rx_from_unknown_sta)(struct tls_wif *wif,
struct wl_event_rx_from_unknown *rx_from_unknown);
int (*net_down)(struct tls_wif *wif);
int (*net_fail)(struct tls_wif *wif);
int (*net_up)(struct tls_wif *wif);
int (*update_stat)(struct tls_wif *wif, void *cur_bss);/* struct ieee80211_bss *cur_bss */
};
/* sk_buff allocated by wlan driver */
struct sk_buff {
struct dl_list list;
u8 *buf;
u32 buf_len;
u32 flags;
};
struct tls_wif {
//void *priv;
struct ieee80211_if_data *priv;
struct wpa_supplicant *wpa_s;
struct tls_wl_event_ops *ops;
#if TLS_CONFIG_SOFTAP_11N
struct hostapd_iface *apif;
#endif
//struct netif *ethif;
//bool net_up;
bool wlan_create;
int (*rx_data_cb)(const u8 *bssid, u8 *buf, u32 buf_len);
#if TLS_CONFIG_AP
bool wmm_set;
void *client_event_callback;
#if TLS_CONFIG_AP_OPT_FWD
int (*rx_ip_cb)(const u8 *bssid, u8 *buf, u32 buf_len);
#endif
#endif
#if 0
int (*send)(struct tls_wif *wif, struct sk_buff *skb);
int (*rx_data_cb)(struct tls_wif *wif, struct sk_buff *skb);
int (*tx_mgmt)(struct tls_wif *wif, struct sk_buff *skb);
int (*send_eapol)(struct tls_wif *wif, struct sk_buff *skb);
int (*send_beacon)(struct tls_wif *wif, struct sk_buff *skb);
#endif
};
void tls_wl_print_stats(struct tls_wif *wif);
int tls_wl_if_scan(struct tls_wif *wif,
struct iw_scan_req *scan_req, u16 size);
int tls_wl_if_scan_result2(struct tls_wif *wif,
u8 *ssid, u32 ssid_len, u8 *buf, u32 buf_size);
int tls_wl_if_scan_result(struct tls_wif *wif, u8 *buf, u32 buf_size);
void tls_wl_if_sta_flush(struct tls_wif *wif, u8 mode);
int tls_wl_if_sta_deauth(struct tls_wif *wif, u8 *own_addr,
const u8 *addr, int reason);
int tls_wl_if_sta_disassoc(struct tls_wif *wif, u8 *own_addr,
const u8 *addr, int reason);
#if TLS_CONFIG_AP
int tls_wl_if_set_tx_queue_params(struct tls_wif *wif, int queue,
int aifs, int cw_min, int cw_max, int burst_time);
void tls_wl_if_set_sta_flags(struct tls_wif *wif, u8 *addr, u32 flags);
int tls_wl_if_send_channel_switch(struct tls_wif *wif, u8 *ownaddr, u8 newch);
void tls_wl_if_switch_channel_width(struct tls_wif *wif, u8 *ownaddr);
void tls_wl_if_channel_info_updata(struct tls_wif *wif);
#if TLS_CONFIG_SOFTAP_11N
void tls_wl_if_get_ht_param(struct tls_wif *wif, u16 *cap, u8 *mcs, u8 *mpdu);
void tls_wl_if_set_sta_ht_param(struct tls_wif *wif, u8 *mac, u8 *ht);
#endif
#endif
int tls_wl_if_set_mode(struct tls_wif *wif, u16 mode);
int tls_wl_if_clear_mode(struct tls_wif *wif, u16 mode);
int tls_wl_if_set_bssid(struct tls_wif *wif, const u8 *addr, u32 mode);
int tls_wl_if_set_ssid(struct tls_wif *wif, struct iw_ssid_params *params);
int tls_wl_if_set_auth(struct tls_wif *wif, u16 flag, u32 value, u8 mode);
int tls_wl_if_set_ps_mode(struct tls_wif *wif, int powersave);
int tls_wl_if_set_freq(struct tls_wif *wif,
int freq);
int tls_wl_if_send_eapol(struct tls_wif *wif,
u8 *buf, u32 len, bool is_apsta);
int tls_wl_if_xmit(struct tls_wif *wif, void *buf, int len, bool is_apsta, bool not_delay);
int tls_wl_if_add_key(struct tls_wif *wif,
struct iw_key_params *params);
int tls_wl_if_remove_key(struct tls_wif *wif,
u32 cipher,
u32 key_idx,
bool pairwise,
u8 *addr);
int tls_wl_if_send_mlme(struct tls_wif *wif,
u8 *buf, u32 len);
int tls_wl_if_set_rate_mode(struct tls_wif *wif,
u32 rate_mode);
int tls_wl_if_set_beacon(struct tls_wif *wif,
struct iw_beacon_parameters *params);
int tls_wl_if_del_beacon(struct tls_wif *wif);
int tls_wl_if_sta_add(struct tls_wif *wif,
struct iw_sta_add_params *params);
int tls_wl_if_sta_remove(struct tls_wif *wif, u8 *addr);
int tls_wl_if_get_inact_sec(struct tls_wif *wif, const u8 *addr);
int tls_wl_if_get_scan_res(struct tls_wif *wif, u8 *buf, u32 buf_size);
int tls_wl_if_disconnect(struct tls_wif *wif);
int tls_wl_if_tx(struct tls_wif *wif,
u8 *buf, u32 buflen, bool last_packet, bool is_apsta, bool not_delay);
int tls_wl_if_set_max_rate(struct tls_wif *wif, u8 max_rate_idx);
int tls_wl_if_get_max_rate(struct tls_wif *wif, u8 *max_rate_idx);
int tls_wl_if_set_adhoc(struct tls_wif *wif, int adhoc_automode);
int tls_wl_if_ps(int wake_up);
int tls_wl_if_standby(int type, int delay, int wake_time);
int tls_wl_if_sleep(int type, int delay, int wake_time);
void tls_wl_if_set_errno(int eno);
int tls_wl_if_get_errno(void);
void tls_wl_if_perror(const char *info);
const char *tls_wl_if_get_errinfo(int eno);
#endif /* end of TLS_WIRELESS_H */
+39
View File
@@ -0,0 +1,39 @@
/**************************************************************************
* File Name : utils.h
* Author :
* Version : 1.0
* Date :
* Description :
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
* All rights reserved.
*
***************************************************************************/
#ifndef UTILS_H
#define UTILS_H
int chk_crc8(u8 *ptr, u32 len);
u8 get_crc8(u8 *ptr, u32 len);
u8 calculate_crc8(u8 crc8, u8 *ptr, u32 len);
u32 get_crc32(u8 *data, u32 data_size);
u32 checksum(u32 *data, u32 length, u32 init);
int atodec(char ch);
int strtodec(int *dec, char *str);
int atohex(char ch);
int strtohex(u32 *hex, char *str);
int strtohexarray(u8 array[], int cnt, char *str);
int strtoip(u32 *ipadr, char * str);
void iptostr(u32 ip, char *str);
void mactostr(u8 mac[], char *str);
int hex_to_digit(int c);
int digit_to_hex(int c);
int hexstr_to_unit(char *buf, u32 *d);
int string_to_uint(char *buf, u32 *d);
int string_to_ipaddr(const char *buf, u8 *addr);
char * strdup(const char *s);
char * strndup(const char *s, size_t len);
int sendchar(int ch);
#endif /* UTILS_H */
+93
View File
@@ -0,0 +1,93 @@
#ifndef __WM_DBG_H__
#define __WM_DBG_H__
#include "wm_debug.h"
/* Define the module switcher */
#define TLS_FLASH_DBG TLS_DBG_OFF
#define TLS_SPI_DBG TLS_DBG_OFF
#define TLS_IO_DBG TLS_DBG_OFF
#define TLS_DMA_DBG TLS_DBG_OFF
#define TLS_WL_DBG TLS_DBG_OFF
#define TLS_WPA_DBG TLS_DBG_OFF
/* flash info */
#if (TLS_FLASH_DBG && TLS_DBG_LEVEL_INFO)
#define TLS_DBGPRT_FLASH_INFO(f, a...) __TLS_DBGPRT_INFO(f, ##a)
#else
#define TLS_DBGPRT_FLASH_INFO(f, a...)
#endif
/* flash warnning */
#if (TLS_FLASH_DBG && TLS_DBG_LEVEL_WARNING)
#define TLS_DBGPRT_FLASH_WARNING(f, a...) __TLS_DBGPRT_WARNING(f, ##a)
#else
#define TLS_DBGPRT_FLASH_WARNING(f, a...)
#endif
/* flash error */
#if (TLS_FLASH_DBG && TLS_DBG_LEVEL_ERR)
#define TLS_DBGPRT_FLASH_ERR(f, a...) __TLS_DBGPRT_ERR(f, ##a)
#else
#define TLS_DBGPRT_FLASH_ERR(f, a...)
#endif
#if (TLS_SPI_DBG && TLS_DBG_LEVEL_INFO)
#define TLS_DBGPRT_SPI_INFO(f, a...) __TLS_DBGPRT_INFO(f, ##a)
#else
#define TLS_DBGPRT_SPI_INFO(f, a...)
#endif
#if (TLS_SPI_DBG && TLS_DBG_LEVEL_WARNING)
#define TLS_DBGPRT_SPI_WARNING(f, a...) __TLS_DBGPRT_WARNING(f, ##a)
#else
#define TLS_DBGPRT_SPI_WARNING(f, a...)
#endif
#if (TLS_SPI_DBG && TLS_DBG_LEVEL_ERR)
#define TLS_DBGPRT_SPI_ERR(f, a...) __TLS_DBGPRT_ERR(f, ##a)
#else
#define TLS_DBGPRT_SPI_ERR(f, a...)
#endif
#if (TLS_IO_DBG && TLS_DBG_LEVEL_INFO)
#define TLS_DBGPRT_IO_INFO(f, a...) __TLS_DBGPRT_INFO(f, ##a)
#else
#define TLS_DBGPRT_IO_INFO(f, a...)
#endif
#if (TLS_IO_DBG && TLS_DBG_LEVEL_WARNING)
#define TLS_DBGPRT_IO_WARNING(f, a...) __TLS_DBGPRT_WARNING(f, ##a)
#else
#define TLS_DBGPRT_IO_WARNING(f, a...)
#endif
#if (TLS_IO_DBG && TLS_DBG_LEVEL_ERR)
#define TLS_DBGPRT_IO_ERR(f, a...) __TLS_DBGPRT_ERR(f, ##a)
#else
#define TLS_DBGPRT_IO_ERR(f, a...)
#endif
#if (TLS_DMA_DBG && TLS_DBG_LEVEL_INFO)
#define TLS_DBGPRT_DMA_INFO(f, a...) __TLS_DBGPRT_INFO(f, ##a)
#else
#define TLS_DBGPRT_DMA_INFO(f, a...)
#endif
#if (TLS_DMA_DBG && TLS_DBG_LEVEL_WARNING)
#define TLS_DBGPRT_DMA_WARNING(f, a...) __TLS_DBGPRT_WARNING(f, ##a)
#else
#define TLS_DBGPRT_DMA_WARNING(f, a...)
#endif
#if (TLS_DMA_DBG && TLS_DBG_LEVEL_ERR)
#define TLS_DBGPRT_DMA_ERR(f, a...) __TLS_DBGPRT_ERR(f, ##a)
#else
#define TLS_DBGPRT_DMA_ERR(f, a...)
#endif
#endif /* __DBG_H__ */
+43
View File
@@ -0,0 +1,43 @@
# THE VERSION NUMBER
SET(CMAKE_SYSTEM_NAME Generic)
CMAKE_MINIMUM_REQUIRED (VERSION 3.10)
PROJECT(WMMAIN)
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
SET(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
set(CMAKE_VERBOSE_MAKEFILE OFF)
# ENABLE ASM
ENABLE_LANGUAGE(ASM)
SET(CMAKE_STATIC_LIBRARY_PREFIX)
SET(CMAKE_STATIC_LIBRARY_SUFFIX)
SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX)
SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX)
# C FLAGS
SET(CMAKE_C_FLAGS " -mthumb --function-sections --data-sections -mcpu=cortex-m3 -std=gnu99 -mabi=aapcs -march=armv7-m -fno-builtin ")
STRING(APPEND CMAKE_C_FLAGS " -DGCC_COMPILE=1 -DWOLFSSL_USER_SETTINGS -D_IN_ADDR_T_DECLARED -D__MACHINE_ENDIAN_H__ -D_TIMEVAL_DEFINED -D__INSIDE_CYGWIN_NET__ ")
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -gdwarf-2 -Wall -DDEBUG ")
SET(CMAKE_C_FLAGS_RELEASE "-Os -Wall")
# DEBUG ASM FLAGS
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -O0 -g3 -gdwarf-2 -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin -DDEBUG ")
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE} -Os -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin ")
# Library sources
SET(LIBRARY_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/wm_main.c"
"${CMAKE_CURRENT_SOURCE_DIR}/tls_sys.c"
)
function(ADD_LIB_TARGET LIBTARGET)
add_library(${LIBTARGET} OBJECT ${LIBRARY_SOURCES})
# ADD_CUSTOM_COMMAND(TARGET ${LIBTARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXECUTABLE_OUTPUT_PATH}/${LIBTARGET} ${CMAKE_CURRENT_SOURCE_DIR}/../../Lib/GNU/${LIBTARGET})
endfunction()
ADD_LIB_TARGET(wmmain.a)
+581
View File
@@ -0,0 +1,581 @@
/**************************************************************************
* File Name : tls_sys.c
* Author :
* Version :
* Date :
* Description :
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
* All rights reserved.
*
***************************************************************************/
#include "wm_config.h"
#include "wm_osal.h"
#include "tls_sys.h"
#include "wm_mem.h"
#include "wm_debug.h"
#include "wm_params.h"
#include "wm_regs.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wm_wifi.h"
#include "wm_netif.h"
#include "wm_sockets.h"
#include "wm_include.h"
#if TLS_CONFIG_AP
#include "wm_dhcp_server.h"
#include "wm_dns_server.h"
#include "wm_cpu.h"
#endif
#include "wm_wl_task.h"
#if TLS_CONFIG_RMMS
#if (GCC_COMPILE==1)
#include "wm_cmdp_hostif_gcc.h"
#else
#include "wm_cmdp_hostif.h"
#endif
#endif
#include "misc.h"
struct tls_sys_msg
{
u32 msg;
void *data;
};
#define SYS_TASK_STK_SIZE 512
static tls_os_queue_t *msg_queue;
#if TLS_DBG_LEVEL_DUMP
void TLS_DBGPRT_DUMP(char *p, u32 len)
{
int i;
if (TLS_DBG_LEVEL_DUMP)
{
wm_printf("dump length : %d\n", len);
for (i = 0; i < len; i++)
{
wm_printf("%02X ", p[i]);
if ((i + 1) % 16 == 0 && (i + 1) % 32 != 0)
{
wm_printf("- ");
}
if ((i + 1) % 32 == 0)
{
wm_printf("\n");
}
if (i == 2000)
{
wm_printf("\n");
break;
}
}
wm_printf("\n");
}
}
//-------------------------------------------------------------------------
#endif
static void sys_net_up()
{
ip_addr_t ip_addr, net_mask, gateway, dns1, dns2;
struct tls_param_ip ip_param;
bool enable = FALSE;
tls_param_get(TLS_PARAM_ID_IP, &ip_param, FALSE);
if (ip_param.dhcp_enable)
{
ip_addr_set_zero(&ip_addr);
ip_addr_set_zero(&net_mask);
ip_addr_set_zero(&gateway);
tls_netif_set_addr( &ip_addr, &net_mask, &gateway);
tls_netif_set_up();
tls_dhcp_start();
}
else
{
tls_dhcp_stop();
tls_netif_set_up();
MEMCPY((char*)ip_2_ip4(&ip_addr), &ip_param.ip, 4);
MEMCPY((char*)ip_2_ip4(&net_mask), &ip_param.netmask, 4);
MEMCPY((char*)ip_2_ip4(&gateway), &ip_param.gateway, 4);
tls_netif_set_addr( &ip_addr, &net_mask, &gateway);
MEMCPY((char*)ip_2_ip4(&dns1), &ip_param.dns1, 4);
MEMCPY((char*)ip_2_ip4(&dns2), &ip_param.dns2, 4);
tls_netif_dns_setserver(0, &dns1);
tls_netif_dns_setserver(1, &dns2);
/*when DHCP is disabled, Use static IP without IP_NET_UP Reporting,
set wifi powersaving flag according to TLS_PARAM_ID_PSM here.*/
tls_param_get(TLS_PARAM_ID_PSM, &enable, TRUE);
tls_wifi_set_psflag(enable, FALSE);
}
return ;
}
//-------------------------------------------------------------------------
#if TLS_CONFIG_AP
static void sys_net2_up()
{
ip_addr_t ip_addr, net_mask, gateway;
struct tls_param_ip ip_param;
u8 dnsname[32];
dnsname[0] = '\0';
tls_param_get(TLS_PARAM_ID_DNSNAME, dnsname, 0);
tls_param_get(TLS_PARAM_ID_SOFTAP_IP, &ip_param, FALSE);
tls_netif2_set_up();
MEMCPY((char*)ip_2_ip4(&ip_addr), &ip_param.ip, 4);
MEMCPY((char*)ip_2_ip4(&net_mask), &ip_param.netmask, 4);
MEMCPY((char*)ip_2_ip4(&gateway), &ip_param.gateway, 4);
tls_netif2_set_addr(&ip_addr, &net_mask, &gateway);
if (ip_param.dhcp_enable)
{
tls_dhcps_start();
}
if ('\0' != dnsname[0])
{
tls_dnss_start(dnsname);
}
return ;
}
//-------------------------------------------------------------------------
static void sys_net2_down()
{
tls_dnss_stop();
tls_dhcps_stop();
tls_netif2_set_down();
return ;
}
#endif
static void sys_net_down()
{
struct tls_param_ip ip_param;
#if TLS_CONFIG_RMMS
tls_rmms_stop();
#endif
tls_param_get(TLS_PARAM_ID_IP, &ip_param, FALSE);
if (ip_param.dhcp_enable)
{
tls_dhcp_stop();
}
tls_netif_set_status(0);
tls_netif_set_down();
/* Try to reconnect if auto_connect is set*/
tls_auto_reconnect();
return ;
}
//-------------------------------------------------------------------------
#if TLS_CONFIG_AP
static void tls_auto_reconnect_softap(void)
{
struct tls_param_ssid ssid;
struct tls_softap_info_t *apinfo;
struct tls_ip_info_t *ipinfo;
struct tls_param_ip ip_param;
struct tls_param_key key;
apinfo = tls_mem_alloc(sizeof(struct tls_softap_info_t));
if (apinfo == NULL)
{
return ;
}
ipinfo = tls_mem_alloc(sizeof(struct tls_ip_info_t));
if (ipinfo == NULL)
{
tls_mem_free(apinfo);
return ;
}
tls_param_get(TLS_PARAM_ID_SOFTAP_SSID, (void*) &ssid, TRUE);
memcpy(apinfo->ssid, ssid.ssid, ssid.ssid_len);
apinfo->ssid[ssid.ssid_len] = '\0';
tls_param_get(TLS_PARAM_ID_SOFTAP_ENCRY, (void*) &apinfo->encrypt, TRUE);
tls_param_get(TLS_PARAM_ID_SOFTAP_CHANNEL, (void*) &apinfo->channel, TRUE);
tls_param_get(TLS_PARAM_ID_SOFTAP_KEY, (void*) &key, TRUE);
apinfo->keyinfo.key_len = key.key_length;
apinfo->keyinfo.format = key.key_format;
apinfo->keyinfo.index = key.key_index;
memcpy(apinfo->keyinfo.key, key.psk, key.key_length);
tls_param_get(TLS_PARAM_ID_SOFTAP_IP, &ip_param, TRUE);
/*ip配置信息:ip地址,掩码,dns名称*/
memcpy(ipinfo->ip_addr, ip_param.ip, 4);
memcpy(ipinfo->netmask, ip_param.netmask, 4);
tls_param_get(TLS_PARAM_ID_DNSNAME, ipinfo->dnsname, FALSE);
tls_wifi_softap_create(apinfo, ipinfo);
tls_mem_free(apinfo);
tls_mem_free(ipinfo);
return ;
}
//-------------------------------------------------------------------------
#endif
void tls_auto_reconnect(void)
{
struct tls_param_ssid ssid;
u8 auto_reconnect = 0xff;
u8 wireless_protocol = 0;
#if 0
u8 i = 0;
while (i < 200)
{
if (tls_wifi_get_oneshot_flag())
{
/*oneshot config ongoing,do not reconnect WiFi*/
return ;
} tls_os_time_delay(1);
i++;
}
#endif
tls_wifi_auto_connect_flag(WIFI_AUTO_CNT_FLAG_GET, &auto_reconnect);
if (auto_reconnect == WIFI_AUTO_CNT_OFF)
{
return ;
}
else if (auto_reconnect == WIFI_AUTO_CNT_TMP_OFF)
{
auto_reconnect = WIFI_AUTO_CNT_ON;
tls_wifi_auto_connect_flag(WIFI_AUTO_CNT_FLAG_SET, &auto_reconnect);
return ; //tmparary return, for active "DISCONNECT" , such as AT CMD
}
tls_param_get(TLS_PARAM_ID_WPROTOCOL, (void*) &wireless_protocol, TRUE);
switch (wireless_protocol)
{
case TLS_PARAM_IEEE80211_INFRA:
#if TLS_CONFIG_AP
case (TLS_PARAM_IEEE80211_INFRA | TLS_PARAM_IEEE80211_SOFTAP):
#endif
{
struct tls_param_original_key origin_key;
struct tls_param_bssid bssid;
tls_param_get(TLS_PARAM_ID_BSSID, (void*) &bssid, TRUE);
tls_param_get(TLS_PARAM_ID_SSID, (void*) &ssid, TRUE);
tls_param_get(TLS_PARAM_ID_ORIGIN_KEY, (void*) &origin_key, TRUE);
if (bssid.bssid_enable)
{
if(ssid.ssid_len)
{
tls_wifi_connect_by_ssid_bssid(ssid.ssid, ssid.ssid_len, bssid.bssid, origin_key.psk, origin_key.key_length);
}
else
{
tls_wifi_connect_by_bssid(bssid.bssid, origin_key.psk, origin_key.key_length);
}
}
else if(ssid.ssid_len)
{
tls_wifi_connect(ssid.ssid, ssid.ssid_len, origin_key.psk, origin_key.key_length);
}
}
break;
#if TLS_CONFIG_AP
case TLS_PARAM_IEEE80211_SOFTAP:
{
tls_auto_reconnect_softap();
}
break;
#endif
default:
break;
}
return ;
}
//-------------------------------------------------------------------------
#if TLS_CONFIG_RMMS
static void tls_proc_rmms(struct rmms_msg *msg)
{
int err;
struct tls_hostif *hif = tls_get_hostif();
if (0 == hif->rmms_status)
{
hif->rmms_status = 1;
err = tls_hostif_cmd_handler(HOSTIF_RMMS_AT_CMD, (char*)msg, 6+strlen(
(char*)(msg->CmdStr)));
if (0 != err)
{
tls_mem_free(msg);
hif->rmms_status = 0;
}
}
return ;
}
//-------------------------------------------------------------------------
#endif
/*
* sys task stack
*/
static u32 sys_task_stk[SYS_TASK_STK_SIZE];
void tls_sys_task(void *data)
{
u8 err;
struct tls_sys_msg *msg;
u8 auto_reconnect = WIFI_AUTO_CNT_OFF;
//u8 oneshotflag = 0;
//u8 auto_mode = 0;
for (;;)
{
err = tls_os_queue_receive(msg_queue, (void **) &msg, 0, 0);
if (!err)
{
switch (msg->msg)
{
case SYS_MSG_NET_UP:
sys_net_up();
break;
#if TLS_CONFIG_AP
case SYS_MSG_NET2_UP:
sys_net2_up();
break;
case SYS_MSG_NET2_DOWN:
sys_net2_down();
break;
case SYS_MSG_NET2_FAIL:
sys_net2_down();
tls_auto_reconnect();
break;
#endif
case SYS_MSG_NET_DOWN:
sys_net_down();
break;
case SYS_MSG_CONNECT_FAILED:
sys_net_down();
break;
case SYS_MSG_AUTO_MODE_RUN:
/*restore WiFi auto reconnect Tmp OFF*/
tls_wifi_auto_connect_flag(WIFI_AUTO_CNT_FLAG_GET,
&auto_reconnect);
if (auto_reconnect == WIFI_AUTO_CNT_TMP_OFF)
{
auto_reconnect = WIFI_AUTO_CNT_ON;
tls_wifi_auto_connect_flag(WIFI_AUTO_CNT_FLAG_SET,
&auto_reconnect);
}
tls_auto_reconnect();
break;
#if TLS_CONFIG_RMMS
case SYS_MSG_RMMS:
tls_proc_rmms(msg->data);
break;
#endif
default:
break;
}
tls_mem_free(msg);
}
else
{
}
}
}
//-------------------------------------------------------------------------
void tls_sys_send_msg(u32 msg, void *data)
{
struct tls_sys_msg *pmsg;
pmsg = tls_mem_alloc(sizeof(struct tls_sys_msg));
if (NULL != pmsg)
{
memset(pmsg, 0, sizeof(struct tls_sys_msg));
pmsg->msg = msg;
pmsg->data = data;
tls_os_queue_send(msg_queue, pmsg, 0);
}
return ;
}
//-------------------------------------------------------------------------
void tls_sys_auto_mode_run(void)
{
tls_sys_send_msg(SYS_MSG_AUTO_MODE_RUN, NULL);
}
//-------------------------------------------------------------------------
static void tls_sys_net_up(void)
{
tls_sys_send_msg(SYS_MSG_NET_UP, NULL);
}
//-------------------------------------------------------------------------
#if TLS_CONFIG_AP
static void tls_sys_net2_up(void)
{
tls_sys_send_msg(SYS_MSG_NET2_UP, NULL);
}
//-------------------------------------------------------------------------
static void tls_sys_net2_down(void)
{
tls_sys_send_msg(SYS_MSG_NET2_DOWN, NULL);
}
static void tls_sys_net2_fail(void)
{
tls_sys_send_msg(SYS_MSG_NET2_FAIL, NULL);
}
#endif
static void tls_sys_net_down(void)
{
tls_sys_send_msg(SYS_MSG_NET_DOWN, NULL);
}
//-------------------------------------------------------------------------
static void tls_sys_connect_failed(void)
{
tls_sys_send_msg(SYS_MSG_CONNECT_FAILED, NULL);
}
//-------------------------------------------------------------------------
static void sys_net_status_changed(u8 status)
{
#if TLS_CONFIG_TLS_DEBUG
struct tls_ethif *ethif;
#endif
#if TLS_CONFIG_AP
u8 wireless_protocol = 0;
#endif
bool enable = FALSE;
switch (status)
{
case NETIF_WIFI_JOIN_SUCCESS:
TLS_DBGPRT_INFO("join net success\n");
tls_sys_net_up();
break;
case NETIF_WIFI_JOIN_FAILED:
{
TLS_DBGPRT_INFO("join net failed\n");
}
tls_sys_connect_failed();
break;
case NETIF_WIFI_DISCONNECTED:
{
TLS_DBGPRT_INFO("net disconnected\n");
}
tls_sys_net_down();
break;
case NETIF_IP_NET_UP:
tls_netif_set_status(1);
/*when DHCP enable, IP_NET_UP Report, set wifi powersaving flag according to TLS_PARAM_ID_PSM*/
tls_param_get(TLS_PARAM_ID_PSM, &enable, TRUE);
tls_wifi_set_psflag(enable, FALSE);
#if TLS_CONFIG_TLS_DEBUG
ethif = tls_netif_get_ethif();
TLS_DBGPRT_INFO("net up ==> ip = %v\n", ethif->ip_addr.addr);
#endif
#if TLS_CONFIG_AP
tls_param_get(TLS_PARAM_ID_WPROTOCOL, (void*) &wireless_protocol,
TRUE);
if ((TLS_PARAM_IEEE80211_SOFTAP &wireless_protocol) &&
(WM_WIFI_JOINED != tls_wifi_softap_get_state()))
{
tls_auto_reconnect_softap();
}
#endif
//#if TLS_CONFIG_RMMS
// tls_rmms_start();
//#endif
break;
#if TLS_CONFIG_AP
case NETIF_WIFI_SOFTAP_SUCCESS:
TLS_DBGPRT_INFO("softap create success.\n");
tls_sys_net2_up();
break;
case NETIF_WIFI_SOFTAP_FAILED:
TLS_DBGPRT_INFO("softap create failed.\n");
tls_sys_net2_fail();
break;
case NETIF_WIFI_SOFTAP_CLOSED:
TLS_DBGPRT_INFO("softap closed.\n");
tls_sys_net2_down();
break;
case NETIF_IP_NET2_UP:
#if TLS_CONFIG_TLS_DEBUG
ethif = tls_netif_get_ethif2();
TLS_DBGPRT_INFO("net up ==> ip = %v\n", ethif->ip_addr.addr);
#endif
break;
#endif
default:
break;
}
}
//-------------------------------------------------------------------------
int tls_sys_init()
{
int err;
/* create messge queue */
#define SYS_MSG_SIZE 20
err = tls_os_queue_create(&msg_queue, SYS_MSG_SIZE);
if (err)
{
return - 1;
}
/* create task */
tls_os_task_create(NULL, "Sys Task", tls_sys_task, (void*)0, (void*)
&sys_task_stk, /* task's stack start address */
SYS_TASK_STK_SIZE *sizeof(u32), /* task's stack size, unit:byte */
TLS_SYS_TASK_PRIO, 0);
tls_netif_add_status_event(sys_net_status_changed);
return 0;
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef TLS_SYS_H
#define TLS_SYS_H
#include "wm_type_def.h"
#include "wm_params.h"
#define SYS_MSG_NET_UP 1
#define SYS_MSG_NET_DOWN 2
#define SYS_MSG_CONNECT_FAILED 3
#define SYS_MSG_AUTO_MODE_RUN 4
#define SYS_MSG_NET2_UP 5
#define SYS_MSG_NET2_DOWN 6
#define SYS_MSG_NET2_FAIL 7
#define SYS_MSG_RMMS 8
int tls_sys_init(void);
void tls_auto_reconnect(void);
#endif /* end of TLS_SYS_H */
+402
View File
@@ -0,0 +1,402 @@
/*****************************************************************************
*
* File Name : wm_main.c
*
* Description: wm main
*
* Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd.
* All rights reserved.
*
* Author :
*
* Date : 2014-6-14
*****************************************************************************/
#include <string.h>
#include "wm_irq.h"
#include "tls_sys.h"
#include "wm_regs.h"
#include "wm_type_def.h"
#include "wm_timer.h"
#include "wm_irq.h"
#include "wm_params.h"
#include "wm_hostspi.h"
#include "wm_flash.h"
#include "wm_fls_gd25qxx.h"
#include "wm_internal_flash.h"
#include "wm_efuse.h"
#include "wm_debug.h"
#include "wm_netif.h"
#include "wm_at_ri_init.h"
#include "wm_config.h"
#include "wm_osal.h"
#include "wm_http_client.h"
#include "wm_cpu.h"
#include "misc.h"
#include "wm_webserver.h"
#include "wm_io.h"
#include "wm_mem.h"
#include "wm_wl_task.h"
#include "wm_wl_timers.h"
#include "wm_watchdog.h"
#ifdef TLS_CONFIG_HARD_CRYPTO
#include "wm_crypto_hard.h"
#endif
#include "wm_gpio_afsel.h"
#include "wm_pmu.h"
/* c librayr mutex */
tls_os_sem_t *libc_sem;
/*----------------------------------------------------------------------------
* Standard Library multithreading interface
*---------------------------------------------------------------------------*/
#ifndef __MICROLIB
/*--------------------------- _mutex_initialize -----------------------------*/
int _mutex_initialize (u32 *mutex) {
/* Allocate and initialize a system mutex. */
//tls_os_sem_create(&libc_sem, 1);
//mutex = (u32 *)libc_sem;
return(1);
}
/*--------------------------- _mutex_acquire --------------------------------*/
void _mutex_acquire (u32 *mutex) {
//u8 err;
/* Acquire a system mutex, lock stdlib resources. */
tls_os_sem_acquire(libc_sem, 0);
}
/*--------------------------- _mutex_release --------------------------------*/
void _mutex_release (u32 *mutex) {
/* Release a system mutex, unlock stdlib resources. */
tls_os_sem_release(libc_sem);
}
#endif
#define TASK_START_STK_SIZE 1200 /* Size of each task's stacks (# of WORDs) */
u32 TaskStartStk[TASK_START_STK_SIZE];
#ifdef TLS_CONFIG_HTTP_CLIENT_TASK
u8 pSession_flag=0;
#endif
#define FW_MAJOR_VER 0x03
#define FW_MINOR_VER 0x04
#define FW_PATCH_VER 0x08
const char FirmWareVer[4] = {
'G',
FW_MAJOR_VER, /* Main version */
FW_MINOR_VER, /* Subversion */
FW_PATCH_VER /* Internal version */
};
const char HwVer[6] = {
'H',
0x1,
0x0,
0x0,
0x0,
0x0
};
extern const char WiFiVer[];
extern u8 tx_gain_group[];
extern void *tls_wl_init(u8 *tx_gain, u8* mac_addr, u8 *hwver);
extern int wpa_supplicant_init(u8 *mac_addr);
extern void tls_sys_auto_mode_run(void);
extern void tls_spi_slave_sel(u16 slave);
extern void EarlyInit(void);
extern void UserMain(void);
extern void tls_fls_layout_init(void);
extern void Debug_UartInit(void);
void task_start (void *data);
void tls_os_timer_init(void)
{
tls_sys_clk sysclk;
tls_sys_clk_get(&sysclk);
SysTick_Config(sysclk.cpuclk*UNIT_MHZ/HZ);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
}
/****************/
/* main program */
/****************/
void vApplicationIdleHook( void )
{
/* clear watch dog interrupt */
tls_watchdog_clr();
#if !defined(__CC_ARM)
__asm volatile ("wfi");
#else
__WFI();
#endif
return;
}
void tls_exception_handler(unsigned int *sp, unsigned int exceptinfo)
{
int i = 0;
u32 value = 0;
value = (*(volatile int *)0xE000ED28);
switch(exceptinfo)
{
case 1:
printf("mem fault:\n");
if (value&0xFF)
{
printf("E000_ED28 Val:%x\n", value&0xFF);
}
break;
case 2:
printf("bus fault:\n");
if ((value>>8)&0xFF)
{
printf("E000_ED29 Val:%x\n", ((value>>8)&0xFF));
}
break;
case 3:
printf("usage fault:\n");
if ((value>>16)&0x3FF)
{
printf("E000_ED2A Val:%x\n", ((value>>16)&0x3FF));
}
break;
case 0:
default:
printf("hard fault:\n");
value = *(volatile int *)0xE000ED2C;
if (value)
{
printf("E000_ED2C Val:%x\n", value);
}
break;
}
// printf("Stack:%08p\n", sp);
// printf("StackInfo:\n");
for (i = 0; i < 16; i++)
{
printf("%08x\n", *sp++);
}
while(1);
}
void wm_gpio_config()
{
/* must call first */
wm_gpio_af_disable();
/* UART0_TX-PA04 UART0_RX-PA05 */
wm_uart0_tx_config(WM_IO_PA_04);
wm_uart0_rx_config(WM_IO_PA_05);
/* UART1_RX-PB11 UART1_TX-PB12 */
wm_uart1_rx_config(WM_IO_PB_11);
wm_uart1_tx_config(WM_IO_PB_12);
#if WM_CONFIG_DEBUG_UART2
/* UART2_RX-PA00 UART2_TX-PA01 */
wm_uart2_rx_config(WM_IO_PA_00);
wm_uart2_tx_scio_config(WM_IO_PA_01);
#endif
extern void pre_gpio_config();
pre_gpio_config();
/*MASTER SPI configuratioin*/
//wm_spi_cs_config(WM_IO_PB_15);
//wm_spi_ck_config(WM_IO_PB_16);
wm_spi_di_config(WM_IO_PB_17);
//wm_spi_do_config(WM_IO_PB_18);
}
bool debug_monitor_enable(void) {
volatile uint32_t *dhcsr = (uint32_t*)0xE000EDF0;
if ((*dhcsr & 0x1) != 0) {
printf("Halting Debug Enabled - Can't Enable Monitor Mode Debug!");
return false;
}
volatile uint32_t *demcr = (uint32_t*)0xE000EDFC;
const uint32_t mon_en_bit = 16;
*demcr |= 1 << mon_en_bit;
// Priority for DebugMonitor Exception is bits[7:0].
// We will use the lowest priority so other ISRs can
// fire while in the DebugMonitor Interrupt
volatile uint32_t *shpr3 = (uint32_t *)0xE000ED20;
*shpr3 = 0xff;
printf("Monitor Mode Debug Enabled!");
return true;
}
void tls_fix_wifi_irq_priority()
{
tls_irq_set_priority(RX_INT, IRQ_MAX_SYSCALL_PRIORITY);
}
int main(void)
{
tls_sys_clk_set(CPU_CLK_80M);
tls_pmu_clk_select(0);
tls_os_init(NULL);
Debug_UartInit();/*initialize debug uart for mapping to printf*/
/* before use malloc() function, must create mutex used by c_lib */
tls_os_sem_create(&libc_sem, 1);
EarlyInit();
{
tls_os_task_create(NULL, NULL,
task_start,
(void *)0,
(void *)&TaskStartStk[0], /* task's stack start address */
TASK_START_STK_SIZE * sizeof(u32), /* task's stack size, unit:byte */
1,
0);
}
/* initial os ticker */
tls_os_timer_init();
//debug_monitor_enable();
tls_os_start_scheduler();
return 0;
}
void disp_version_info(void)
{
TLS_DBGPRT_INFO("\n\n");
TLS_DBGPRT_INFO("****************************************************************\n");
TLS_DBGPRT_INFO("* *\n");
TLS_DBGPRT_INFO("* Copyright (C) 2014 WinnerMicro Co. Ltd. *\n");
TLS_DBGPRT_INFO("* All rights reserved. *\n");
TLS_DBGPRT_INFO("* WinnerMicro Firmware Version: %x.%x.%X *\n",
FirmWareVer[1], FirmWareVer[2], FirmWareVer[3]);
TLS_DBGPRT_INFO("* WinnerMicro Hardware Version: %x.%x.%x.%x.%x *\n",
HwVer[1], HwVer[2], HwVer[3],HwVer[4],HwVer[5]);
TLS_DBGPRT_INFO("* *\n");
TLS_DBGPRT_INFO("* WinnerMicro Wi-Fi Lib Version: %x.%x.%x *\n",
WiFiVer[0], WiFiVer[1], WiFiVer[2]);
TLS_DBGPRT_INFO("****************************************************************\n");
}
/*****************************************************************************
* Function Name // task_start
* Descriptor // before create multi_task, we create a task_start task
* // in this example, this task display the cpu usage
* Input
* Output
* Return
****************************************************************************/
void task_start (void *data)
{
u8 mac_addr[6] = {0x00,0x25,0x08,0x09,0x01,0x0F};
/* must call first to configure gpio Alternate functions according the hardware design */
wm_gpio_config();
#if TLS_CONFIG_HARD_CRYPTO
tls_crypto_init();
#endif
#if (TLS_CONFIG_LS_SPI)
tls_spi_init();
tls_spifls_init();
#endif
tls_fls_init();
/*initialize flash layout parameter according to image type*/
tls_fls_layout_init();
/*PARAM GAIN,MAC default*/
tls_ft_param_init();
tls_param_load_factory_default();
tls_param_init(); /*add param to init sysparam_lock sem*/
tls_get_tx_gain(&tx_gain_group[0]);
TLS_DBGPRT_INFO("tx gain ");
TLS_DBGPRT_DUMP((char *)(&tx_gain_group[0]), 12);
if (tls_wifi_mem_cfg(WIFI_MEM_START_ADDR, 7, 7)) /*wifi tx&rx mem customized interface*/
{
TLS_DBGPRT_INFO("wl mem initial failured\n");
}
tls_get_mac_addr(&mac_addr[0]);
TLS_DBGPRT_INFO("mac addr ");
TLS_DBGPRT_DUMP((char *)(&mac_addr[0]), 6);
if(tls_wl_init(NULL, &mac_addr[0], NULL) == NULL){
TLS_DBGPRT_INFO("wl driver initial failured\n");
}
if (wpa_supplicant_init(mac_addr)) {
TLS_DBGPRT_INFO("supplicant initial failured\n");
}
tls_fix_wifi_irq_priority();
tls_ethernet_init();
tls_sys_init();
/*HOSTIF&UART*/
#if TLS_CONFIG_HOSTIF
tls_hostif_init();
#if (TLS_CONFIG_HS_SPI)
tls_hspi_init();
#endif
#if TLS_CONFIG_UART
//tls_uart_init();
#endif
#if TLS_CONFIG_HTTP_CLIENT_TASK
// http_client_task_init();
#endif
#endif
/* call user main function */
UserMain();
tls_sys_auto_mode_run();
NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP, ENABLE);
for (;;)
{
#if 1
tls_os_time_delay(0x10000000);
#else
//printf("start up\n");
extern void tls_os_disp_task_stat_info(void);
tls_os_disp_task_stat_info();
tls_os_time_delay(1000);
#endif
}
}