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:
File diff suppressed because it is too large
Load Diff
@@ -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****/
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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. ***/
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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__
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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****/
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user