更新硬件SDK

This commit is contained in:
kerwincui
2023-03-04 03:44:56 +08:00
parent dcdf6e1b7c
commit e39d3d2f03
1900 changed files with 663153 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename:
*
* Description:
*
* History:
*
* Notes:
*
******************************************************************************/
#ifndef EC_STRING_H
#define EC_STRING_H
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS DECLEARATION *
*----------------------------------------------------------------------------*/
#if defined(__cplusplus)
extern "C" {
#endif
int32_t strlen_fast(const char *str);
char* ec_strnstr(const char *s, const char *find, size_t slen);
#ifdef __cplusplus
}
#endif
#endif // EC_STRING_H

View File

@@ -0,0 +1,70 @@
#ifndef __EC_UICC_API_H__
#define __EC_UICC_API_H__
/******************************************************************************
Copyright: - 2017, All rights reserved by AirM2M Ltd.
File name: - ecuiccapi.h
Description: - the header file for UICC open API.
Function List: -
History: - 09/20/2022, Originated by xlhu
******************************************************************************/
/*********************************************************************************
* Includes
*********************************************************************************/
#include "commontypedef.h"
/*********************************************************************************
* Macros
*********************************************************************************/
/*********************************************************************************
* Type Definition
*********************************************************************************/
/******************************************************************************
*****************************************************************************
* Functions
*****************************************************************************
******************************************************************************/
/******************************************************************************
* SoftSimReset
* Description: This API called by modem/uiccdrv task to reset softsim and get ATR parameter from softsim,
* as same as code/warm reset with physical SIM card.
* param[out] UINT16 *atrLen, the pointer to the length of ATR, this memory don't need to be free.
* param[out] UINT8 *atrData, the pointer to the ATR data, this memory don't need to be free.
* atrData buffer size is 33, fill atrData shall not exceed 33 bytes.
* Comment: This API will be called only if softsim feature is enabled by AT CMD.
* Shall send signal/msg to softsim task and block to wait response .
* Softsim internal process running in this func is not allowed.
******************************************************************************/
void SoftSimReset(UINT16 *atrLen, UINT8 *atrData);
/******************************************************************************
* SoftSimApduReq
* Description: This API will be called by modem/uiccdrv task to send APDU(TPDU) request and get response from softsim,
* support case 1/2/3/4 command/response process.
* param[in] UINT16 txDataLen, the length of tx data
* param[in] UINT8 *txData, the pointer to the tx data, this memory don't need to be free.
* param[out] UINT16 *rxDataLen, the pointer to the length of rx data, this memory don't need to be free.
* param[out] UINT8 *rxData, the pointer to the rx data, this memory don't need to be free.
* rxData buffer size is 258, fill rxData shall not exceed 258 bytes.
* Comment: This API will be called only if softsim feature is enabled by AT CMD.
* Shall send signal/msg to softsim task and block to wait response.
* Softsim internal process running in this func is not allowed.
******************************************************************************/
void SoftSimApduReq(UINT16 txDataLen, UINT8 *txData, UINT16 *rxDataLen, UINT8 *rxData);
/******************************************************************************
* SoftSimInit
* Description: This api called by modem/uiccdrv task to start softsim task if softsim feature is enabled.
* input: void
* output: void
* Comment:
******************************************************************************/
void SoftSimInit(void);
#endif

View File

@@ -0,0 +1,109 @@
/**************************************************************************//**
* @file exception_dump.h
* @brief CMSIS OS Tick header file
* @version V1.0.0
* @date 05. June 2017
******************************************************************************/
/*
* Copyright (c) 2017-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _EXCEPTION_DUMP_H
#define _EXCEPTION_DUMP_H
#include "cmsis_compiler.h"
#include "commontypedef.h"
#include "mem_map.h"
#define MAX_DELAYHHH 0//0xffffff
#define MAX_DELAY 0//0xff
#define DUMP_UART_INSTANCE 0
#define DUMP_SYNC_RSP_LEN 8
//#define DUMP_SYNC_RSP_LEN 2
#define DUMP_RECV_FIFO_LEN 16
#define CMD_FIX_LEN 8
#define CMD_FCS_LEN 4
#define PROTOCOL_RSP_FIX_LEN 8
#define PREAMBLE_CNT 1
#define PREAMBLE_STRING_LEN 10
#define PREAMBLE_WITH_NULL 1
#define MAX_CMD_DATALEN 32 //maximum data size for cmd
#define MAX_READ_DATALEN (48*1024) //maximum data size for cmd
#define MAX_RETRY_COUNT 32
#define DATA_DUMP_WAIT_SYNC_MAX_RETRY_COUNT 10
#define DATA_DUMP_GET_CMD_MAX_RETRY_COUNT 100
#define DUMP_CID 0xdc
#define N_DUMP_CID 0x23
#define READ_ONECE_DATA_LEN 256
#define ACK 0
#define NACK 1
#define GetDataCmd 0x20
#define GetInfoCmd 0x21
#define FinishCmd 0x25
#define WaitPeriod_1s 1000000
#define DUMP_RETRY_CMD_COUNT 1
#define DUMP_RETRY_CMD_RESEND 2
#define DUMP_RETRY_ADDR 0x00C000
#define DUMP_RETRY_COUNT_MAX 2
#define DUMP_END_FLAG_INIT 0xEC00
#define DUMP_END_FLAG_SUCC 0xEC88
typedef struct {
uint32_t ReadDataAddr;
uint32_t ReadLen;
}ReadDataReqCell;
typedef struct {
uint8_t Command;
uint8_t Sequence;
uint8_t CID;
uint8_t NCID;
uint16_t Status;
uint16_t Length;//Length for Data filed
//uint8_t Data[MAX_CMD_DATALEN];
uint32_t FCS;
}DumpRspWrap, *PtrDumpRspWrap;
typedef struct {
uint8_t Command;
uint8_t Sequence;
uint8_t CID;
uint8_t NCID;
uint32_t Length;//Length for Data filed
uint8_t Data[MAX_CMD_DATALEN];
uint32_t FCS;
}DumpReqWrap, *PtrDumpReqWrap;
uint32_t EcDumpTopFlow(void);
#ifdef FEATURE_UART_HELP_DUMP_ENABLE
#define EC_UART_HELP_DUMP_BUFF_LEN 128
uint32_t EcDumpHandshakeProcUart(uint32_t SyncPeriod);
uint32_t EcDumpDataFlowUart(void);
#endif
#endif /* _EXCEPTION_DUMP_H */

View File

@@ -0,0 +1,502 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename:exception_process.h
*
* Description:
*
* History:
*
* Notes:
*
******************************************************************************/
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#ifndef _EXCEPTION_PROCESS_H
#define _EXCEPTION_PROCESS_H
#include "cmsis_compiler.h"
#include "commontypedef.h"
#include "mem_map.h"
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
#define EC_FUNC_CALL_ADDR_DEPTH 4
#define EC_ASSERT_FUNC_CALL_ADDR_DEPTH 4
#define EC_EXCEP_STACK_DEPTH 32
#define EC_EXCEP_SECTOR_SIZE 4096
#define EC_EXCEP_MAGIC_NUMBER (0x00ec00ec)
#define EC_EXCEP_FLASH_SECTOR_BASE EC_EXCEPTION_FLASH_BASE
#define EC_EXCEP_TASK_NAME_LEN 12
#define EC_SP_PSP_FLAG 0x4
#define EC_REG_SYS_CTRL_STATE (*(volatile unsigned int *) (0xE000ED24u))
#define EC_REG_MFSR (*(volatile unsigned int *) (0xE000ED28u))
#define EC_REG_MMAR (*(volatile unsigned int *) (0xE000ED34u))
#define EC_REG_BFSR (*(volatile unsigned int *) (0xE000ED29u))
#define EC_REG_BFAR (*(volatile unsigned int *) (0xE000ED38u))
#define EC_REG_UFSR (*(volatile unsigned int *) (0xE000ED2Au))
#define EC_REG_HFSR (*(volatile unsigned int *) (0xE000ED2Cu))
#define EC_REG_DFSR (*(volatile unsigned int *) (0xE000ED30u))
#define EC_REG_AFSR (*(volatile unsigned int *) (0xE000ED3Cu))
// magic number for fs assert indication "FS_Assert_sF", 12bytes/3 words 0x46535F41 0x73736572 0x745F7346
#define EC_FS_ASSERT_MAGIC_NUMBER0 (0x46535F41)
#define EC_FS_ASSERT_MAGIC_NUMBER1 (0x73736572)
#define EC_FS_ASSERT_MAGIC_NUMBER2 (0x745F7346)
#define EC_FS_ASSERT_REFORMAT_THRESHOLD (10)
#define AT_PORT_UART_INSTANCE (1)
#define RESET_REASON_MAGIC (0xACD20E00)
#define RESET_REASON_MASK (0xFFFFFF00)
#define ACTIVE_RESET_MAGIC (0x5)
#define ACTIVE_RESET_MASK (0xF)
#define FUNC_CALL_TRACE
#define EC_EXCEP_COMPRESS_SIZE 4096
#define EC_EXCEP_COMPRESS_HEAD_OFFSET 4
#define EC_AP_64K_RAM_START_ADDR 0x000
#define EC_AP_64K_RAM_END_ADDR 0x10000
#define EC_AP_64K_RAM_LEN (EC_AP_64K_RAM_END_ADDR - EC_AP_64K_RAM_START_ADDR)
#define EC_AP_125M_RAM_START_ADDR 0x400000
#define EC_AP_125M_RAM_END_ADDR 0x4B0000
#define EC_AP_125M_RAM_CODE_START_ADDR 0x400000
#define EC_AP_125M_RAM_CODE_END_ADDR 0x8000
#define EC_AP_125M_RAM_CODE_LEN (EC_AP_125M_RAM_CODE_END_ADDR - EC_AP_125M_RAM_CODE_START_ADDR)
#define EC_AP_125M_RAM_RW_START_ADDR 0x400000
#define EC_AP_125M_RAM_RW_END_ADDR 0x4B0000
#define EC_AP_125M_RAM_RW_LEN (EC_AP_125M_RAM_RW_END_ADDR - EC_AP_125M_RAM_RW_START_ADDR)
#define EC_CP_64K_RAM_START_ADDR 0x200000
#define EC_CP_64K_RAM_END_ADDR 0x210000
#define EC_CP_64K_RAM_LEN (EC_CP_64K_RAM_END_ADDR - EC_CP_64K_RAM_START_ADDR)
#define EC_CP_125M_RAM_START_ADDR 0x4B0000
#define EC_CP_125M_RAM_END_ADDR 0x4B0000
#define EC_CP_125M_RAM_CODE_START_ADDR 0x4B0000
#define EC_CP_125M_RAM_CODE_END_ADDR 0x4B0000
#define EC_CP_125M_RAM_CODE_LEN (EC_CP_125M_RAM_CODE_END_ADDR - EC_CP_125M_RAM_CODE_START_ADDR)
#define EC_CP_125M_RAM_RW_START_ADDR 0x4B0000
#define EC_CP_125M_RAM_RW_END_ADDR 0x4B0000
#define EC_CP_125M_RAM_RW_LEN (EC_CP_125M_RAM_RW_END_ADDR - EC_CP_125M_RAM_RW_START_ADDR)
#define EC_EXCEPTION_FLASH_BASE FLASH_EXCEP_DUMP_ADDR
#define EC_EXCEPTION_FLASH_BLOCK_NUMBS FLASH_EXCEP_DUMP_SECTOR_NUM // (420KB/105 sectors)
#define EC_EXCEPTION_FLASH_MAX_LEN (EC_EXCEPTION_FLASH_BLOCK_NUMBS*EC_EXCEP_COMPRESS_SIZE) // (424KB)
#define EC_EXCEPTION_AP_RAM_BASE (0x00000)
#define EC_EXCEPTION_AP_RAM_END (0x10000)
#define EC_EXCEPTION_AP_RAM_LEN (EC_EXCEPTION_AP_RAM_END - EC_EXCEPTION_AP_RAM_BASE)
#define EC_EXCEPTION_CP_RAM_BASE (0x200000)
#define EC_EXCEPTION_CP_RAM_END (0x210000)
#define EC_EXCEPTION_CP_RAM_LEN (EC_EXCEPTION_CP_RAM_END - EC_EXCEPTION_CP_RAM_BASE)
#define EC_EXCEPTION_APCP_RAM_BASE (0x400000)
#define EC_EXCEPTION_APCP_RAM_END (0x540000)
#define EC_EXCEPTION_APCP_RAM_LEN (EC_EXCEPTION_APCP_RAM_END - EC_EXCEPTION_APCP_RAM_BASE)
#define EC_EXCEPTION_CP_SHARED_RAM_LEN (0x14000)
#define EC_SHAREDINFO_RAM_END_ADDR (0x53F000)
#define EC_ASSERT_PC_ADDR (EC_SHAREDINFO_RAM_END_ADDR-0x20) // 0x53EFE0
#define EC_ASSERT_LR_ADDR (EC_SHAREDINFO_RAM_END_ADDR-0x18) // 0x53EFE8
#define EC_EXCEPTION_MAGIC_AP_ADDR (EC_SHAREDINFO_RAM_END_ADDR-0x10) // 0x53EFF0
#define EC_EXCEPTION_MAGIC_CP_ADDR (EC_SHAREDINFO_RAM_END_ADDR-0x0C) // 0x53EFF4
#define EC_EXCEPTION_STORE_RAM_ADDR (EC_SHAREDINFO_RAM_END_ADDR-0x8) // 0x53EFF8
#define EC_COMPRESS_FLAG_AP_64K "ec_comp_ap_64k"
#define EC_COMPRESS_FLAG_AP_125M "ec_comp_ap_125m"
#define EC_COMPRESS_FLAG_CP_64K "ec_comp_cp_64k"
#define EC_COMPRESS_FLAG_CP_125M "ec_comp_cp_125m"
#define EC_COMPRESS_ADDR_AP_64K "ec_comp_addr_ap:"
#define EC_COMPRESS_ADDR_CP_64K "ec_comp_addr_cp:"
#define EC_COMPRESS_ADDR_125M "ec_comp_addr_all:"
#define EC_COMPRESS_ADDR_AP_125M "ec_comp_addr_share_ap:"
#define EC_COMPRESS_ADDR_CP_125M "ec_comp_addr_share_cp:"
#define EC_AP_HARDFAULT_TASK_FLAG 0xAF012013
#define EC_AP_ASSERT_TASK_FLAG 0xAA012013
#define EC_AP_HARDFAULT_INT_FLAG 0xAF010129
#define EC_AP_ASSERT_INT_FLAG 0xAA010129
#define EC_AP_HARDFAULT_SMALLIMAGE_FLAG 0xAF019527
#define EC_AP_ASSERT_SMALLIMAGE_FLAG 0xAA019527
#define EC_CP_HARDFAULT_TASK_FLAG 0xCF012013
#define EC_CP_ASSERT_TASK_FLAG 0xCA012013
#define EC_CP_HARDFAULT_INT_FLAG 0xCF010129
#define EC_CP_ASSERT_INT_FLAG 0xCA010129
#define EC_CP_HARDFAULT_SMALLIMAGE_FLAG 0xCF019527
#define EC_CP_ASSERT_SMALLIMAGE_FLAG 0xCA019527
#define EC_EXCEP_TYPE_AP_TASK_HARDFAULT EC_AP_HARDFAULT_TASK_FLAG
#define EC_EXCEP_TYPE_AP_TASK_ASSERT EC_AP_ASSERT_TASK_FLAG
#define EC_EXCEP_TYPE_CP_TASK_HARDFAULT EC_CP_HARDFAULT_TASK_FLAG
#define EC_EXCEP_TYPE_CP_TASK_ASSERT EC_CP_ASSERT_TASK_FLAG
#define EC_EXCEP_TYPE_AP_INT_HARDFAULT EC_AP_HARDFAULT_INT_FLAG
#define EC_EXCEP_TYPE_AP_INT_ASSERT EC_AP_ASSERT_INT_FLAG
#define EC_EXCEP_TYPE_CP_INT_HARDFAULT EC_CP_HARDFAULT_INT_FLAG
#define EC_EXCEP_TYPE_CP_INT_ASSERT EC_CP_ASSERT_INT_FLAG
#define EC_EXCEP_TYPE_AP_SMALLIMAGE_HARDFAULT EC_AP_HARDFAULT_SMALLIMAGE_FLAG
#define EC_EXCEP_TYPE_AP_SMALLIMAGE_ASSERT EC_AP_ASSERT_SMALLIMAGE_FLAG
#define EC_EXCEP_TYPE_CP_SMALLIMAGE_HARDFAULT EC_CP_HARDFAULT_SMALLIMAGE_FLAG
#define EC_EXCEP_TYPE_CP_SMALLIMAGE_ASSERT EC_CP_ASSERT_SMALLIMAGE_FLAG
#define EC_EXCEPTION_START_FLAG 0xEC112013
#define EC_EXCEPTION_END_FLAG 0xEC990129
#define EC_EXCEP_ASSERT_BUFF_LEN 120
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
typedef struct ec_exception_comp_tag
{
uint32_t needCompressAddr;
uint32_t needCompressTotalLen;
uint32_t needCompressOnceLen;
uint32_t compressedBufAddr;
uint32_t compressedBufLen;
uint32_t writeFlashAddr;
uint32_t compressType;
}ec_comp_input;
typedef struct ec_exception_data_tag
{
UINT32 startAddr;
UINT32 compressedLen;
}ec_exception_data;
typedef struct ec_exception_addr_tag
{
uint32_t ap_ram_start_addr;
uint32_t ap_ram_end_addr;
uint32_t cp_ram_start_addr;
uint32_t cp_ram_end_addr;
uint32_t apcp_ram_start_addr;
uint32_t apcp_ram_end_addr;
uint32_t ec_stack_start_addr;
uint32_t ec_stack_end_addr;
uint32_t ec_code_start_addr;
uint32_t ec_code_end_addr;
}ec_exception_addr;
typedef struct _ec_m3_exception_regs
{
struct
{
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t sp;
uint32_t lr;
uint32_t pc;
union
{
uint32_t value;
struct
{
uint32_t IPSR : 8;
uint32_t EPSR : 8;
uint32_t APSR : 8;
}bits;
}psr;
uint32_t exc_return;
uint32_t msp;
uint32_t psp;
uint32_t CONTROL;
uint32_t BASEPRI;
uint32_t PRIMASK;
uint32_t FAULTMASK;
}stack_frame;
union
{
uint32_t value;
struct
{
uint32_t MEM_FAULT_ACT : 1;
uint32_t BUS_FAULT_ACT : 1;
uint32_t UNUSED_BITS1 : 1;
uint32_t USAGE_FAULT_ACT : 1;
uint32_t UNUSED_BITS2 : 3;
uint32_t SVCALLACT : 1;
uint32_t MONITORACT : 1;
uint32_t UNUSED_BITS3 : 1;
uint32_t PENDSVACT : 1;
uint32_t SYSTICKACT : 1;
uint32_t USAGEFAULTPENDED : 1;
uint32_t MEMFAULTPENDED : 1;
uint32_t BUSFAULTPENDED : 1;
uint32_t SVCALLPENDED : 1;
uint32_t MEMFAULT_EN : 1;
uint32_t BUSFAULT_EN : 1;
uint32_t USAGEFAULT_EN : 1;
}bits;
}sys_ctrl_stat;
union
{
uint8_t value;
struct
{
uint8_t IACCVIOL : 1;
uint8_t DACCVIOL : 1;
uint8_t UNUSED_BIT : 1;
uint8_t MUNSTKERR : 1;
uint8_t MSTKERR : 1;
uint8_t MLSPERR : 1;
uint8_t UNUSED_BIT2 : 1;
uint8_t MMARVALID : 1;
}bits;
}mfsr;
union
{
uint8_t value;
struct
{
uint8_t IBUSERR : 1;
uint8_t PRECISEER : 1;
uint8_t IMPREISEER : 1;
uint8_t UNSTKERR : 1;
uint8_t STKERR : 1;
uint8_t LSPERR : 1;
uint8_t UNUSED_BIT : 1;
uint8_t BFARVALID : 1;
}bits;
}bfsr;
union
{
unsigned short value;
struct
{
unsigned short UNDEFINSTR : 1;
unsigned short INVSTATE : 1;
unsigned short INVPC : 1;
unsigned short NOCP : 1;
unsigned short UNUSED_BITS : 4;
unsigned short UNALIGNED : 1;
unsigned short DIVBYZERO : 1;
}bits;
}ufsr;
union
{
uint32_t value;
struct
{
uint32_t UNUSED_BIT1 : 1;
uint32_t VECTBL : 1;
uint32_t UNUSED_BIT2 : 28;
uint32_t FORCED : 1;
uint32_t DEBUGEVT : 1;
}bits;
}hfsr;
union
{
uint32_t value;
struct
{
uint32_t HALTED : 1;
uint32_t BKPT : 1;
uint32_t DWTTRAP : 1;
uint32_t VCATCH : 1;
uint32_t EXTERNAL : 1;
}bits;
}dfsr;
uint32_t mmfar;
uint32_t bfar;
uint32_t afar;
}ec_m3_exception_regs;
typedef struct _ec_exception_store
{
uint32_t ec_start_flag;
uint32_t ec_exception_flag;
uint32_t ec_exception_count;
ec_m3_exception_regs excep_regs;
ec_exception_addr excep_addr;
uint32_t func_call_stack[EC_FUNC_CALL_ADDR_DEPTH];
uint32_t curr_time;
uint32_t excep_step;
uint8_t curr_task_name[EC_EXCEP_TASK_NAME_LEN];
uint8_t ec_assert_buff[EC_EXCEP_ASSERT_BUFF_LEN];
uint32_t ec_end_flag;
}ec_exception_store;
enum
{
excep_r0 = 0,
excep_r1 = 1,
excep_r2 = 2,
excep_r3 = 3,
excep_r12 = 4,
excep_lr = 5,
excep_pc = 6,
excep_psr = 7,
};
typedef enum EXCEPTION_CONFIG_OPTION
{
EXCEP_OPTION_DUMP_FLASH_EPAT_LOOP, /*0 -- dump full exception info to flash and EPAT tool then trapped in endless loop(while(1))*/
EXCEP_OPTION_PRINT_RESET, /*print necessary exception info, and then reset*/
EXCEP_OPTION_DUMP_FLASH_RESET, /*dump full exception info to flash, and then reset*/
EXCEP_OPTION_DUMP_FLASH_EPAT_RESET, /*dump full exception info to flash and EPAT tool, and then reset*/
EXCEP_OPTION_SILENT_RESET, /*reset directly*/
EXCEP_OPTION_DUMP_FLASH_EPAT_LOOP_AND_UART_HELP_DUMP = 10, /*10 -- enable uart help dump and dump full exception info to flash and EPAT tool then trapped in endless loop(while(1))*/
EXCEP_OPTION_DUMP_FLASH_EPAT_RESET_AND_UART_HELP_DUMP = 13, /*13 -- enable uart help dump and dump full exception info to flash and EPAT tool, and then reset*/
EXCEP_OPTION_MAX
}ExcepConfigOp;
enum
{
reg_r0 = 0,
reg_r1,
reg_r2,
reg_r3,
reg_r4,
reg_r5,
reg_r6,
reg_r7,
reg_r8,
reg_r9,
reg_r10,
reg_r11,
reg_r12,
reg_sp,
reg_lr,
reg_pc,
};
typedef enum
{
EC_RAM_COMP_NORMAL = 0,
EC_AP_64K_RAM_COMP = 1,
EC_AP_125M_RAM_COMP,
EC_CP_64K_RAM_COMP,
EC_CP_125M_RAM_COMP,
}ecRamCompType;
typedef enum
{
EC_CORE_TYPE_AP = 1,
EC_CORE_TYPE_CP = 2,
}ecCoreType;
typedef enum
{
EC_CHIP_TYPE_EC616 = 0x616,
EC_CHIP_TYPE_EC618 = 0x618,
}ecChipType;
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS DECLEARATION *
*----------------------------------------------------------------------------*/
#if defined ( __CC_ARM )
extern unsigned int __current_pc(void); // arm_cc used to get pc, it cannot get pc directly
extern unsigned int __current_sp(void); // arm_cc used to get sp
#elif defined(__GNUC__)
void *__current_pc(void);
#endif
void ecRecordNodeInit(void);
void excepCheckFaultType(ec_m3_exception_regs *excep_regs);
void excepShowStackFrame(ec_m3_exception_regs *excep_regs);
extern void excepEcAssert(const char *func, uint32_t line, uint32_t v1, uint32_t v2, uint32_t v3);
void excepGetTaskInfo(void);
void excepCleanInExcephandler(void);
BOOL excepIsInExcephandler(void);
BOOL excepIsFsAssert(void);
BOOL excepDumpCheckPoint(uint8_t id);
#if defined ( __CC_ARM )
//extern __inline void ec_assert_regs(void);
extern __INLINE __asm void ec_assert_regs(void);
extern void excepPrintAssertInfo(const char *func, uint32_t line, const char *file, uint32_t v1, uint32_t v2, uint32_t v3);
#ifdef EC_ASSERT_FLAG
#define EC_ASSERT(x,v1,v2,v3) \
do { \
{ \
if((x) == 0) \
{ \
ec_assert_regs(); \
*((unsigned int *)EC_ASSERT_PC_ADDR) = __current_pc(); \
*((unsigned int *)EC_ASSERT_LR_ADDR) = __GET_RETURN_ADDRESS(); \
excepEcAssert(__FUNCTION__, __LINE__, (uint32_t)(v1),(uint32_t)(v2),(uint32_t)(v3)); \
while(1); \
}\
} \
} while(0)
#else
#define EC_ASSERT(x,v1,v2,v3) \
do { \
{ \
if((x) == 0) \
{ \
printf("Assert, func:%s, file: %s, line: %d, val: 0x%x,0x%x,0x%x \r\n", __FUNCTION__, __FILE__, __LINE__, (uint32_t)(v1),(uint32_t)(v2),(uint32_t)(v3)); \
__disable_irq();\
while(1);\
}\
} \
} while(0)
#endif
#elif defined(__GNUC__)
extern void ec_assert_regs(void);
#define EC_ASSERT(x,v1,v2,v3) \
do { \
{ \
if((x) == 0) \
{ \
ec_assert_regs(); \
excepEcAssert(__FUNCTION__, __LINE__, (uint32_t)(v1),(uint32_t)(v2),(uint32_t)(v3)); \
while(1); \
}\
} \
} while(0)
#endif
#ifdef FEATURE_DUMP_CHECK
#define EXCEP_CHECK_POINT(ID) excepDumpCheckPoint(ID)
#endif
#endif /* _EXCEPTION_H */

View File

@@ -0,0 +1,243 @@
#ifndef __SCT_AES_SHA_API_H__
#define __SCT_AES_SHA_API_H__
/******************************************************************************
******************************************************************************
Copy right: 2017-, Copyrigths of AirM2M Ltd.
File name: sct_aes_sha_api.h
Description: SCT AES/SHA API, external, and provide to app
History: 2020/12/02 Originated by Jason
******************************************************************************
******************************************************************************/
#include "osasys.h"
/******************************************************************************
*****************************************************************************
* MARCO
*****************************************************************************
******************************************************************************/
/******************************************************************************
*****************************************************************************
* STRUCT
*****************************************************************************
******************************************************************************/
typedef enum
{
SCT_AES_SHA_RET_OK = 0,
SCT_AES_SHA_ERROR = -1,
SCT_AES_SHA_BUSY = -2
}SctAesShaRetEnum;
typedef INT32 SctAesShaRet;
/*
* AES mode, same enum as: DescAESMode
*/
typedef enum
{
SCT_AES_ECB = 0,
SCT_AES_CBC = 1,
SCT_AES_CTR = 2
}SctAESMode;
/*
* AES PAD MODE, same enum as: DescAESPadMode
*/
typedef enum
{
/*
0 - No Padding, should: dataLen%16 == 0
1 - PKCS7, paddingLen = 16 <20>C dataLen%16, paddingValue = k
2 <20>C PaddingOneZeros (ISO/IEC 7816-4), paddingLen = 16 <20>C dataLen%16, paddingValue = 0x80,0x00,<2C><>..0x00
3 - PaddingZerosLen (ANSI X.923), paddingLen = 16 <20>C dataLen%16, paddingValue = 0x00,0x00,<2C><>..k
4 - PaddingZeros, paddingLen = 16 <20>C dataLen%16, paddingValue = 0x00,0x00,<2C><>..0x00
*/
SCT_AES_NO_PAD = 0,
SCT_AES_PKCS7_PAD = 1,
SCT_AES_ONE_ZEROS_PAD = 2,
SCT_AES_ZERO_LEN_PAD = 3,
SCT_AES_ZERO_PAD = 4
}SctAESPadMode;
/*
* AES Key source, same enum as: DescAESKeySelect
*/
typedef enum
{
SCT_AES_CK_FROM_ADDR = 0,
SCT_AES_CK_FROM_EFUSE = 1
}SctAESKeySelect;
/*
* AES CK len, same enum as: DescAESCKLen
*/
typedef enum
{
/* If key is from flash, only support length: 128/192 */
SCT_AES_CK_LEN_128 = 0,
SCT_AES_CK_LEN_192 = 1,
SCT_AES_CK_LEN_256 = 2
}SctAESCKLen;
/*
* AES DIR
* AESDIR is useless (default set to 0) for CTR (2) AES mode
*/
typedef enum
{
SCT_AES_ENC_DIR = 0, /* Encryption */
SCT_AES_DEC_DIR = 1 /* Decryption */
}SctAESDir;
/*
* endian
*/
typedef enum
{
SCT_LITTLE_ENDIAN = 0,
SCT_BIG_ENDIAN = 1
}SctEndianType;
/*
* SHA MODE, same enum as: DescSHAMode
*/
typedef enum
{
SCT_SHA_1 = 0, /* SHA output: 20 bytes */
SCT_SHA_224 = 1, /* SHA output: 28 bytes */
SCT_SHA_256 = 2 /* SHA output: 32 bytes */
}SctSHAMode;
/*
* SCT AES cipher request
*/
typedef struct
{
UINT32 inputByteLen : 16; /* AES input data length */
UINT32 aesMode : 2; /* SctAESMode: ECB/CBC/CTR */
UINT32 aesPadMode : 3; /* SctAESPadMode, For CTR mode, useless, set to 0 */
UINT32 ckSelect : 1; /* SctAESKeySelect, CK select from: "ckAddr", or from eFUSE */
UINT32 ckLen : 2; /* SctAESCKLen: 128/192/256, if CK select from eFUSE, only support: 128/192 */
UINT32 dir : 1; /* SctAESDir, Encryption/Decryption. For CTR mode, useless, set to 0 */
UINT32 ckBLEndian : 1; /* SctEndianType, if not certain/known, suggest big endian: DESC_BIG_ENDIAN */
UINT32 ivBLEndian : 1; /* SctEndianType, if not certain/known, suggest big endian: DESC_BIG_ENDIAN */
UINT32 : 5;
UINT8 *pInput; /* Input */
UINT8 *pOutput; /* Output */
UINT8 *pCkAddr; /* Ignore it, if key select from eFUSE. and must 4 bytes aligned */
UINT8 *pIvAddr; /* initial vector,
* Note:
* a) for CBC(AESMode = 1) mode, initial vector address
* b) for CTR(AESMode = 2) mode, initial counter address,
* c) Must 4 bytes aligned, and total 16 bytes
*/
}SctAesReq; //20 bytes
/******************************************************************************
*****************************************************************************
* Functions
*****************************************************************************
******************************************************************************/
/*****************************************************************************
* Two types of SHA API
* 1> SHA segment API, which SHA input datas could be divided serveral segments
*
* 2> SHA whole API, all SHA datas input once.
*****************************************************************************/
/*******
* 1> SHA segment API
*******/
/*
* SHA start
*/
/******************************************************************************
* SctShaSegStart
* Description: SHA segment API, which SHA input datas could be divided serveral segments,
* SHA start and lock the SCT HW, before SHA done (called by SctShaSegEnd()),
* SHA HW can't used by other modules
* input: SctSHAMode shaMode //SHA mode
* const UINT8 *shaHdr //SHA header, which also need to calc SHA before input data, if none, input PNULL
* UINT16 shaHdrByteLen //SHA header byte length
* output: SctShaRet
* Note: "pShaHdr" should be freed in caller, after "SctShaSegEnd()" called
******************************************************************************/
SctAesShaRet SctShaSegStart(SctSHAMode shaMode, const UINT8 *pShaHdr, UINT16 shaHdrByteLen);
/******************************************************************************
* SctShaAppendSeg
* Description: SHA segment API, calc SHA
* input: SctSHAMode shaMode //SHA mode
* const UINT8 *pInput //SHA input source data
* UINT16 inputLen //SHA input source data length
* output: SctShaRet
******************************************************************************/
SctAesShaRet SctShaAppendSeg(SctSHAMode shaMode, const UINT8 *pInput, UINT16 inputLen);
/******************************************************************************
* SctShaSegEnd
* Description: SHA segment API, end SHA calc
* input: SctSHAMode shaMode //SHA mode
* SctEndianType outBLType //output, big/little endian, if not known, suggest BIG endian
* UINT8 shaOutput[32] //output, SHA value
* output: SctShaRet
******************************************************************************/
SctAesShaRet SctShaSegEnd(SctSHAMode shaMode, SctEndianType outBLType, UINT8 shaOutput[32]);
/********
* 2. SHA whole API, all SHA datas input once.
********/
/******************************************************************************
* SctShaCalc
* Description: SHA whole API, all SHA datas input once
* input: SctSHAMode shaMode //SHA mode
* const UINT8 *pInput //pInput data
* UINT16 inputLen //input data length in byte
* const UINT8 *pShaHdr //SHA header, which also need to calc SHA before input data, if none, input PNULL
* UINT16 shaHdrByteLen //SHA header length in byte
* SctEndianType outBLType //big/little endian, if not known, suggest BIG endian
* UINT8 shaOutput[32] //output, SHA value
* output: SctShaRet
******************************************************************************/
SctAesShaRet SctShaCalc(SctSHAMode shaMode,
UINT8 *pInput,
UINT16 inByteLen,
UINT8 *pShaHdr,
UINT16 shaHdrByteLen,
SctEndianType outBLType,
UINT8 shaOutput[32]);
/*****************************************************************************
* AES API
*****************************************************************************/
/******************************************************************************
* SctAesCalc
* Description: AES encrypt/decrypt calculation
* input: SctAesReq *pAesReq
* output: SctShaRet
******************************************************************************/
SctAesShaRet SctAesCalc(SctAesReq *pAesReq);
#endif

View File

@@ -0,0 +1,141 @@
#ifndef __SCT_PPP_CRC_API_H__
#define __SCT_PPP_CRC_API_H__
/******************************************************************************
******************************************************************************
Copy right: 2017-, Copyrigths of AirM2M Ltd.
File name: sct_ppp_crc_api.h
Description: SCT PPP EEA and CRC API, which provide to app
History: 2022/02/08 Originated by Jason
******************************************************************************
******************************************************************************/
#include "osasys.h"
/******************************************************************************
*****************************************************************************
* MARCO
*****************************************************************************
******************************************************************************/
/*
* UINT32 * 8 = 256 bits
*/
#define SCT_PPP_ACCM_TABLE_WORD_SIZE 8
typedef enum
{
SCT_PPP_RET_OK = 0,
SCT_PPP_ERROR = -1,
SCT_PPP_BUSY = -2,
SCT_PPP_INVALID_INPUT = -3
}SctPppRetEnum;
typedef INT32 SctPppRet;
/******************************************************************************
*****************************************************************************
* STRUCT
*****************************************************************************
******************************************************************************/
/******************************************************************************
*****************************************************************************
* Functions
*****************************************************************************
******************************************************************************/
/*
* PPP escape ACCM table config
*/
void SctPppEscapeAccmConfig(UINT32 pppAccmTbl[SCT_PPP_ACCM_TABLE_WORD_SIZE]);
/*
* PPP de-escape ACCM table config
*/
void SctPppDeEscapeAccmConfig(UINT32 pppAccmTbl[SCT_PPP_ACCM_TABLE_WORD_SIZE]);
/******************************************************************************
* SctPppEscapeCalcSize
* Description: calc PPP escape PKG size/length in bytes
* input: const DlPduBlock *pHead //input, a list, one PDU one PPP raw packet
* UINT32 *pOutList //output, should be a UINT32 array, escape pkg size for each PDU, and must 4 bytes aligned
* UINT32 listSize //input, "pOutList" array size
* DlPduBlock **pRetNext //output, if PDU number in input: "pHead" > "listSize", then not all PDU could calc escaped size, then output here
* output: INT32 //succ return 0, or return < 0
* Comment:
* 1> PPP raw pkg (DlPduBlock) input format:
* +-------+---------------------+
* |PPP hdr| data |
* +-------+---------------------+
* 2> \PPP escape pkg format: \
* +--+-------------------------------+-----+--+
* |7E| escaped PPP pkg | CRC |7E|
* +--+-------------------------------+-----+--+
* |<-------------- output size -------------->|
* 3> if "pOutList[n]" set to 0, means last PKG
* 4> !!!!!! "pOutList" must be __ALIGNED(4) !!!!!!
******************************************************************************/
SctPppRet SctPppEscapeCalcSize(DlPduBlock *pHead, UINT32 *pOutList, UINT32 listSize, DlPduBlock **pRetNext);
/******************************************************************************
* SctPppEscape
* Description: PPP escape: add "7E" and CRC
* input: const DlPduBlock *pHead //input, a list, one PDU one PPP raw packet
* DlPduBlock *pEscapeHead //ouput, output buffer should allocated in caller
* output: INT32 //succ return 0, or return < 0
* Comment:
* 1> PPP raw pkg (DlPduBlock) input format:
* +-------+---------------------+
* |PPP hdr| data |
* +-------+---------------------+
* 2> \output PPP escape pkg format: \
* +--+-------------------------------+-----+--+
* |7E| escaped PPP pkg | CRC |7E|
* +--+-------------------------------+-----+--+
* |<------ pEscapeHead->length -------------->|
* ^pEscapeHead->pPdu
* Note:
* a) Caller should call: SctPppEscapeCalcSize() to calc the escaped pkg size;
* b) then alloc the buffer (maybe from DLFC) according to the escaped pkg size;
* c) finally call this API: SctPppEscape() to do PPP escape, and the escaped pkg size
* will be checked again in this API, to avoid a bug cause overflow
******************************************************************************/
SctPppRet SctPppEscape(const DlPduBlock *pHead, DlPduBlock *pEscapeHead);
/******************************************************************************
* SctPppDeEscape
* Description: PPP deescape
* input: const UlPduBlock *pHead //input, a list, PPP pkg start and end with "7E"
* UlPduBlock *pDeEscapeHead //ouput, output buffer should allocated in caller
* output: INT32 //succ return 0, or return < 0
* Comment:
* 1> PPP pkg (UlPduBlock) input format: //note, PKG should start and end with "7E" (will check in this API)
* +--+-------------------------------+-----+--+
* |7E| escaped PPP pkg | CRC |7E|
* +--+-------------------------------+-----+--+
* 2> |output PPP deescape pkg format: /
* +-------+----------------------+-----+
* |PPP hdr| data | CRC |
* +-------+----------------------+-----+
* |<------ pDeEscapeHead->length ----->|
* ^pDeEscapeHead->ptr
* 3> If CRC checked failed, "pDeEscapeHead->pppCrcNok" set to 1
* Note:
* a) The caller should be pre-alloc the buffer in "pDeEscapeHead", use to fill
* de-escaped pkg. And the pre-alloc buffer size should be estimated big enough, suggest
* equal the input escaped pkg size.
* b) After de-escaped in this API, de-escaped pkg size will be checked and set to
* the actually value.
* c) In some case, the caller can't input the header "7E", so we don't check it as mandatory
******************************************************************************/
SctPppRet SctPppDeEscape(const UlPduBlock *pHead, UlPduBlock *pDeEscapeHead);
#endif

View File

@@ -0,0 +1,67 @@
#ifndef _SYS_RECORD_H
#define _SYS_RECORD_H
#define EC_TRACE_SCHEDULE_RECORD 1
#define EC_TRACE_SCHEDULE_PRINT 1
#define RECORD_LIST_LEN 30
#define RECORD_LIST_NAME_LEN 4
typedef enum ecRecordType_enum
{
EC_RECORD_TYPE_RESV = 0,
EC_RECORD_TYPE_USB = 1,
EC_RECORD_TYPE_XIC = 2,
EC_RECORD_TYPE_TASK = 3,
EC_RECORD_TYPE_MAX,
}ecRecordType;
typedef enum ecRecordPrintType_enum
{
EC_RECORD_PRINT_RESV = 0,
EC_RECORD_PRINT_IN = 1,
EC_RECORD_PRINT_OUT = 2,
EC_RECORD_PRINT_MAX,
}ecRecordPrintType;
typedef union
{
UINT32 ecNVICAndResv; // NVIC(0-14)---U16 resv(0xFFFF)---U16
UINT32 ecXicModuleAndIdx; // xic module(0-2)---U16 idx(0-31)---U16
CHAR ecRecordName[RECORD_LIST_NAME_LEN]; //
}ecInterInfo;
typedef struct _recordNodeList
{
ecInterInfo ecInterInfos;
UINT32 ecInTime;
}ecRecordNodeList;
typedef struct _recordNodeParam
{
UINT32 ecRecordType;
UINT32 ecLogInOrOut;
UINT32 ecNVIC;
UINT32 ecResv;
UINT32 ecInTime;
UINT32 ecXicModule;
UINT32 ecInterruptIdx;
UINT32 ecInterruptType;
}vRecordParam;
void ecTraceUsbIntOut(void);
void ecTraceUsbIntIn(void);
void ecTraceXicIntOut(INT32 module, INT32 idx);
void ecTraceXicIntIn(INT32 module, INT32 idx);
void vTracePrintSchedule(vRecordParam recordParam);
void vTraceScheduleRecord(vRecordParam recordParam);
#endif

View File

@@ -0,0 +1,81 @@
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include <string.h>
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
#define UNALIGNED(x) ((uint32_t)x & 0x3)
#define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS *
*----------------------------------------------------------------------------*/
/*
* Reference: https://github.com/eblot/newlib/blob/master/newlib/libc/string/strlen.c
*/
int32_t strlen_fast(const char *str)
{
const char *start = str;
uint32_t* aligned_addr;
while(UNALIGNED(str))
{
if(!*str)
{
return str - start;
}
str++;
}
aligned_addr = (uint32_t*)str;
while(!DETECTNULL(*aligned_addr))
{
aligned_addr++;
}
str = (char *)aligned_addr;
while(*str)
{
str++;
}
return str - start;
}
/*
* Reference: http://src.gnu-darwin.org/src/lib/libc/string/strnstr.c.html
*/
char* ec_strnstr(const char *s, const char *find, size_t slen)
{
char c, sc;
size_t len;
if((c = *find++) != '\0')
{
len = strlen(find);
do
{
do
{
if((sc = *s++) == '\0' || slen-- < 1)
return NULL;
} while(sc != c);
if(len > slen)
return NULL;
} while(strncmp(s, find, len) != 0);
s--;
}
return (char*)s;
}

View File

@@ -0,0 +1,200 @@
/******************************************************************************
Copyright: - 2017, All rights reserved by AirM2M Ltd.
File name: - ecuiccapi.c
Description: - UICC open API.
Function List: -
History: - 09/20/2022, Originated by xlhu
******************************************************************************/
/******************************************************************************
* Include Files
*******************************************************************************/
#include "cmsis_os2.h"
#include "FreeRTOS.h"
#include "task.h"
#include "os_common.h"
#include DEBUG_LOG_HEADER_FILE
#include "debug_trace.h"
#include "ecuiccapi.h"
/*********************************************************************************
* Macros
*********************************************************************************/
/******************************************************************************
* Extern global variables
*******************************************************************************/
/******************************************************************************
* Extern functions
*******************************************************************************/
/******************************************************************************
* Global variables
*******************************************************************************/
/*
* bSoftSIMTaskCreate
* Whether the SoftSIM task created.
*/
BOOL bSoftSIMTaskCreate = FALSE;
/******************************************************************************
* Types
*******************************************************************************/
/******************************************************************************
* Local variables
*******************************************************************************/
/******************************************************************************
* Function Prototypes
*******************************************************************************/
/******************************************************************************
* Function definition
*******************************************************************************/
#define __DEFINE_SOFTSIM_ADAPT_FUNCTION__ //just for easy to find this position in SS
/******************************************************************************
* SoftSIM interface adapted note
* 1> The SoftSIM feature is disable as default, and enabled by AT+ECSIMCFG="softsim",1
* 2> SoftSIM task shall be created in SoftSimInit func or appinit depended by softsim vender.
* 3> SoftSIM vender shall adapt functions SoftSimReset/SoftSimApduReq.
*******************************************************************************/
/******************************************************************************
* SoftSimReset
* Description: This API called by modem/uiccdrv task to reset softsim and get ATR parameter from softsim,
* as same as code/warm reset with physical SIM card.
* param[in] null
* param[out] UINT16 *atrLen, the pointer to the length of ATR, this memory don't need to be free.
* param[out] UINT8 *atrData, the pointer to the ATR data, this memory don't need to be free.
* atrData buffer size is 33, fill atrData shall not exceed 33 bytes.
* Comment: This API will be called only if softsim feature is enabled by AT CMD.
* Shall send signal/msg to softsim task and block to wait response .
* Softsim internal process running in this func is not allowed.
******************************************************************************/
void SoftSimReset(UINT16 *atrLen, UINT8 *atrData)
{
osSemaphoreId_t sem = osSemaphoreNew(1U, 0, PNULL);
osStatus_t osState = osOK;
/*
* softsim vender shall implement 3 steps as below
*/
/*
* 1> create signal/msg
*/
/*
* 2> send signal/msg to softsim task with sem/atrLen/atrData
*/
/*
* 3> process signal/msg on softsim task, then retrun paramters and release sem on softsim task
*/
/*
* wait for sem 2sec
*/
if ((osState = osSemaphoreAcquire(sem, 2000)) != osOK)
{
OsaDebugBegin(FALSE, osState, 0, 0);
OsaDebugEnd();
}
/*
* Semaphore delete
*/
osSemaphoreDelete(sem);
}
/******************************************************************************
* SoftSimApduReq
* Description: This API will be called by modem/uiccdrv task to send APDU(TPDU) request and get response from softsim,
* support case 1/2/3/4 command/response process.
* param[in] UINT16 txDataLen, the length of tx data
* param[in] UINT8 *txData, the pointer to the tx data, this memory don't need to be free.
* param[out] UINT16 *rxDataLen, the pointer to the length of rx data, this memory don't need to be free.
* param[out] UINT8 *rxData, the pointer to the rx data, this memory don't need to be free.
* rxData buffer size is 258, fill rxData shall not exceed 258 bytes.
* Comment: This API will be called only if softsim feature is enabled by AT CMD.
* Shall send signal/msg to softsim task and block to wait response.
* Softsim internal process running in this func is not allowed.
******************************************************************************/
void SoftSimApduReq(UINT16 txDataLen, UINT8 *txData, UINT16 *rxDataLen, UINT8 *rxData)
{
osSemaphoreId_t sem = osSemaphoreNew(1U, 0, PNULL);
osStatus_t osState = osOK;
/*
* softsim vender shall implement 3 steps as below
*/
/*
* 1> create signal/msg
*/
/*
* 2> send signal/msg to softsim task with sem/txDataLen/txData/rxDataLen/rxData
*/
/*
* 3> process signal/msg on softsim task, then retrun paramters and release sem on softsim task
*/
/*
* wait for sem 2sec
*/
if ((osState = osSemaphoreAcquire(sem, 2000)) != osOK)
{
OsaDebugBegin(FALSE, osState, 0, 0);
OsaDebugEnd();
}
/*
* Semaphore delete
*/
osSemaphoreDelete(sem);
}
/******************************************************************************
* SoftSimInit
* Description: This api called by modem/uiccdrv task to start softsim task if softsim feature is enabled.
* input: void
* output: void
* Comment:
******************************************************************************/
void SoftSimInit(void)
{
if (bSoftSIMTaskCreate == TRUE)
{
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, SoftSimInit_0, P_INFO, "Softsim task has already been created");
return;
}
/*
* start softsim task
*/
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, SoftSimInit_1, P_INFO, "Start softsim task");
/*
* softsim vender implement softsim task created
*/
//delay 100ms for softsim task init
osDelay(100);
//set flag after task created
bSoftSIMTaskCreate = TRUE;
}

View File

@@ -0,0 +1,781 @@
#include "stdio.h"
#include "string.h"
#include "uart.h"
#if FEATURE_CCIO_ENABLE
#include "usb_device.h"
#endif
#include DEBUG_LOG_HEADER_FILE
#include "mem_map.h"
#include "exception_process.h"
#include "hal_dumpMedia.h"
#include "exception_dump.h"
#include "plat_config.h"
#ifdef FEATURE_UART_HELP_DUMP_ENABLE
int *excepStepDump = (int *)0x404008;
uint32_t excepCfgOption = 0xff;
#define EcDumpGetUartDumpModeId(ownerId, moduleId, subId) (ownerId##__##moduleId##__##subId)
#endif
extern int *excepStep;
int excepDumpEndFlag = DUMP_END_FLAG_INIT;
uint32_t dumpRetryReadCount = MAX_RETRY_COUNT;
uint32_t dumpHandshakeRetryCnt = MAX_RETRY_COUNT;
uint32_t dumpWaitSyncRetryCnt = DATA_DUMP_WAIT_SYNC_MAX_RETRY_COUNT;
uint32_t dumpGetCmdRetryCnt = DATA_DUMP_GET_CMD_MAX_RETRY_COUNT;
const uint8_t dump_handshake_code[]= "enter assert dump mode";
const uint8_t dump_response_code[]= "ok";
const uint8_t PreambleDumpString[PREAMBLE_STRING_LEN] = {0x44, 0x55, 0x4d, 0x50, 0x44, 0x55, 0x4d, 0x50, 0xd, 0xa};
const uint16_t wCRCTableAbs[] =
{
0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400,
};
uint32_t tDataInfoCell [][2]=
{
{EC_EXCEPTION_AP_RAM_BASE, EC_EXCEPTION_AP_RAM_LEN},
{EC_EXCEPTION_CP_RAM_BASE, EC_EXCEPTION_CP_RAM_LEN},
{EC_EXCEPTION_APCP_RAM_BASE, EC_EXCEPTION_APCP_RAM_LEN},
};
extern void delay_us(uint32_t us);
extern void usbc_trace_disable(void);
int excepDelay(uint32_t maxDelay)
{
int i=0;
int j=0;
for(i=0; i<maxDelay; i++)
{
if(i==0xfff)
{
j = maxDelay+2;
}
}
return j;
}
uint32_t EcDumpCheckIfNeedRetry(uint32_t cmdType, PtrDumpReqWrap dumpReqWrap, PtrDumpReqWrap dumpReqWrapTemp)
{
ReadDataReqCell * ptrReadDataReqCell;
ReadDataReqCell * ptrReadDataReqCellTemp;
switch(cmdType)
{
case DUMP_RETRY_CMD_COUNT:
*excepStep = (*excepStep | 0x10000000);
ptrReadDataReqCell = (ReadDataReqCell*)(&(dumpReqWrap->Data[0]));
ptrReadDataReqCellTemp = (ReadDataReqCell*)(&(dumpReqWrapTemp->Data[0]));
if(ptrReadDataReqCell->ReadDataAddr == ptrReadDataReqCellTemp->ReadDataAddr)
{
dumpRetryReadCount++;
}
else
{
dumpRetryReadCount = 0;
memcpy(dumpReqWrapTemp, dumpReqWrap, sizeof(DumpReqWrap));
}
break;
case DUMP_RETRY_CMD_RESEND:
*excepStep = (*excepStep | 0x20000000);
if(dumpRetryReadCount >= DUMP_RETRY_COUNT_MAX)
{
ptrReadDataReqCell = (ReadDataReqCell*)(&dumpReqWrap->Data);
memset((void *)DUMP_RETRY_ADDR, 0, ptrReadDataReqCell->ReadLen);
memcpy((void *)DUMP_RETRY_ADDR, (void *)ptrReadDataReqCell->ReadDataAddr, ptrReadDataReqCell->ReadLen);
ptrReadDataReqCell->ReadDataAddr = DUMP_RETRY_ADDR;
}
break;
}
return 0;
}
static uint16_t EcDumpCRC16(uint16_t wCRC, uint8_t *pchMsg, uint16_t wDataLen)
{
//uint16_t wCRC = 0xFFFF;
uint16_t i;
uint8_t chChar;
for (i = 0; i < wDataLen; i++)
{
chChar = *pchMsg++;
wCRC = wCRCTableAbs[(chChar^wCRC)&15]^(wCRC>>4);
wCRC = wCRCTableAbs[((chChar >>4)^ wCRC)&15]^(wCRC>>4);
}
return wCRC;
}
uint32_t VerifyPreamble(uint8_t *Preamble)
{
uint32_t idx;
uint32_t CheckCnt = 0;
for (idx = 0; idx < sizeof(PreambleDumpString); idx++)
{
if (PreambleDumpString[idx] == Preamble[idx]) {
CheckCnt++;
}
}
if (CheckCnt>1)
{
return TRUE;
}
return FALSE;
}
uint32_t EcDumpWaitSync(void)
{
uint8_t idx = 0;
uint8_t RecChar[DUMP_RECV_FIFO_LEN];
uint8_t RetValue = 0;
uint8_t epNum = 0xff;
uint32_t instance;
uint32_t instanceTemp;
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
instance = DUMP_UART_INSTANCE;
instanceTemp = instance;
eehDumpMediaFlush(UART_0_FOR_UNILOG);//flush RX FIFO is better to avoid left hdsk data, only for UART
}
else
{
instance = (uint32_t)usbDevGetLogIfIdx();
epNum = usbDevGetEpNumFromIf(usbDevGetLogIfIdx());
instanceTemp = (epNum&0xf);
extern void usbc_ctrl_full_flush_txfifo (uint32_t num );
usbc_ctrl_full_flush_txfifo((epNum>>4)&0xf);
}
delay_us(400000);//wait and let EPAT change its baudrate
for (idx = 0; idx < PREAMBLE_CNT; idx++)
{
RetValue = eehDumpMediaSend(instance, (uint8_t *)&PreambleDumpString[0], PREAMBLE_STRING_LEN, 1000);
if (RetValue != PREAMBLE_STRING_LEN)
{
*excepStep = (*excepStep | 0x8);
return 1;
}
}
//Host send Preamble twice
RetValue = eehDumpMediaRecv(instanceTemp, &RecChar[0], PREAMBLE_CNT*PREAMBLE_STRING_LEN-2 + PREAMBLE_WITH_NULL, WaitPeriod_1s);
if(RetValue > 0)
{
eehDumpMediaSend(instance, &RecChar[0], RetValue, 1000);
}
if (RetValue != (PREAMBLE_CNT*PREAMBLE_STRING_LEN+PREAMBLE_WITH_NULL-2))
{
*excepStep = (*excepStep | 0x10);
return 1;
}
if (VerifyPreamble(&RecChar[0]) ||VerifyPreamble(&RecChar[4]))
{
*excepStep = (*excepStep | 0x20);
return 0;
}
*excepStep = (*excepStep | 0x40);
return 1;
}
uint32_t EcDumpWaitCmd(PtrDumpReqWrap ptrDumpReqWrap)
{
uint32_t RetValue = 0;
uint8_t epNum;
uint32_t instance;
uint32_t instanceTemp;
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
instance = DUMP_UART_INSTANCE;
instanceTemp = instance;
}
else
{
instance = (uint32_t)usbDevGetLogIfIdx();
epNum = usbDevGetEpNumFromIf(usbDevGetLogIfIdx());
instanceTemp = (epNum&0xf);
}
RetValue = eehDumpMediaRecv(instanceTemp, (uint8_t *)ptrDumpReqWrap, CMD_FIX_LEN, WaitPeriod_1s);
if (RetValue != CMD_FIX_LEN)
{
*excepStep = (*excepStep | 0x100);
return 1;
}
if (ptrDumpReqWrap->Length > MAX_CMD_DATALEN)
{
ptrDumpReqWrap->Length = MAX_CMD_DATALEN;
}
#if 1
RetValue = eehDumpMediaRecv(instanceTemp, (uint8_t *)(&ptrDumpReqWrap->Data[0]), ptrDumpReqWrap->Length, WaitPeriod_1s);
if (RetValue != ptrDumpReqWrap->Length)
{
*excepStep = (*excepStep | 0x200);
return 1;
}
RetValue = eehDumpMediaRecv(instanceTemp, (uint8_t *)(&ptrDumpReqWrap->FCS), CMD_FCS_LEN, WaitPeriod_1s);
if (RetValue != CMD_FCS_LEN)
{
*excepStep = (*excepStep | 0x400);
return 1;
}
#endif
*excepStep = (*excepStep | 0x800);
return 0;
}
uint32_t EcDumpCheckCmd(PtrDumpReqWrap ptrDumpReqWrap)
{
uint32_t sum = 0;
uint8_t * pStartAddr;
if ((ptrDumpReqWrap->CID != DUMP_CID) ||(ptrDumpReqWrap->NCID != N_DUMP_CID))
{
*excepStep = (*excepStep | 0x1000);
return 1;
}
pStartAddr = (uint8_t*) (&ptrDumpReqWrap->Command);
sum = EcDumpCRC16(0xFFFF, pStartAddr, CMD_FIX_LEN + ptrDumpReqWrap->Length);
if (sum != ptrDumpReqWrap->FCS)
{
//return 0;//test now , no check sum
*excepStep = (*excepStep | 0x2000);
return 1;
}
*excepStep = (*excepStep | 0x4000);
return 0;
}
uint32_t EcDumpHandleGetData(PtrDumpReqWrap ptrDumpReqWrap)
{
uint32_t RetValue = 0;
DumpRspWrap tDumpRspWrap;
ReadDataReqCell * ptrReadDataReqCell;
uint32_t Sum = 0xFFFF;
uint32_t Idx;
uint32_t *DataBuff;
uint32_t instance;
uint32_t sendDataLenLeft;
uint32_t sendDataLen;
uint32_t sendDataLastFlag = 0;
uint8_t dataAndCrcBuf[READ_ONECE_DATA_LEN+CMD_FCS_LEN] = {0};
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
instance = DUMP_UART_INSTANCE;
EcDumpCheckIfNeedRetry(DUMP_RETRY_CMD_RESEND, ptrDumpReqWrap, NULL);
}
else
{
instance = (uint32_t)usbDevGetLogIfIdx();
EcDumpCheckIfNeedRetry(DUMP_RETRY_CMD_RESEND, ptrDumpReqWrap, NULL);
}
ptrReadDataReqCell = (ReadDataReqCell*)(&ptrDumpReqWrap->Data[0]);
tDumpRspWrap.Command = ptrDumpReqWrap->Command;
tDumpRspWrap.Sequence = ptrDumpReqWrap->Sequence;
tDumpRspWrap.CID = ptrDumpReqWrap->CID;
tDumpRspWrap.NCID = ptrDumpReqWrap->NCID;
if ((ptrReadDataReqCell->ReadLen > MAX_READ_DATALEN) || ((ptrReadDataReqCell->ReadDataAddr%4)!=0))
{
tDumpRspWrap.Length = 0;
tDumpRspWrap.Status = NACK;
Sum = EcDumpCRC16(0xFFFF, &tDumpRspWrap.Command, PROTOCOL_RSP_FIX_LEN+tDumpRspWrap.Length);
tDumpRspWrap.FCS = Sum;
RetValue = eehDumpMediaSend(instance, &tDumpRspWrap.Command, PROTOCOL_RSP_FIX_LEN+tDumpRspWrap.Length + CMD_FCS_LEN, 1000);
*excepStep = (*excepStep | 0x10000);
return RetValue;
}
tDumpRspWrap.Status = ACK;
tDumpRspWrap.Length = ptrReadDataReqCell->ReadLen;
RetValue = eehDumpMediaSend(instance, &tDumpRspWrap.Command, PROTOCOL_RSP_FIX_LEN, 1000);
if (RetValue != PROTOCOL_RSP_FIX_LEN)
{
*excepStep = (*excepStep | 0x20000);
return 1;
}
Sum = EcDumpCRC16(Sum, &tDumpRspWrap.Command,PROTOCOL_RSP_FIX_LEN);
for (Idx = 0; Idx < ptrReadDataReqCell->ReadLen;)
{
(DataBuff) = (uint32_t *)(ptrReadDataReqCell->ReadDataAddr + Idx);
sendDataLenLeft = ptrReadDataReqCell->ReadLen - Idx;
if(sendDataLenLeft < READ_ONECE_DATA_LEN)
{
sendDataLen = sendDataLenLeft;
}
else
{
sendDataLen = READ_ONECE_DATA_LEN;
}
Sum = EcDumpCRC16(Sum, (uint8_t*)(DataBuff), sendDataLen);
Idx = Idx + sendDataLen;
}
tDumpRspWrap.FCS = Sum;
for (Idx = 0; Idx < ptrReadDataReqCell->ReadLen;)
{
(DataBuff) = (uint32_t *)(ptrReadDataReqCell->ReadDataAddr + Idx);
sendDataLenLeft = ptrReadDataReqCell->ReadLen - Idx;
if(sendDataLenLeft < READ_ONECE_DATA_LEN)
{
sendDataLen = sendDataLenLeft;
sendDataLastFlag = 1;
}
else
{
sendDataLen = READ_ONECE_DATA_LEN;
if((READ_ONECE_DATA_LEN+Idx)==ptrReadDataReqCell->ReadLen)
{
sendDataLastFlag = 1;
}
}
if(sendDataLastFlag != 1)
{
RetValue = eehDumpMediaSend(instance, (uint8_t*)(DataBuff), sendDataLen, 5000);
}
else
{
memcpy(dataAndCrcBuf, (uint8_t*)(DataBuff), READ_ONECE_DATA_LEN);
memcpy(&dataAndCrcBuf[READ_ONECE_DATA_LEN], (uint8_t *)(&tDumpRspWrap.FCS), CMD_FCS_LEN);
RetValue = eehDumpMediaSend(instance, (uint8_t*)(dataAndCrcBuf), (READ_ONECE_DATA_LEN+CMD_FCS_LEN), 5000);
}
//excepDelay(1000);
if (RetValue != READ_ONECE_DATA_LEN)
{
*excepStep = (*excepStep | 0x40000);
return 1;
}
Idx = Idx + sendDataLen;
}
*excepStep = (*excepStep | 0x100000);
return RetValue;
}
uint32_t EcDumpHandleGetInfo(PtrDumpReqWrap ptrDumpReqWrap)
{
uint32_t RetValue = 0;
DumpRspWrap tDumpRspWrap;
uint32_t Sum = 0xFFFF;
uint32_t instance;
char infoCmdBuf[96] = {0};
uint32_t infoCellLen = sizeof(tDataInfoCell);
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
instance = DUMP_UART_INSTANCE;
}
else
{
instance = (uint32_t)usbDevGetLogIfIdx();
}
tDumpRspWrap.Command = ptrDumpReqWrap->Command;
tDumpRspWrap.Sequence = ptrDumpReqWrap->Sequence;
tDumpRspWrap.CID = ptrDumpReqWrap->CID;
tDumpRspWrap.NCID = ptrDumpReqWrap->NCID;
tDumpRspWrap.Status = ACK;
tDumpRspWrap.Length = sizeof(tDataInfoCell);
memcpy(infoCmdBuf, &tDumpRspWrap.Command, PROTOCOL_RSP_FIX_LEN);
Sum = EcDumpCRC16(Sum, &tDumpRspWrap.Command,PROTOCOL_RSP_FIX_LEN);
memcpy(&infoCmdBuf[PROTOCOL_RSP_FIX_LEN], (uint8_t *)&tDataInfoCell, sizeof(tDataInfoCell));
Sum = EcDumpCRC16(Sum, (uint8_t *)&tDataInfoCell, sizeof(tDataInfoCell));
tDumpRspWrap.FCS = Sum;
memcpy(&infoCmdBuf[PROTOCOL_RSP_FIX_LEN+infoCellLen], (uint8_t *)(&tDumpRspWrap.FCS), CMD_FCS_LEN);
RetValue = eehDumpMediaSend(instance, (uint8_t *)infoCmdBuf, PROTOCOL_RSP_FIX_LEN+infoCellLen+CMD_FCS_LEN, 1000);
if (RetValue != CMD_FCS_LEN)
{
*excepStep = (*excepStep | 0x1000000);
return 1;
}
*excepStep = (*excepStep | 0x2000000);
return 0;
}
uint32_t EcDumpDataFlow(void)
{
uint32_t retryCount = dumpWaitSyncRetryCnt;
uint32_t RetValue = 1;
DumpReqWrap tDumpReqWrap;
DumpReqWrap tDumpReqWrapTmep;
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
//UART_init(DUMP_UART_INSTANCE, 921600, false);
eehDumpMediaInit();
}
while(retryCount)
{
RetValue = EcDumpWaitSync();
if(RetValue == 0)
{
break;
}
else
{
retryCount--;
}
}
if(retryCount == 0)//sync failed
{
return 1;
}
retryCount = dumpGetCmdRetryCnt;
while(retryCount)
{
memset(&tDumpReqWrap, 0, sizeof(tDumpReqWrap));
*excepStep = (*excepStep | 0x80);
RetValue = EcDumpWaitCmd(&tDumpReqWrap);
if (RetValue != 0)
{
retryCount--;
continue;
}
if(tDumpReqWrap.Command != 0x00)
{
EcDumpCheckIfNeedRetry(DUMP_RETRY_CMD_COUNT, &tDumpReqWrap, &tDumpReqWrapTmep);
}
*excepStep = (*excepStep | 0x10);
RetValue = EcDumpCheckCmd(&tDumpReqWrap);
if (RetValue != 0)
{
continue;
}
retryCount = dumpGetCmdRetryCnt;
switch(tDumpReqWrap.Command)
{
case GetDataCmd:
*excepStep = (*excepStep | 0x8000);
EcDumpHandleGetData(&tDumpReqWrap);
break;
case GetInfoCmd:
*excepStep = (*excepStep | 0x200000);
EcDumpHandleGetInfo(&tDumpReqWrap);
break;
case FinishCmd:
excepDumpEndFlag = DUMP_END_FLAG_SUCC;
return 0;
default:
break;
}
}
return RetValue;
}
uint32_t EcDumpHandshakeProc(uint32_t SyncPeriod)
{
uint8_t recv_buffer[DUMP_SYNC_RSP_LEN];
uint32_t SyncCnt = 0;
uint32_t RetValue = 0;
uint32_t idx;
uint8_t epNum;
uint32_t instance;
uint32_t retryCnt = 0;
uint32_t instanceTemp;
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
instance = DUMP_UART_INSTANCE;
retryCnt = dumpHandshakeRetryCnt;
instanceTemp = instance;
}
else
{
retryCnt = dumpHandshakeRetryCnt;
instance = (uint32_t)usbDevGetLogIfIdx();
epNum = usbDevGetEpNumFromIf(usbDevGetLogIfIdx());
instanceTemp = (epNum&0xf);
}
//eehDumpMediaPurgeRx(instance); only valid for UART and no need to reset RX FIFO again
memset(recv_buffer, 0, sizeof(recv_buffer));
while(SyncCnt++ < retryCnt)
{
uniLogFlushOut();
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
ECPLAT_PRINTF(UNILOG_PLA_INTERNAL_CMD, ecDumpHandshakeProc, P_ERROR, "enter dump handshake mode");
uniLogFlushOut();
}
else
{
ECPLAT_PRINTF(UNILOG_PLA_INTERNAL_CMD, ecDumpUsbHandshakeProc, P_ERROR, "enter USB dump handshake mode");
uniLogFlushOut();
}
RetValue = eehDumpMediaRecv(instanceTemp, recv_buffer, DUMP_SYNC_RSP_LEN, WaitPeriod_1s/2);
if (RetValue >= 2)
{
if(RetValue < (DUMP_SYNC_RSP_LEN - 2))
{
delay_us(WaitPeriod_1s/2);
}
else
{
for (idx = 0; idx < DUMP_SYNC_RSP_LEN - 2; idx++)
{
if ((recv_buffer[idx] == dump_response_code[0]) && (recv_buffer[idx+1] == dump_response_code[1]))
{
*excepStep = (*excepStep | 0x2);
return 0;
}
}
}
}
else
{
delay_us(WaitPeriod_1s/2);
}
}
*excepStep = (*excepStep | 0x4);
return 1;
}
uint32_t EcDumpTopFlow(void)
{
uint32_t RetValue = 1;
uint32_t instance = 0;
*excepStep = 0x0;
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
instance = DUMP_UART_INSTANCE;
}
else
{
usbc_trace_disable();
eehDumpMediaInit();
instance = (uint32_t)usbDevGetLogIfIdx();
}
*excepStep = (*excepStep | 0x1);
eehDumpMediaFlush(instance);
RetValue = EcDumpHandshakeProc(WaitPeriod_1s>>1);
if (RetValue == 0)
{
RetValue = EcDumpDataFlow();
*excepStep = (*excepStep | 0x4000000);
}
*excepStep = (*excepStep | 0x8000000);
#ifdef FEATURE_UART_HELP_DUMP_ENABLE
excepCfgOption = BSP_GetPlatConfigItemValue(PLAT_CONFIG_ITEM_FAULT_ACTION);
if ((RetValue == 1)&&((excepCfgOption == EXCEP_OPTION_DUMP_FLASH_EPAT_LOOP_AND_UART_HELP_DUMP)||(excepCfgOption == EXCEP_OPTION_DUMP_FLASH_EPAT_RESET_AND_UART_HELP_DUMP)))
{
RetValue = EcDumpHandshakeProcUart(WaitPeriod_1s>>1);
if (RetValue == 0)
{
RetValue = EcDumpDataFlowUart();
*excepStepDump = (*excepStepDump | 0x4000000);
}
*excepStepDump = (*excepStepDump | 0x8000000);
}
#endif
return RetValue;
}
#ifdef FEATURE_UART_HELP_DUMP_ENABLE
uint32_t EcDumpHandshakeProcUart(uint32_t SyncPeriod)
{
uint8_t recv_buffer[DUMP_SYNC_RSP_LEN];
uint32_t SyncCnt = 0;
uint32_t RetValue = 0;
uint32_t idx;
uint32_t retryCnt = 0;
uint32_t instanceTemp;
uint32_t uartDumpModeId = 0;
uint32_t atPortBaudRate = 0xff;
uint8_t uartDumpModeBuff[EC_UART_HELP_DUMP_BUFF_LEN] = {0};
int i;
*excepStepDump = 0;
uniLogSetPherType(UART_0_FOR_UNILOG);
atPortBaudRate = BSP_GetPlatConfigItemValue(PLAT_CONFIG_ITEM_LOG_BAUDRATE);
UART_init(DUMP_UART_INSTANCE, atPortBaudRate & 0x7FFFFFFFUL, false);
retryCnt = 32;
instanceTemp = DUMP_UART_INSTANCE;
memset(recv_buffer, 0, sizeof(recv_buffer));
for(i=0; i<EC_UART_HELP_DUMP_BUFF_LEN; i++)
{
uartDumpModeBuff[i] = 0xff;
if(((i%16) == 3)||((i%16) == 11))
{
uartDumpModeBuff[i] = 0xfe;
}
}
uartDumpModeBuff[28] = 0x6e;
uartDumpModeBuff[29] = 0x27;
uartDumpModeBuff[30] = 0xc9;
uartDumpModeBuff[31] = 0x70;
uartDumpModeId = EcDumpGetUartDumpModeId(UNILOG_PLAT_AP, UNILOG_PLA_INTERNAL_CMD, ecDumpHandshakeProc);
uartDumpModeId = uartDumpModeId & ~0x7FF;
uartDumpModeBuff[32] = ((uartDumpModeId >> 28)&0xff)|0x20;
uartDumpModeBuff[33] = (uartDumpModeId >> 20)&0xff;
uartDumpModeBuff[34] = (uartDumpModeId >> 12)&0xff;
uartDumpModeBuff[35] = (uartDumpModeId >> 4)&0xf0;
uartDumpModeBuff[36] = 0xf;
while(SyncCnt++ < retryCnt)
{
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
//ECPLAT_PRINTF(UNILOG_EXCEP_PRINT, ecDumpHandshakeProc, P_ERROR, "enter dump handshake mode");
UART_send(DUMP_UART_INSTANCE, (const uint8_t *)uartDumpModeBuff, EC_UART_HELP_DUMP_BUFF_LEN, 10000);
}
RetValue = eehDumpMediaRecv(instanceTemp, recv_buffer, DUMP_SYNC_RSP_LEN, WaitPeriod_1s);
if (RetValue >= 2)
{
for (idx = 0; idx < DUMP_SYNC_RSP_LEN - 2; idx++)
{
if ((recv_buffer[idx] == dump_response_code[0]) && (recv_buffer[idx+1] == dump_response_code[1]))
{
*excepStepDump = (*excepStepDump | 0x2);
return 0;
}
}
}
}
*excepStepDump = (*excepStepDump | 0x4);
return 1;
}
uint32_t EcDumpDataFlowUart(void)
{
uint32_t retryCount = dumpWaitSyncRetryCnt;
uint32_t RetValue = 1;
DumpReqWrap tDumpReqWrap;
DumpReqWrap tDumpReqWrapTmep;
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
//UART_init(DUMP_UART_INSTANCE, 921600, false);
eehDumpMediaInit();
}
while(retryCount)
{
RetValue = EcDumpWaitSync();
if(RetValue == 0)
{
break;
}
else
{
retryCount--;
}
}
if(retryCount == 0)//sync failed
{
return 1;
}
retryCount = dumpGetCmdRetryCnt;
while(retryCount)
{
memset(&tDumpReqWrap, 0, sizeof(tDumpReqWrap));
*excepStepDump = (*excepStepDump | 0x80);
RetValue = EcDumpWaitCmd(&tDumpReqWrap);
if (RetValue != 0)
{
retryCount--;
continue;
}
if(tDumpReqWrap.Command != 0x00)
{
EcDumpCheckIfNeedRetry(DUMP_RETRY_CMD_COUNT, &tDumpReqWrap, &tDumpReqWrapTmep);
}
*excepStepDump = (*excepStepDump | 0x10);
RetValue = EcDumpCheckCmd(&tDumpReqWrap);
if (RetValue != 0)
{
continue;
}
retryCount = dumpGetCmdRetryCnt;
switch(tDumpReqWrap.Command)
{
case GetDataCmd:
*excepStepDump = (*excepStepDump | 0x8000);
EcDumpHandleGetData(&tDumpReqWrap);
break;
case GetInfoCmd:
*excepStepDump = (*excepStepDump | 0x200000);
EcDumpHandleGetInfo(&tDumpReqWrap);
break;
case FinishCmd:
excepDumpEndFlag = DUMP_END_FLAG_SUCC;
return 0;
default:
break;
}
}
return RetValue;
}
#endif

View File

@@ -0,0 +1,68 @@
/****************************************************************************
*
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
* File name: hal_adc.h
* Description: EC618 adc hal driver header file
* History: Rev1.0 2019-12-12
* Rev1.1 2020-02-29 Add api to get internal thermal temperature
*
****************************************************************************/
#ifndef _HAL_ADC_H
#define _HAL_ADC_H
/**
\addtogroup hal_adc_interface_gr
\{
*/
/**
\brief Calibarte ADC raw sample code
\param[in] input ADC conversion raw register value
\return calibrated voltage in unit of uV
*/
uint32_t HAL_ADC_CalibrateRawCode(uint32_t input);
/**
\brief Convert ADC thermal channel raw sample to temperature in unit of mili degree centigrade
\param[in] input ADC thermal channel register value
\return temperature in unit of mili centidegree
*/
int32_t HAL_ADC_ConvertThermalRawCodeToTemperatureHighAccuracy(uint32_t input);
/**
\brief Convert ADC thermal channel raw sample to temperature in unit of degree centigrade
\param[in] input ADC thermal channel register value
\return temperature in unit of centidegree
*/
int32_t HAL_ADC_ConvertThermalRawCodeToTemperature(uint32_t input);
/**
\brief Get Vbat voltage in unit of mV in given time
\param[in] timeout_ms timeout value in unit of ms
\return error code or calibrated Vbat voltage
- -2 : timeout
- -1 : other errors
- > 0 : calibrated Vbat voltage in unit of mV
\note This API shall only be used in task context since semphore is used for synchronization
*/
int32_t HAL_ADC_SampleVbatVoltage(uint32_t timeout_ms);
/**
\brief Get ADC thermal temperature in unit of degree centigrade in given time
\param[in] timeout_ms timeout value in unit of ms
\param[in,out] temperatruePtr pointer to temperature
\return error code
- -2 : timeout
- -1 : other errors
\note This API shall only be used in task context since semphore is used for synchronization
*/
int32_t HAL_ADC_GetThermalTemperature(uint32_t timeout_ms, int32_t* temperatruePtr);
/** \} */
#ifdef __cplusplus
}
#endif
#endif /* _HAL_ADC_H */

View File

@@ -0,0 +1,87 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename: hal_adcproxy.h
*
* Description: ap collect adc for cp use
*
* History: 2021.06.20 initiated by Zhao Weiqi
*
* Notes:
*
******************************************************************************/
#ifndef HAL_ADC_PROXY_H
#define HAL_ADC_PROXY_H
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
/* to use default efuse data, set to 1 if no data in efuse */
#define USE_DEFAULT_EFUSE_VALUE 1
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
#define ADC_PROXY_VBAT 0
#define ADC_PROXY_INTTEMP 1
#define ADC_PROXY_EXTTEMP 2
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS DECLEARATION *
*----------------------------------------------------------------------------*/
/**
* @brief cpADCProxyStartChannel
* @details start adc collection for cp use
* @note
*/
void cpADCProxyStartChannel(uint8_t ADCSampleBm);
/**
* @brief cpADCInit
* @details always call this api, use
use aio1 for vref, should call far before aio2 start sample, aio1 output need long stable time,
so call this api as early as possible
* @note
*/
void cpADCInit(void);
/**
* @brief cpADCDeInit
* @details power off vref output
* @note
*/
void cpADCDeInit(void);
/**
* @brief adcProxyConvertRawCodeToTemperature
* @details calculate internal thermal from adc raw data. output accuracy is 0.001 degree
* @note
*/
int32_t adcProxyConvertRawCodeToTemperature(uint32_t input);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,171 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename: hal_alarm.h
*
* Description: header of hal_alarm.c, battery low and high temperature interrupt handler
*
* History: 2021.05.12 initiated by Zhao Weiqi
*
* Notes:
*
******************************************************************************/
#ifndef CHIP_HALALARM_H
#define CHIP_HALALARM_H
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
typedef enum
{
ALARM_TYPE_VOLT = 0,
ALARM_TYPE_THERM,
}alarmMsgType_e;
typedef enum
{
ALARM_INFO_DOWNWARD = 0,
ALARM_INFO_UPWARD,
}alarmMsgInfo_e;
typedef struct
{
uint8_t value;
}alarmInfo;
typedef enum _EPAT_alarmVoltThd
{
VOLT_THRESHOLD_2150 = 0,
VOLT_THRESHOLD_2200,
VOLT_THRESHOLD_2250,
VOLT_THRESHOLD_2300,
VOLT_THRESHOLD_2350,
VOLT_THRESHOLD_2400,
VOLT_THRESHOLD_2450,
VOLT_THRESHOLD_2500,
VOLT_THRESHOLD_2550,
VOLT_THRESHOLD_2600,
VOLT_THRESHOLD_2650 = 10,
VOLT_THRESHOLD_2700,
VOLT_THRESHOLD_2750,
VOLT_THRESHOLD_2800,
VOLT_THRESHOLD_2850,
VOLT_THRESHOLD_2900,
VOLT_THRESHOLD_2950 = 16,
VOLT_THRESHOLD_3000,
VOLT_THRESHOLD_3050,
VOLT_THRESHOLD_3100,
VOLT_THRESHOLD_3150 = 20,
VOLT_THRESHOLD_3200,
VOLT_THRESHOLD_3250,
VOLT_THRESHOLD_3300 = 23,
}alarmVoltThd;
typedef enum _EPAT_alarmThmThd
{
THM_THRESHOLD_LEVEL0 = 0,
THM_THRESHOLD_LEVEL1 = 1,
THM_THRESHOLD_LEVEL2 = 2,
THM_THRESHOLD_LEVEL3 = 3,
}alarmThmThd;
typedef enum _EPAT_alarmHysteresisRange
{
THM_HYSTERESIS_10 = 0,
THM_HYSTERESIS_20 = 1,
THM_HYSTERESIS_30 = 2,
THM_HYSTERESIS_40 = 3,
}alarmHysteresisRange;
typedef struct
{
uint8_t voltEnable : 1;
uint8_t thermEnable : 1;
uint8_t rsvd : 6;
alarmVoltThd voltThd; /* voltage alarm threshold */
alarmThmThd thermThd; /* thermal alarm threshold */
alarmHysteresisRange hysterThd; /* thermal alarm hysteresis config */
}alarmParamCfg_t;
typedef void(* vbatLowCallback_t)(bool isVoltAboveThd);
typedef void(* thmHighCallback_t)(bool isTempAboveThd);
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS DECLEARATION *
*----------------------------------------------------------------------------*/
/**
* @brief alarmVBatInit
* @details vbat alarm init, callback will excute when vbat is too low
the hysteresis is fixed to 200mV
*
* @param voltThd100: vbat too low threshold
e.g. set threshold to 2.20V then voltThd100 = 220
* @return null
*/
void alarmVBatInit(uint16_t voltThd100);
/**
* @brief alarmVBatDeinit
* @details vbat alarm deinit, no vbat alarm will come anymore
*
* @return null
*/
void alarmVBatDeinit(void);
/**
* @brief alarmThmHighInit
* @details thermometer alarm init, callback will excute when temperature is too high
*
* @param thmThd: set the threshold
@param range: set the hysteresis range
* @return null
*/
void alarmThmHighInit(alarmThmThd thmThd, alarmHysteresisRange range);
/**
* @brief alarmThmHighDeinit
* @details thermometer alarm deinit, no thermometer alarm will come anymore
*
* @return null
*/
void alarmThmHighDeinit(void);
/**
* @brief alarmFuncInit
* @details init to detect low voltage and high temperature
*
* @return null
*/
void alarmFuncInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,95 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename: hal_charge.c
*
* Description: api for charge status detect
*
* History: initiated by Zhao Weiqi
*
* Notes:
*
******************************************************************************/
#ifndef HAL_CHARGE_H
#define HAR_CHARGE_H
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#include <stdbool.h>
#include <stdint.h>
#include "charge.h"
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTION DECLEARATION *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* GLOBAL VARIABLES *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTIONS *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS *
*----------------------------------------------------------------------------*/
/**
* @brief chargeIntHandler
* @details charge interrupt handler
*
* @return null
*/
void chargeIntHandler(void);
/**
* @brief chargeDetectInit
* @details Charge detect initialize
*
* @param cb: callback function for charge status update
* @param monitorEn: enable monitor to detect status_charging and status_full
@param sample_dly: sample delay.
* @return null
*/
void chargeDetectInit(chargeStatusCb cb, bool monitorEn, uint32_t sample_dly);
/**
* @brief chargeDetectDeinit
* @details Charge detect deinitialize
*
* @return null
*/
void chargeDetectDeinit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,129 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename:hal_dumpMedia.h
*
* Description: used to provid adapt API for ram dump
*
* History:
*
* Notes:
*
******************************************************************************/
#ifndef HAL_DUMPMEDIA_H
#define HAL_DUMPMEDIA_H
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS DECLEARATION *
*----------------------------------------------------------------------------*/
/**
\fn eehDumpMediaInit( void )
\brief used to init dump media for eeh dump, map to UART or USB
\note only called in eeh dump procedure
*/
void eehDumpMediaInit( void );
/**
\fn eehDumpMediaFlush(uint32_t instance)
\brief used to flush FIFO, only valid for UART now
\param[in] instance UART instance
\note only called in eeh dump procedure
*/
void eehDumpMediaFlush(uint32_t instance);
/**
\fn eehDumpMediaPurgeRx(uint32_t instance)
\brief used to flush FIFO, only valid for UART now
\param[in] instance UART instance
\note only called in eeh dump procedure
*/
void eehDumpMediaPurgeRx(uint32_t instance);
/**
\fn eehDumpMediaRecv(uint32_t instance, uint8_t *data, uint32_t num, uint32_t timeout_us)
\brief used to recv data from host via polling, uldp is still involved
\param[in] instance ep number or uart instance for recv
\param[in] data data pointer to store recv data
\param[in] num recv data length
\param[in] timeout_us timeout value when nothing recv
\note only called in eeh dump procedure
*/
uint32_t eehDumpMediaRecv(uint32_t instance, uint8_t *data, uint32_t num, uint32_t timeout_us);
/**
\fn eehDumpMediaSend(uint32_t instance, uint8_t *data, uint32_t num, uint32_t timeout_us)
\brief used to recv data from host via polling, uldp is still involved
\param[in] instance ep number or uart instance for recv
\param[in] data data pointer to send
\param[in] num send data length
\param[in] timeout_us timeout value when nothing recv
\note only called in eeh dump procedure
*/
uint32_t eehDumpMediaSend(uint32_t instance, uint8_t *data, uint32_t num, uint32_t timeout_us);
/**
\fn eehDumpMediaPollingEp0(uint32_t loopCnt, uint32_t loopInr)
\brief polling EP0 ctrl info and handle it, e.g. VCOM open
\param[in] loopCnt how many loop times
\param[in] loopInr internalval for each loop
\note only called in eeh dump procedure
*/
void eehDumpMediaPollingEp0(uint32_t loopCnt, uint32_t loopInr);
/**
\fn eehDumpMediaPollingRndisHalt(uint32_t loopCnt, uint32_t loopInr)
\brief request rndis halt to host, need polling send sucesss or timeout
\param[in] loopCnt how many loop times
\param[in] loopInr internalval for each loop
\note only called in eeh dump procedure
*/
int32_t eehDumpMediaPollingRndisHalt(uint32_t loopCnt, uint32_t loopInr);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,287 @@
/****************************************************************************
*
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
* File name: hal_i2s.h
* Description: EC618 i2s hal driver header file
* History: Rev1.0 2021-9-18
*
****************************************************************************/
#ifndef _HAL_I2S_H
#define _HAL_I2S_H
#include "i2s.h"
#include "codecDrv.h"
/**
\addtogroup i2s_interface_gr
\{
*/
// 1. Static control part
typedef enum
{
CODEC_ES8388 = 0, ///< ES8388 codec
CODEC_NAU88C22 = 1, ///< NAU88C22 codec
CODEC_ES7148 = 2, ///< ES7148
CODEC_ES7149 = 3, ///< ES7149
CODEC_ES8311 = 4, ///< ES8311
CODEC_TM8211 = 5, ///< TM8211
}i2sCodecType_e;
typedef enum
{
MSB_MODE = 0, ///< Left aligned mode
LSB_MODE = 1, ///< Right aligned mode
I2S_MODE = 2, ///< I2S mode
PCM_MODE = 3, ///< PCM mode
}i2sMode_e;
typedef enum
{
CODEC_MASTER_MODE = 0, ///< Codec plays as master
CODEC_SLAVE_MODE = 1, ///< Codec plays as slave
}i2sRole_e;
typedef enum
{
SAMPLERATE_8K = 1, ///< Sample rate 8k
SAMPLERATE_16K = 2, ///< Sample rate 16k
SAMPLERATE_32K = 3, ///< Sample rate 32k
SAMPLERATE_22_05K = 4, ///< Sample rate 22.05k
SAMPLERATE_44_1K = 5, ///< Sample rate 44.1k
SAMPLERATE_48K = 6, ///< Sample rate 48k
SAMPLERATE_96K = 7, ///< Sample rate 96k
}i2sSampleRate_e;
typedef enum
{
FRAME_SIZE_16_16 = 0, ///< WordSize 16bit, SlotSize 16bit
FRAME_SIZE_16_32 = 1, ///< WordSize 16bit, SlotSize 32bit
FRAME_SIZE_24_32 = 2, ///< WordSize 24bit, SlotSize 32bit
FRAME_SIZE_32_32 = 3, ///< WordSize 32bit, SlotSize 32bit
}i2sFrameSize_e;
typedef enum
{
PLAY = 0, ///< Audio play
RECORD = 1, ///< Audio record
}i2sPlayRecord_e;
typedef enum
{
I2S_CLK_DISABLE = 0, ///< Disable I2S clock
I2S_CLK_ENABLE = 1, ///< Enable I2S clock
}i2sPowerCtrl_e;
typedef enum
{
MONO = 0,
DUAL_CHANNEL = 1,
}i2sChannelSel_e;
typedef struct
{
i2sCodecType_e codecType; ///< Codec choose
i2sMode_e mode; ///< Audio mode choose
i2sRole_e role; ///< Role choose
i2sSampleRate_e sampleRate; ///< Sample rate choose
i2sFrameSize_e frameSize; ///< Frame size choose
i2sPlayRecord_e playRecord; ///< Play or record choose
i2sChannelSel_e channelSel; ///< Mono or dual channel select
uint32_t totalNum; ///< Audio source total num
}i2sParamCtrl_t;
// 2. Dynamic control part
typedef enum
{
STOP_I2S = 0, ///< Stop play or record
START_SEND = 1, ///< Start Play
START_RECV = 2, ///< Start record
START_SEND_RECV = 3, ///< Start Play or record
}i2sStartStop_e;
typedef enum
{
VOLUMN_INCREASE = 0, ///< Volumn increase
VOLUMN_DECREASE = 1, ///< Volumn decrease
}i2sVolumnCtrl_e;
typedef enum
{
// @ 1.8V level
VOL_1_65V = 0,
VOL_1_70V,
VOL_1_75V,
VOL_1_80V,
VOL_1_85V,
VOL_1_90V,
VOL_1_95V,
VOL_2_00V,
// @ 2.8V level
VOL_2_65V = 8,
VOL_2_70V,
VOL_2_75V,
VOL_2_80V,
VOL_2_85V,
VOL_2_90V,
VOL_2_95V,
VOL_3_00V,
// @ 3.3V level
VOL_3_05V = 16,
VOL_3_10V,
VOL_3_15V,
VOL_3_20V,
VOL_3_25V,
VOL_3_30V,
VOL_3_35V,
VOL_3_40V,
}i2sIOVolSel_t;
typedef void (*i2sCbFunc_fn) (uint32_t event, uint32_t arg); ///< I2S init callback event.
///////////////////////////////////////////////////////////////
// When play, everytime play 1k size of audio src, then in i2sTxCb function, calculate how many data remained for
// sending. Data on the tail of transfering can be abandon, it won't influence the user to listen.
////////////////////////////////////////////////////////////////
#define I2S_DMA_TX_DESCRIPTOR_CHAIN_NUM 1 ///< DMA TX descriptor chain number
#define AUDIO_TX_TRANSFER_SIZE 1024 ///< Maximum TX DMA transfer size each descriptor
///////////////////////////////////////////////////////////////
// This macro controls record. Every receive buffer is 8k, total has 35 picecs of this buffer that using DMA to receive.
// If you want to change the time of record, modify these two macros.
// How to set these parameters?
// For example:
// Your buffer size is 284954byte, use it to divide 8000, get 35.61925. Define this macro to 35.
////////////////////////////////////////////////////////////////
#define I2S_DMA_RX_DESCRIPTOR_CHAIN_NUM 35 ///< DMA RX descriptor chain number
#define AUDIO_RX_TRANSFER_SIZE 8000 ///< Maximum RX DMA transfer size each descriptor
/**
\brief Init I2S interface, include pinMux, and enable clock.
\param[out] powerCtrl Enable or disable I2S clock.
\param[out] txCb Indicate that i2s tx operation has been done.
\param[out] rxCb Indicate that i2s rx operation has been done.
\return
*/
void HAL_I2sInit(i2sPowerCtrl_e powerCtrl, i2sCbFunc_fn txCb, i2sCbFunc_fn rxCb);
/**
\brief Configure i2s.
\param[in] paramCtrl Every i2s control parameters
\return
\details
1. Parameter "paramCtrl" involves all the parameters that need to set in i2s development.
(1). i2sCodecType_e codecType
Choose the codec that you use.
(2). i2sMode_e mode
We support 4 I2S interface modes, choose the one you need.
Note! Since I2S mode will have phase difference with other 3 modes, so please note that if you connect a speaker
in the LOUT1 or LOUT2, I2S mode will change to another speaker outer pin than other 3 modes.
(3). i2sRole_e role
Codec acts as master or slave, so our controller will act as slave or master accordingly.
(4). i2sSampleRate_e sampleRate
Choose the Sample rate you need.
(5). i2sFrameSize_e frameSize
WordSize shouldn't bigger than slotSize. WordSize is the real size you use, and slotSize is the length that one
frame occupys.
(6). i2sPlayRecord_e playRecord
Choose play audio or record audio.
(7). i2sChannelSel_e channelSel
Choose mono or dual channel.
(8). uint32_t totalNum
When playing, the total size of audio source.
*/
void HAL_I2sConfig(i2sParamCtrl_t paramCtrl);
/**
\brief Use i2s interface to play or record audio.
\param[in] playRecord Play or record.
\param[in,out] memAddr Audio source buffer when playing or recording
\param[in] trunkSize The size of everytime send or receive data.
\return
*/
void HAL_I2sTransfer(i2sPlayRecord_e playRecord, uint8_t* memAddr, uint32_t trunkSize);
/**
\brief Start play/record audio or stop play/record audio.
\param[in] startStop Start or stop play/record audio.
\return
*/
void HAL_I2sStartSop(i2sStartStop_e startStop);
/**
\brief Set total num of sending data to i2s.
\param[in] totalNum Total num of data.
\return
*/
void HAL_I2SSetTotalNum(uint32_t totalNum);
/**
\brief Get total num of data.
\return Total num of data.
*/
uint32_t HAL_I2SGetTotalNum(void);
/**
\brief Set play or record.
\param[in] playRecord Set i2s to play or record.
\return
*/
void HAL_I2SSetPlayRecord(i2sPlayRecord_e playRecord);
/**
\brief If codec don't have the ablity to adjust volumn, using this api to achieve it.
\param[in] srcBuf Audio source address of playing.
\param[in] srcTotalNum Total num of audio source for playing.
\param[in] volScale Increase or decrease the volumn.
\details
1. Mute, write 00 for volScale.
1. Decrease volumn to 50% of original, write 05 for volScale.
2. Increase volumn to 5 times of original, write 50 for volScale.
3. Increase volumn to 10 times of original, write 100 for volScale.
4. "volScale" can change from 00(mute), 01(10%), 02(20%)......30(300%), 40(400%), 100(1000%)......
\return
*/
void HAL_I2sSrcAdjustVolumn(int16_t* srcBuf, uint32_t srcTotalNum, uint16_t volScale);
void HAL_normalIOVoltSet(i2sIOVolSel_t sel);
void HAL_aonIOVoltSet(i2sIOVolSel_t sel);
#if 0
/**
\brief Control the volumn by codec when play audio.
\param[out] volumnCtrl Increase or decrease the volumn.
\param[out] step The gap each time when adjust the volumn.
\return
*/
void HAL_I2sVolumnCtrl(i2sVolumnCtrl_e volumnCtrl, uint8_t step);
#endif
/** \} */
#ifdef __cplusplus
}
#endif
#endif /* _HAL_I2S_H */

View File

@@ -0,0 +1,68 @@
/****************************************************************************
*
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
* File name: hal_misc.h
* Description: EC618 hal for misc header file
* History: Rev1.0 2019-12-12
*
****************************************************************************/
#ifndef _HAL_MISC_H
#define _HAL_MISC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
/**
\brief HAL_Get_ChipID enum
*/
typedef enum _chip_id_sel
{
CHIP_ID_ONLYID = 0, /**< only read chip ID */
CHIP_ID_REVID, /**< only read revison ID */
CHIP_ID_FULLID /**< read both chip ID & revison ID */
} chip_id_sel;
/**
\brief Get chip id
\param[in] sel HAL_Get_ChipID enum
\return chip id value
*/
uint32_t HAL_Get_ChipID(chip_id_sel sel);
/**
\fn delay_us(uint32_t us)
\brief delay time in microseconds.
\param[in] us number of us
\note Given the maximum cpu frequency is 204.8MHz and the limit in calculation,
* the maximum time can be delayed is 0xFFFFFFFF / 2048 = 2097151 us = 2097 m
*/
void delay_us(uint32_t us);
/**
\fn apmuBootDbgGPIOSet(bool level)
\brief set gpio level in boot flow, for boot time dbg
\param[in] level
\note should set register directly, do not use api
*/
void apmuBootDbgGPIOSet(bool level);
/**
\fn bool apmuGetLongSlpCfg(void)
\brief config the maximum sleep length.
1. We suggest return false to sleep no more than 36hour
2. But when usb is disabled and you do not care about time accuracy,
return true to set maximum sleep time to 1165 hour
\note false: sleep no more than 36.4 hour, true: can sleep 1165 hour
*/
bool apmuGetLongSlpCfg(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_MISC_H */

View File

@@ -0,0 +1,83 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename:
*
* Description:
*
* History:
*
* Notes:
*
******************************************************************************/
#ifndef HAL_PHY_H
#define HAL_PHY_H
#include "commontypedef.h"
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS DECLEARATION *
*----------------------------------------------------------------------------*/
/**
\fn void Phy2ApPlatSignalProc(UINT16 sigId)
\brief handle phy to plat ipc signal
\param[in] sigId
\returns void
*/
void Phy2ApPlatSignalProc(UINT16 sigId, void *msgBdyPtr);
/**
\fn void halPhyGetDebugModule(CHAR *strName, UINT8 *phyModule)
\brief STRING -> PHY debug module ID
\returns BOOL
*/
BOOL halPhyGetDebugModule(CHAR *strName, UINT8 *phyModule);
/**
\fn INT32 halPhySetDebugCfgInfo(UINT16 atHandle, UINT32 phyModId, INT32 *pCfgParams, UINT8 paramNum)
\brief Set PHY debug config
\returns INT32 // 0 - succ, < 0 fail
*/
INT32 halPhySetDebugCfgInfo(UINT16 atHandle, UINT32 phyModId, INT32 *pCfgParams, UINT8 paramNum);
/**
\fn void halPhyGetDebugAtStringInfo(CHAR *pAtRspBuf, UINT16 bufLen)
\brief print the PHY debug info
\returns void
*/
void halPhyGetDebugAtStringInfo(CHAR *pAtRspBuf, UINT16 bufLen);
#endif /* _HAL_PHY_H */

View File

@@ -0,0 +1,82 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename: hal_pwrkey.h
*
* Description: header of hal_pwrkey.c, power on/off and software debounce
*
* History: 2021.05.06 initiated by Zhao Weiqi
*
* Notes:
*
******************************************************************************/
#ifndef HAL_PWRKEY_H
#define HAL_PWRKEY_H
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#include "pwrkey.h"
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS DECLEARATION *
*----------------------------------------------------------------------------*/
/**
* @brief pwrKeyIntHandler
* @details call in PwrKey_WakeupIntHandler
*
* @return null
*/
void pwrKeyIntHandler(void);
/**
* @brief pwrKeyInit
* @details init and enable powerkey
*
* @param workMode
@param pullUpEn
@param dlyCfg
@param Callback
* @return null
*/
void pwrKeyInit(pwrKeyWorkMode workMode, bool pullUpEn, pwrKeyDly_t dlyCfg, pwrKeyCallback_t Callback);
/**
* @brief pwrKeyDeinit
* @details deinit and disable powerkey
*
* @param pullUpEn
* @return null
*/
void pwrKeyDeinit(bool pullUpEn);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,316 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename: hal_rfCali.h
*
* Description: header of hal_rfCali.c
*
* History: 2021.07.28 initiated by Jinxin Huang
*
* Notes:
*
******************************************************************************/
#ifndef HAL_RF_CALI_H
#define HAL_RF_CALI_H
#include <stdint.h>
//#include "at_util.h"
#include DEBUG_LOG_HEADER_FILE
#include "debug_trace.h"
#include "shareinfo.h"
#if defined(__CC_ARM)
#pragma anon_unions
#endif
/*********************************************************************************
* Defines
*********************************************************************************/
#define RF_NST_A2C_BUFF_ADDR ShareInfoAPSetPhyCaliMem() // 0xC800 : 50K
#define RF_NST_C2A_BUFF_ADDR (RF_NST_A2C_BUFF_ADDR+0xC800)
#define RF_NST_TEMP_BUFF_ADDR1 (RF_NST_C2A_BUFF_ADDR+0x3C00)//(RF_NST_C2A_BUFF_ADDR+0xC800) // 50K -> 30K
#define RF_NST_TEMP_BUFF_ADDR2 (RF_NST_TEMP_BUFF_ADDR1+0x7800)//(RF_NST_TEMP_BUFF_ADDR1+0xC800) // 50K -> 15K
#define RF_NST_TABLE_BUFF_ADDR (RF_NST_TEMP_BUFF_ADDR2+0x3C00)//(RF_NST_TEMP_BUFF_ADDR2+0xC800) //100K
#define RF_CALNST_CRC16_LENGTH_HEX (2)
#define RF_CALNST_CRC16_LENGTH_CHAR (RF_CALNST_CRC16_LENGTH_HEX * 2)
#define RF_CALNST_RSP_HEADER_LENGTH_HEX (4)
#define RF_CALNST_RSP_HEADER_LENGTH_CHAR (RF_CALNST_RSP_HEADER_LENGTH_HEX * 2)
#define RF_CALNST_CRC_ENABLE_IND_BITMASK (0x2) // indicate crc check enable or not 0-disable, 1-enable
#define RF_CALNST_PC_CRC_IND_BITMASK (0x4) // indicate crc check value by pc
#define RF_CALNST_NEXT_DATA_BLOCK_BITMASK (0xF8) // indicate ue next send data block counter
#define RF_CALNST_DATA_END_IND_BITMASK (0x1) // indicate data end, 0-end, 1- not end
#define SIZE_OF_COMMANDID (2)
#define RF_CAL_RSP_HEADER_BYTES (10) // (2+4+4) MT00000000
#define NO_ERR_DATA_FINISH_NOT (2)
#define NO_ERR_DATA_FINISH (1)
#define NO_ERR (0)
#define ERR_WR_FLASH (-14)
#define ERR_AFC_FAILURE_RC32K_CALI_ERR (-15)
#define ERR_AFC_FAILURE_RC32K_CALI_ERR_TIMEOUT (-16)
#define ERR_WR_FLASH_AT_TYPE (-17)
// define RF factory calibration Response message Buffer Maximum Length. Unit: bytes(Hex)
#define RF_FC_RESPONSE_OTHER_LEN (16) // 2(MT)+4(status+errInd)+4(length)+4(crc)+2(\r\n)
#define RF_FC_RESPONSE_ONE_MSG_MAX_HEX_LEN ((8000 - RF_FC_RESPONSE_OTHER_LEN)/2) // 4-finishstatus+errInd, 2-crc
#define RF_FC_RESPONSE_ONE_MSG_MAX_CHAR_LEN (8000)
#define C2A_BUFFER_DATA_LENGTH_IND_SIZE (12) // 4bytes-cmdid,4bytes-retvalue, 4bytes-datalength
/* AT+ECRFTEST */
#define ATC_ECRFTEST_0_STR_DEFAULT NULL
#define ATC_ECRFTEST_0_STR_MAX_LEN 8000 /* */
/* AT+ECRFNST */
#define ATC_ECRFNST_0_STR_DEFAULT NULL
#define ATC_ECRFNST_0_STR_MAX_LEN 8000 /* */
/* Command Handle in AP*/
#define RF_CAL_SELFCAL (0x03)
#define RF_CAL_WRITE_TABLE (0x0f)
#define RF_CAL_READ_TABLE (0x10)
#define RF_CAL_AFC_GET_DATA (0x0e)
/* AT^PHYDEBUG */
/* RF CaliTable struct*/
#define FCALI_COMN_TABLE_SIZE 96
#define FCALI_AFC_TABLE_SIZE 5
#define FCALI_AGC_ONEFREQ_TABLE_SIZE 12
#define FCALI_FREQ_MAX_NUM 10
#define RX_IP2_FREQ_MAX_NUM 32
#define FCALI_APC_FREQCMPST_POINTS_MAX_NUM 20
#define FCALI_BAND_BTMP_MAX_NUM 20 // Ec618,EC718P
#define FCALI_BAND_BTMP_MAX_NUM_718 11 // EC718
#define FCALI_POWER_SWP_MAX_NUM 8
#define FCALI_APC_CENTRA_CMDS_MAX_NUM 100
#define RX_IP2_TABLE_SIZE (RX_IP2_FREQ_MAX_NUM+1)
#define FCALI_AGC_ONEBAND_TABLE_SIZE (FCALI_AGC_ONEFREQ_TABLE_SIZE+1)*FCALI_FREQ_MAX_NUM
#define FCALI_APC_ONEBAND_TABLE_SIZE ((FCALI_FREQ_MAX_NUM/2)+(FCALI_FREQ_MAX_NUM*(3+FCALI_APC_FREQCMPST_POINTS_MAX_NUM))+(FCALI_POWER_SWP_MAX_NUM*2)+(FCALI_APC_CENTRA_CMDS_MAX_NUM*2))
#define NV_HEADER_SIZE 32
#define SELFCALI_TABLE_MAX_DATA_SIZE (8*1024 - NV_HEADER_SIZE)
#define FCALI_TABLE_MAX_DATA_SIZE (60*1024 - NV_HEADER_SIZE)
//#define FPGA_DEBUG_ADI
#define RF_NST_CP_GOTO_WHILE 0x80
#define RF_NST_CP_DO_NOTHING 0x81
#define FCALI_AFC_TABLE_SIZE 5
#ifdef FPGA_DEBUG_ADI
#define RF_RC32K_CALI_THRESHOLD 94 // error = 3125*3% ~= 94
#define RF_RC32K_CALI_RADIO 3125 // 102.4MHz / 32768 = 3125
#else
#define RF_RC32K_CALI_THRESHOLD 250 // error = 12500*2% = 250
#define RF_RC32K_CALI_RADIO 12500 // 409.6MHz / 32768 = 12500
#endif
#define ABS(a) ((a)>0 ? (a) : -(a))
/* AT+ECRFTEST */
#define ATC_ECRFTEST_0_STR_DEFAULT NULL
#define ATC_ECRFTEST_0_STR_MAX_LEN 8000 /* */
/* AT+ECRFNST */
#define ATC_ECRFNST_0_STR_DEFAULT NULL
#define ATC_ECRFNST_0_STR_MAX_LEN 8000 /* */
#define RF_CALNST_PREHANDLE_CRC_ERROR (-2) // preHandle error
#define RF_CALNST_TRANSDATABLOCK_INDEX_ERROR (-3)
/*********************************************************************************
* Enums
*********************************************************************************/
enum
{
DATA_END = 0,
DATA_NOEND = 1,
};
enum
{
PC_CRC_CHECK_OK = 0,
PC_CRC_CHECK_ERROR = 1,
};
enum
{
CRC_CHECK_DISABLE = 0,
CRC_CHECK_ENABLE = 1,
};
enum
{
RF_FCCALI_TABLE_Start = 0,
RF_FCCALI_TABLE_COMMINFO = 1,
RF_FCCALI_TABLE_AFC = 2,
RF_FCCALI_TABLE_AGC_1 = 3,
RF_FCCALI_TABLE_AGC_2 = 4,
RF_FCCALI_TABLE_RXIP2_1 = 5,
RF_FCCALI_TABLE_RXIP2_2 = 6,
RF_FCCALI_TABLE_APC = 7,
RF_FCCALI_TABLE_END = 8,
RF_FCCALI_TABLE_SELFCAL = 9,
};
// EC+ECRFTEST command Index
enum
{
RF_UNIT_TEST = 0x0,
RF_TX_POWER_FIXED = 0x1,
RF_APT_DAC_FIXED = 0x2,
RF_TX_CMD_FIXED = 0x3,
RF_THERMAL_VAL_GET = 0x4,
RF_TMPRT_COMP_ONOFF = 0x5,
RF_SIGNALING_DEBUG_ENA = 0x6,
RF_VOLTG_COMP_ONOFF = 0x7,
RF_TX_PABIAS_MIPI_REGS_FIXED = 0x8,
RF_FEM_GPIO_SET = 0x9,
RF_RC32K_LATCH_URC = 0x30,
RF_RC32K_GAP_GET = 0x31,
RF_RC32K_PTEST = 0x50,
RF_LDORET_SET = 0x60,
RF_DCDCVPA_ENA_DEBUG = 0x70,
};
//extern UINT16 dataPos = C2A_BUFFER_DATA_LENGTH_IND_SIZE; // first 4 bytes is total data length
//extern UINT16 lstDataSize = 0;
//extern UINT16 lstDataAddrOfst = 0;
//extern UINT8 transCount = 0;
enum
{
ADC_CVT_IDLE = 0x0,
ADC_CVT_BUSY
};
enum
{
RF_DEBUG_CMD_OUT_FLAG_NONE = 0x0,
RF_DEBUG_CMD_OUT_FLAG_REGS,
RF_DEBUG_CMD_OUT_FLAG_SARADC,
RF_DEBUG_CMD_OUT_FLAG_DUPLEXLOSS,
};
/*********************************************************************************
* struct
*********************************************************************************/
typedef union
{
struct
{
UINT16 finishInd :1; // data finish indication, 0-finished, 1-unfinshed
UINT16 crcEnaFlag :1; // crc check enable 0-disable, 1-enable
UINT16 pcCrcErrInd :1; // pc crc check indication, 0-no error, 1-error
UINT16 dbCounter :5; // data blocker counter
UINT16 cmdId :8; // commandId
};
UINT16 u16;
}CmdInfo;
typedef union
{
UINT32 u32[FCALI_COMN_TABLE_SIZE];
}RfFcComInfos; // 384 bytes
typedef union
{
UINT32 u32[FCALI_AFC_TABLE_SIZE];
}RfAfcTable; // 20 bytes
typedef union
{
UINT32 u32[FCALI_AGC_ONEBAND_TABLE_SIZE];
}RfAgcOneBandTable; // 520Bytes
typedef union
{
UINT32 u32[RX_IP2_TABLE_SIZE];
}RfRxIp2Table; // 132Bytes
typedef union
{
UINT32 u32[FCALI_APC_ONEBAND_TABLE_SIZE];
}RfApcOneBandTable; // 2*10+92*10+64+800 = 1804 bytes
typedef struct // for ec618, ec718p
{
RfFcComInfos comInfo;
RfAfcTable afc;
RfAgcOneBandTable agcTb1[FCALI_BAND_BTMP_MAX_NUM];
RfAgcOneBandTable agcTb2[FCALI_BAND_BTMP_MAX_NUM];
RfRxIp2Table rxIp2Tb1;
RfRxIp2Table rxIp2Tb2;
RfApcOneBandTable apc[FCALI_BAND_BTMP_MAX_NUM];
}RfFcaliTable;
typedef struct // for ec718
{
RfFcComInfos comInfo;
RfAfcTable afc;
RfAgcOneBandTable agcTb1[FCALI_BAND_BTMP_MAX_NUM_718];
RfRxIp2Table rxIp2Tb1;
RfRxIp2Table rxIp2Tb2;
RfApcOneBandTable apc[FCALI_BAND_BTMP_MAX_NUM_718];
}RfFcaliTable718;
typedef struct
{
__IO UINT16 cvtStatus;
__IO UINT16 cvtCode;
}RfCaliAdcStatus;
//define Afc info sections
typedef union RfAfcTableAp_Tag
{
struct
{
UINT32 freq100KHz; // unit:100KHz
INT32 dcxoDeltaFreq;
UINT32 dcxoCbank;
INT16 dcxoT0; // fwl=4, 1/16 degree.
UINT16 dcxoT0Code;
UINT32 rc32KCap;
};
UINT32 u32[FCALI_AFC_TABLE_SIZE];
}RfAfcTableAp; // 20 bytes
void atRfNstRspInd(INT32 chanId, UINT8 *dataOutReq, UINT32 outLen, BOOL phyRspEna);
INT32 ResumeTrans(UINT16 dataBlockCounter,UINT8* dataOut, UINT16* lenOut);
void atRfCaliGetThermal(RfAfcTableAp *pAfcTb);
INT32 atRf32KCapCali(UINT32 *cTuneRst);
BOOL atRf32KEnaGet(void);
INT32 RfAtNstCmdPreHandle(UINT16 atHandle, UINT8* data, UINT16 length, UINT8* dataOut, UINT16* lenOut);
UINT16 crc16_ccitt(void *dataptr, int len);
void RfHexToChar(UINT8* inHex);
void RfHexToString(UINT8* outStr, UINT8* rawData, UINT16 rawDataLen);
INT32 RfFcWriteTable(UINT16 *pDataIn, UINT16 srcHdr);
void RfAtTestCmd(UINT16 atHandle, UINT8* dataIn, UINT16 length);
void RfRc32KTestTmExp(void* arg);
void atRfNstRspDebug(INT32 chanId);
BOOL RfOpenApiDcdcVpaCfg (UINT8 ena, UINT8 voltage);
void RfCmiReqNoAt(UINT16 primId, UINT16 primSize, void *primBody);
//void RfOpenApiDcdcVpaRsp ( void );
#endif

View File

@@ -0,0 +1,42 @@
/****************************************************************************
*
* Copy right: 2022-, Copyrigths of AirM2M Ltd.
* File name: hal_uartDump.h
* Description: header file for dumping info through UART when exception occurs
* History: Rev1.0 2022-1-17
*
****************************************************************************/
#ifndef _HAL_UART_DUMP_H
#define _HAL_UART_DUMP_H
/**
\brief Initialize uart dump port
\details
This API will use the setting(pinmux, baudrate) if UART has already been initialized,
otherwise custom settting should be supplied properly to make uart dump work
*/
void HAL_UartDumpPortInit(void);
/**
\brief Check validation of uart dump port
\return true if current dump port is valid, otherwise false
\note Internal use for exception code
*/
bool HAL_UartDumpPortCheck(void);
/**
\brief Send data to uart dump port in polling way
\param[in] data Pointer to buffer with data to be sent to
\param[in] num Number of data items to send
\param[in] timeout_us timeout value in unit of us
\return num of data items sent in the internal of timeout
\note Internal use for exception code
*/
uint32_t HAL_UartDumpPortSend(const uint8_t *data, uint32_t num, uint32_t timeout_us);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_UART_DUMP_H */

View File

@@ -0,0 +1,251 @@
/****************************************************************************
*
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
* File name: hal_adc.c
* Description: EC618 adc hal driver source file
* History: Rev1.0 2019-12-12
* Rev1.1 2020-02-29 Add api to get internal thermal temperature
*
****************************************************************************/
#include "adc.h"
#include "hal_trim.h"
#include "cmsis_os2.h"
typedef struct _adc_conversion_result
{
volatile uint32_t rawCode;
osSemaphoreId_t sem;
} adc_conversion_result_t;
static adc_conversion_result_t g_adcVbatResult = {0};
static adc_conversion_result_t g_adcThermalResult = {0};
/**
\fn void ADC_VbatCallback(uint32_t result)
\brief Vbat channel callback
\return
*/
static void ADC_VbatCallback(uint32_t result)
{
g_adcVbatResult.rawCode = result;
if(g_adcVbatResult.sem)
{
osSemaphoreRelease(g_adcVbatResult.sem);
}
}
/**
\fn void ADC_ThermalCallback(uint32_t result)
\brief Thermal channel callback
\return
*/
static void ADC_ThermalCallback(uint32_t result)
{
g_adcThermalResult.rawCode = result;
if(g_adcThermalResult.sem)
{
osSemaphoreRelease(g_adcThermalResult.sem);
}
}
/**
\breif Calibarte ADC raw sample code
\param[in] input ADC conversion raw register value
\return calibrated voltage in unit of mV
\details
The calibration data stored in EFUSE is two sample values of 500mV and 900mV when Vref is set to 1200mV.
The calibration process can be deduced below with 3 equations:
Given:
Gain * Code500 + Offset = 500 (a)
Gain * Code900 + Offset = 900 (b)
To calculate:
Gain * Input + Offset (c) where Input is actual conversion data from ADC
We can get Gain and Offset from equation (a) and (b):
Gain = 400 / (Code900 - Code500)
Offset = 500 - 400 / (Code900 -Code500) * Code500
Put them into equation (c), Result is:
Result = 400 * (Input - Code500) / (Code900 - Code500) + 500
Round the result in the way: round(a/b) = (a + b/2) / b
Final result = (400 * (Input - Code500) + (Code900 - Code500) / 2) / (Code900 - Code500) + 500
In case of EFUSE value is invalid, we have to set Gain value to be 1200 / 4096 and Offset value to be 0.
So Result = Input * 1200 / 4096, after round
Final result = ((Input * 1200) + 2048) / 4096
*/
uint32_t HAL_ADC_CalibrateRawCode(uint32_t input)
{
int32_t temp = 0;
int32_t diff = 0;
AdcEfuseCalCode_t * efuseCalcodePtr = trimAdcGetCalCode();
// Resulotion is 12-bits
input &= 0xFFFU;
// EFUSE value is invalid
if((efuseCalcodePtr->code500 == 0) || (efuseCalcodePtr->code900 == 0))
{
return ((input * 1200000) + 2048) / 4096;
}
else
{
temp = input - efuseCalcodePtr->code500;
diff = efuseCalcodePtr->code900 - efuseCalcodePtr->code500;
temp = (400000 * temp + (diff >> 1)) / diff + 500000;
return (temp < 0) ? 0 : temp;
}
}
/**
\breif Convert ADC thermal channel raw sample to temperature in unit of centidegree
\param[in] input ADC thermal channel register value
\return temperature in unit of centidegree
\details
The empirical equation between temperature and ADC thermal ram sample is:
T = k * Input + T0 (a)
where k is slope and its value is approximately -0.16, T0 is bias and its value ranges from 400 to 500,
Input is actual conversion data from ADC
The actural k is deduced from EFUSE values with equation:
k = -(1000 / 1.731 / 0.95) * (0.4 / (Code900 - Code500)) (b)
where Code900 and Code500 are ADC calibration data stored in EFUSE, refer to previous comment in \ref HAL_ADC_CalibrateRawCode
T0 = Toffset - k * Tcode (c)
where Toffset and Tcode are Thermal calibartion data also stored in EFUSE and Toffset is a number with accuracy of 2 decimal digits
To get rid of float number calculation and balance accuracy loss, we here amplify the equation (a) by 4000,
that's T = (4000 * k * Input + 4000 * T0) / 4000 (d)
Combine equation (c), we get
T = (4000 * k * (Input - Tcode) + 4000 * Toffset) / 4000 (e)
Put equation (b) into (e) and note that Toffset has accuracy of 2 decimal digits, perform some simplifying we get
T = (-972970 / (Code900 - Code500) * (Input - Tcode) + Toffset * 1000) / 4000 (f)
Also, round the result in the way: round(a/b) = (a + b/2) / b if a > 0 and round(a/b) = (a - b/2) / b if a < 0
The final result is:
T = (-972970 / (Code900 - Code500) * (Input - Tcode) + Toffset * 1000 + 2000) / 4000 (g)
*/
int32_t HAL_ADC_ConvertThermalRawCodeToTemperatureHighAccuracy(uint32_t input)
{
static int32_t gain = 0;
int32_t temp;
AdcEfuseCalCode_t * efuseCalcodePtr = trimAdcGetCalCode();
AdcEfuseT0Code_t * efuseT0CodePtr = trimAdcGetT0Code();
// Resulotion is 12-bits
input &= 0xFFFU;
if(gain == 0)
{
gain = -972970 / (int32_t)(efuseCalcodePtr->code900 - efuseCalcodePtr->code500);
}
temp = gain * (int32_t)(input - efuseT0CodePtr->codet0) + (int32_t)(efuseT0CodePtr->t0 * 1000);
return (temp > 0) ? (temp + 2000) / 4 : (temp - 2000) / 4;
}
int32_t HAL_ADC_ConvertThermalRawCodeToTemperature(uint32_t input)
{
return HAL_ADC_ConvertThermalRawCodeToTemperatureHighAccuracy(input) / 1000;
}
int32_t HAL_ADC_SampleVbatVoltage(uint32_t timeout_ms)
{
AdcConfig_t adcConfig;
int ret = -1;
g_adcVbatResult.sem = osSemaphoreNew(1U, 0, NULL);
// semphore created succussful
if(g_adcVbatResult.sem != NULL)
{
ADC_getDefaultConfig(&adcConfig);
adcConfig.channelConfig.vbatResDiv = ADC_VBAT_RESDIV_RATIO_3OVER16;
ADC_channelInit(ADC_CHANNEL_VBAT, ADC_USER_APP, &adcConfig, ADC_VbatCallback);
ADC_startConversion(ADC_CHANNEL_VBAT, ADC_USER_APP);
ret = osSemaphoreAcquire(g_adcVbatResult.sem, timeout_ms);
ADC_channelDeInit(ADC_CHANNEL_VBAT, ADC_USER_APP);
if(ret == osOK)
{
ret = HAL_ADC_CalibrateRawCode(g_adcVbatResult.rawCode);
// amplify the result by the reciprocal of div ratio
ret = ret * 16 / 3;
ret = (ret + 500) / 1000; // uV -> mV
}
osSemaphoreDelete(g_adcVbatResult.sem);
}
return ret;
}
int32_t HAL_ADC_GetThermalTemperature(uint32_t timeout_ms, int32_t* temperatruePtr)
{
int ret = -1;
if(temperatruePtr == NULL)
return -1;
g_adcThermalResult.sem = osSemaphoreNew(1U, 0, NULL);
// semphore created succussful
if(g_adcThermalResult.sem != NULL)
{
ADC_channelInit(ADC_CHANNEL_THERMAL, ADC_USER_APP, NULL, ADC_ThermalCallback);
ADC_startConversion(ADC_CHANNEL_THERMAL, ADC_USER_APP);
ret = osSemaphoreAcquire(g_adcThermalResult.sem, timeout_ms);
ADC_channelDeInit(ADC_CHANNEL_THERMAL, ADC_USER_APP);
if(ret == osOK)
{
*temperatruePtr = HAL_ADC_ConvertThermalRawCodeToTemperature(g_adcThermalResult.rawCode);
}
osSemaphoreDelete(g_adcThermalResult.sem);
}
return ret;
}

View File

@@ -0,0 +1,350 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename: hal_alarm.c
*
* Description: api for battery low and high temperature interrupt process
*
* History: initiated by Zhao Weiqi
*
* Notes:
*
******************************************************************************/
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#include <string.h>
#include "hal_alarm.h"
#include DEBUG_LOG_HEADER_FILE
#include "alarm.h"
#include "FreeRTOS.h"
#include "cmsis_os2.h"
#include "queue.h"
#include "ic.h"
#include "ec618.h"
#include "slpman.h"
#include "cms_comm.h"
#ifdef FEATURE_AT_ENABLE
#include "atec_alarm_cnf_ind.h"
#endif
extern void delay_us(uint32_t us);
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
#define ALARM_TASK_STATK_SIZE 512
#define ALARM_EVENT_QUEUE_SIZE 2
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
typedef struct {
alarmMsgType_e msgType;
alarmMsgInfo_e msgInfo;
} alarmQueueMsg_t;
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTION DECLEARATION *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* GLOBAL VARIABLES *
*----------------------------------------------------------------------------*/
static QueueHandle_t alarmQueueHandle;
static bool alarmTaskExist = false;
static vbatLowCallback_t gAlarmVoltCb = NULL;
static vbatLowCallback_t gAlarmThermCb = NULL;
static alarmParamCfg_t gAlmParamDataBase;
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTIONS *
*----------------------------------------------------------------------------*/
static void ALM_enterLowPowerStatePrepare(void* pdata, slpManLpState state)
{
switch (state)
{
case SLPMAN_SLEEP1_STATE:
break;
default:
break;
}
}
static void ALM_exitLowPowerStateRestore(void* pdata, slpManLpState state)
{
switch (state)
{
case SLPMAN_SLEEP1_STATE:
if(gAlmParamDataBase.voltEnable == true)
{
alarmVBatInit(gAlmParamDataBase.voltThd);
}
if(gAlmParamDataBase.thermEnable == true)
{
alarmThmHighInit(gAlmParamDataBase.thermThd,gAlmParamDataBase.hysterThd);
}
if((gAlmParamDataBase.voltEnable == true) || (gAlmParamDataBase.thermEnable == true))
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, ALM_exitLowPowerStateRestore_1, P_VALUE, "Alarm Func Init: %d,%e<alarmVoltThd> - %d,%e<alarmThmThd>,%e<alarmHysteresisRange>", gAlmParamDataBase.voltEnable, gAlmParamDataBase.voltThd, gAlmParamDataBase.thermEnable, gAlmParamDataBase.thermThd, gAlmParamDataBase.hysterThd);
break;
default:
break;
}
}
static void thmHigh_interruptHandler(void)
{
alarmQueueMsg_t msg;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
uint8_t thm_hi = alarmThmGetIntIndicate();
if(thm_hi)
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, thmHigh_interruptHandler_0, P_WARNING, "Thm Interrupt Enter: Temperature too high");
else
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, thmHigh_interruptHandler_1, P_VALUE, "Thm Interrupt Enter: Temperature below threshold");
if(apmuGetImageType() == 1)
{
msg.msgType = ALARM_TYPE_THERM;
if(thm_hi == 1)
msg.msgInfo = ALARM_INFO_UPWARD;
else
msg.msgInfo = ALARM_INFO_DOWNWARD;
if (alarmQueueHandle)
{
if (pdTRUE != xQueueSendFromISR(alarmQueueHandle, &msg, &xHigherPriorityTaskWoken))
{
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, thmHigh_interruptHandler_2, P_VALUE, "Alarm message send in isr error");
}
}
else
{
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, thmHigh_interruptHandler_3, P_VALUE, "Alarm message queue not ready in isr");
}
if(xHigherPriorityTaskWoken)
{
portYIELD_FROM_ISR(pdTRUE);
}
}
else
{
if(gAlarmThermCb!=NULL)
gAlarmThermCb(thm_hi);
}
}
static void vbatLow_interruptHandler(void)
{
alarmQueueMsg_t msg;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
uint8_t vbat_info = alarmVBatGetIntIndicate();
if(vbat_info == 0)
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, vbatLow_interruptHandler_0, P_WARNING, "Vbat Interrupt Enter: Bat volatage too low");
else
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, vbatLow_interruptHandler_1, P_VALUE, "Vbat Interrupt Enter: Bat volatage above threshold");
if(apmuGetImageType() == 1)
{
msg.msgType = ALARM_TYPE_VOLT;
if(vbat_info == 1)
msg.msgInfo = ALARM_INFO_UPWARD;
else
msg.msgInfo = ALARM_INFO_DOWNWARD;
if (alarmQueueHandle)
{
if (pdTRUE != xQueueSendFromISR(alarmQueueHandle, &msg, &xHigherPriorityTaskWoken))
{
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, vbatLow_interruptHandler_2, P_VALUE, "Alarm message send in isr error");
}
}
else
{
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, vbatLow_interruptHandler_3, P_VALUE, "Alarm message queue not ready in isr");
}
if(xHigherPriorityTaskWoken)
{
portYIELD_FROM_ISR(pdTRUE);
}
}
else
{
if(gAlarmVoltCb!=NULL)
gAlarmVoltCb(vbat_info);
}
}
static void alarmIndUrcBcast(alarmMsgType_e msgType, alarmInfo *info)
{
#ifdef FEATURE_AT_ENABLE
MWNvmCfgAlarmParam param;
mwNvmCfgGetAlarmParam(&param);
if(!param.voltUrcEnable) return;
uint32_t primId = (msgType == ALARM_TYPE_VOLT) ? APPL_ALARM_VOLT_IND : APPL_ALARM_THERM_IND;
applSendCmsInd(BROADCAST_IND_HANDLER, APPL_ALARM, primId, sizeof(alarmInfo), (void *)info);
#endif
}
static void alarmTask(void *arg)
{
alarmQueueMsg_t msg;
alarmInfo info;
while(1)
{
if (xQueueReceive(alarmQueueHandle, &msg, portMAX_DELAY))
{
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, alarmTask_1, P_VALUE, "alarmTask: type=%d, info=%d", msg.msgType, msg.msgInfo);
info.value = msg.msgInfo;
switch(msg.msgType)
{
case ALARM_TYPE_VOLT:
{
alarmIndUrcBcast(ALARM_TYPE_VOLT, &info);
if(gAlarmVoltCb!=NULL)
gAlarmVoltCb(msg.msgInfo);
break;
}
case ALARM_TYPE_THERM:
{
alarmIndUrcBcast(ALARM_TYPE_THERM, &info);
if(gAlarmThermCb!=NULL)
gAlarmThermCb(msg.msgInfo);
break;
}
default:
break;
}
}
}
}
static void alarmThreadInit(void)
{
if(alarmTaskExist == false)
{
alarmTaskExist = true;
alarmQueueHandle = xQueueCreate(ALARM_EVENT_QUEUE_SIZE, sizeof(alarmQueueMsg_t));
if(alarmQueueHandle == NULL)
{
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, alarmThreadInit_1, P_VALUE, "Alarm task queue init error");
}
osThreadAttr_t task_attr;
memset(&task_attr,0,sizeof(task_attr));
task_attr.name = "almTask";
task_attr.stack_size = ALARM_TASK_STATK_SIZE;
task_attr.priority = osPriorityNormal1;
osThreadNew(alarmTask, NULL, &task_attr);
}
}
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS *
*----------------------------------------------------------------------------*/
void alarmVBatInit(uint16_t voltThd)
{
if(apmuGetImageType() == 1)
alarmThreadInit();
alarmVBatHwInit(voltThd);
delay_us(10);
XIC_ClearPendingIRQ(PXIC0_PM_VBAT_LOW_IRQn);
XIC_SetVector(PXIC0_PM_VBAT_LOW_IRQn, vbatLow_interruptHandler);
XIC_EnableIRQ(PXIC0_PM_VBAT_LOW_IRQn);
}
void alarmVBatDeinit(void)
{
XIC_DisableIRQ(PXIC0_PM_VBAT_LOW_IRQn);
alarmVBatHwDeinit();
delay_us(10);
XIC_ClearPendingIRQ(PXIC0_PM_VBAT_LOW_IRQn);
}
void alarmThmHighInit(alarmThmThd thmThd, alarmHysteresisRange range)
{
if(apmuGetImageType() == 1)
alarmThreadInit();
alarmThmHwInit(thmThd, range);
delay_us(10);
XIC_ClearPendingIRQ(PXIC1_THM_HI_IRQn);
XIC_SetVector(PXIC1_THM_HI_IRQn, thmHigh_interruptHandler);
XIC_EnableIRQ(PXIC1_THM_HI_IRQn);
}
void alarmThmHighDeinit(void)
{
XIC_DisableIRQ(PXIC1_THM_HI_IRQn);
alarmThmHwDeinit();
delay_us(10);
XIC_ClearPendingIRQ(PXIC1_THM_HI_IRQn);
}
void alarmFuncInit(void) // this function also call in paging
{
alarmParamCfg_t cfg;
cfg.voltEnable = true;
cfg.voltThd = VOLT_THRESHOLD_2200;
cfg.thermEnable = true;
cfg.thermThd = THM_THRESHOLD_LEVEL3;
cfg.hysterThd = THM_HYSTERESIS_40;
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, alarmFuncInit_1, P_VALUE, "Alarm Func Init: %d,%e<alarmVoltThd> - %d,%e<alarmThmThd>,%e<alarmHysteresisRange>", cfg.voltEnable, cfg.voltThd, cfg.thermEnable, cfg.thermThd, cfg.hysterThd);
if(cfg.voltEnable)
alarmVBatInit(cfg.voltThd);
if(cfg.thermEnable)
alarmThmHighInit(cfg.thermThd,cfg.hysterThd);
gAlarmThermCb = NULL;
gAlarmVoltCb = NULL;
if(apmuGetImageType() == 1)
{
#ifdef PM_FEATURE_ENABLE
slpManRegisterPredefinedBackupCb(SLP_CALLBACK_ALM_MODULE, ALM_enterLowPowerStatePrepare, NULL);
slpManRegisterPredefinedRestoreCb(SLP_CALLBACK_ALM_MODULE, ALM_exitLowPowerStateRestore, NULL);
memcpy(&gAlmParamDataBase, &cfg, sizeof(alarmParamCfg_t));
#endif
}
}

View File

@@ -0,0 +1,117 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename: hal_charge.c
*
* Description: api for charge status detect
*
* History: initiated by Zhao Weiqi
*
* Notes:
*
******************************************************************************/
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#include <string.h>
#include "hal_charge.h"
#include"ec618.h"
#include "FreeRTOS.h"
#include DEBUG_LOG_HEADER_FILE
#include "cmsis_os2.h"
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTION DECLEARATION *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* GLOBAL VARIABLES *
*----------------------------------------------------------------------------*/
osTimerId_t chargeMonTimer;
static uint8_t chargeMonTimerId = 0;
chargeStatusCb chargeStatusCbFunc;
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTIONS *
*----------------------------------------------------------------------------*/
static void chargeMonTimerExp(void *argument)
{
chargeStatus_e chargeStatus = chargeGetCurStatus();
if(chargeStatusCbFunc != NULL)
chargeStatusCbFunc(chargeStatus);
}
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS *
*----------------------------------------------------------------------------*/
void chargeIntHandler(void)
{
chargeStatus_e chargeStatus = chargeGetCurStatus();
ECPLAT_PRINTF(UNILOG_PMU, chargeIntHandler_1, P_VALUE, "Charger Int Enter, Status Update = %d", chargeStatus);
if(chargeStatusCbFunc != NULL)
chargeStatusCbFunc(chargeStatus);
}
void chargeDetectInit(chargeStatusCb cb, bool monitorEn, uint32_t sample_dly)
{
chargeHwInit();
chargeStatusCbFunc = cb;
chargeStatus_e chargeStatus = chargeGetCurStatus();
ECPLAT_PRINTF(UNILOG_PMU, chargeDetectInit_1, P_VALUE, "Charger Detect Init, Status Update = %d", chargeStatus);
if(chargeStatusCbFunc != NULL)
chargeStatusCbFunc(chargeStatus);
if(monitorEn)
{
if(chargeMonTimer == NULL)
{
chargeMonTimer = osTimerNew((osTimerFunc_t)chargeMonTimerExp, osTimerPeriodic, (void *)(uint32_t)chargeMonTimerId, NULL);
}
osTimerStart(chargeMonTimer, sample_dly);
}
NVIC_EnableIRQ(ChrgpadWakeup_IRQn);
}
void chargeDetectDeinit(void)
{
chargeHwDeinit();
NVIC_DisableIRQ(ChrgpadWakeup_IRQn);
chargeStatusCbFunc = NULL;
if(chargeMonTimer != NULL)
{
if(osTimerIsRunning(chargeMonTimer))
{
osTimerStop(chargeMonTimer);
}
osTimerDelete(chargeMonTimer);
chargeMonTimer = NULL;
}
}

View File

@@ -0,0 +1,443 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename:hal_dumpMedia.c
*
* Description: used to provid adapt API for ram dump
*
* History: initiated by bchang
*
* Notes:
*
******************************************************************************/
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#include "RTE_Device.h"
#include "Driver_Common.h"
#include "usbmst_top.h"
#include "uldp.h"
#if FEATURE_CCIO_ENABLE
#include "usb_device.h"
#endif
//#include "usbc_ctrl.h"
#include "uart.h"
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* GLOBAL VARIABLES *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTION DECLEARATION *
*----------------------------------------------------------------------------*/
extern int32_t uldpUsbClrCmpltFlg(usbmst_top_st *ptop,uint8_t epNum);
extern void delay_us(uint32_t us);
extern uint32_t usbc_dev_int_handler (void);
extern int32_t uldpUsbGetCmpltFlg(usbmst_top_st *ptop);
extern int32_t ulog_vcom_chkdtr( void );
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTIONS *
*----------------------------------------------------------------------------*/
#if (RTE_USB_EN == 1)
/**
\fn usbPollingRecv(uint32_t epNum, uint8_t *data, uint32_t num, uint32_t timeout_us)
\brief used to recv data from host via polling, uldp is still involved
\param[in] epNum ep number for recv
\param[in] data data pointer to store recv data
\param[in] num recv data length
\param[in] timeout_us timeout value when nothing recv
\note only called in eeh dump procedure
*/
static uint32_t usbPollingRecv(uint32_t epNum, uint8_t *data, uint32_t num, uint32_t timeout_us)
{
uint32_t rbIdx=0,avaSize=0;
uint32_t rbAddr,rbLen;
if(num == 0)
return num;
//wait until cmplt flag set for epNum or timeout
while((!(uldpUsbGetCmpltFlg(NULL)&(1<<epNum)))&&timeout_us)
{
delay_us(1);
timeout_us--;
}
if(timeout_us == 0)//timeout, recv nothing
return 0;
//get recv data length
uldpEpBufInfoGet((UsbRxEpNum_e)epNum,&rbIdx,&avaSize);
extern void ccioGetLogRbAddrLen(uint32_t *len, uint32_t *addr );
ccioGetLogRbAddrLen(&rbLen,&rbAddr);
//clr cmplt flag
uldpUsbClrCmpltFlg(NULL,epNum);
//cfg next rx
uldpCfgRxEpPara((UsbRxEpNum_e)epNum, 1,0,rbLen);
usbDevCfgOutXfer(usbDevGetLogIfIdx());
if(rbIdx<=num)
{
memcpy(data,(uint8_t *)rbAddr,rbIdx);
return rbIdx;
}
else
{
memcpy(data,(uint8_t *)rbAddr,num);// more data recv than expected
return num;
}
}
/**
\fn usbUldpEehInit(uint32_t epNum)
\brief used to reinit uldp recv in polling mode
\param[in] epNum ep number for recv
\note only called in eeh dump procedure
*/
static void usbUldpEehInit(uint32_t epNum)
{
uint32_t rbLen;
uint32_t addr;
ECPLAT_PRINTF(UNILOG_CCIO, usbUldpEehInit_1, P_SIG, "dump outep num %d", epNum);
//step1 static and working mode should inherent from CCIO LOG devive, ignore!
//step2 clear LOG outep cmplt int,maybe a int is coming during dump
uldpUsbClrCmpltFlg(NULL,epNum);
//step3 configure a new transfer, from beginning of RB
extern void ccioGetLogRbAddrLen(uint32_t *len, uint32_t *addr );
ccioGetLogRbAddrLen(&rbLen,&addr);
uldpCfgRxEpStaticPara(epNum, addr, rbLen);
uldpCfgRxEpPara((UsbRxEpNum_e)epNum, 1,0,rbLen);
usbDevCfgOutXfer(usbDevGetLogIfIdx());
}
#endif
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS *
*----------------------------------------------------------------------------*/
/**
\fn eehDumpMediaInit( void )
\brief used to init dump media for eeh dump, map to UART or USB
\param[in] N/A
\note only called in eeh dump procedure
*/
void eehDumpMediaInit( void )
{
#if (RTE_USB_EN == 1)
uint8_t epNum = 0;
#endif
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
UART_init(0,/*DUMP_UART_INSTANCE--TBD!!*/ 921600, false);
}
else//USB
{
#if (RTE_USB_EN == 1)
//usbTxRxFifoFlush();//to be added
epNum = usbDevGetEpNumFromIf(usbDevGetLogIfIdx());
extern void usbc_ctrl_diep_unmask(uint32_t epnum);
usbc_ctrl_diep_unmask((uint32_t)((epNum>>4)&0xf));
//usbc_ctrl_flush_txfifo(&t_usbc_core_top, epNum);
//usbc_ctrl_flush_rxfifo(&t_usbc_core_top);
usbUldpEehInit((epNum&0xf));//low 4 bit is outep num
#endif
}
}
/**
\fn eehDumpMediaFlush(uint32_t instance)
\brief used to flush FIFO, only valid for UART now
\param[in] instance UART instance
\note only called in eeh dump procedure
*/
void eehDumpMediaFlush(uint32_t instance)
{
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
UART_flush(instance);//flush both TX/RX FIFO
}
else//USB
{
// TBD: no need to flush, flushed when init
}
}
/**
\fn eehDumpMediaPurgeRx(uint32_t instance)
\brief used to flush FIFO, only valid for UART now
\param[in] instance UART instance
\note only called in eeh dump procedure
*/
void eehDumpMediaPurgeRx(uint32_t instance)
{
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
UART_purgeRx(instance);//flush both RX FIFO
}
else//USB
{
// TBD: no need to flush, flushed when init
}
}
/**
\fn eehDumpMediaRecv(uint32_t instance, uint8_t *data, uint32_t num, uint32_t timeout_us)
\brief used to recv data from host via polling, uldp is still involved
\param[in] instance ep number or uart instance for recv
\param[in] data data pointer to store recv data
\param[in] num recv data length
\param[in] timeout_us timeout value when nothing recv
\note only called in eeh dump procedure
*/
uint32_t eehDumpMediaRecv(uint32_t instance, uint8_t *data, uint32_t num, uint32_t timeout_us)
{
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
return UART_receive(instance, data, num, timeout_us);
}
else//USB
{
#if (RTE_USB_EN == 1)
return usbPollingRecv(instance, data, num, timeout_us);
#else
return 0;
#endif
}
}
/**
\fn eehDumpMediaSend(uint32_t instance, uint8_t *data, uint32_t num, uint32_t timeout_us)
\brief used to recv data from host via polling, uldp is still involved
\param[in] instance ep number or uart instance for recv
\param[in] data data pointer to send
\param[in] num send data length
\param[in] timeout_us timeout value when nothing recv
\note only called in eeh dump procedure
*/
uint32_t eehDumpMediaSend(uint32_t instance, uint8_t *data, uint32_t num, uint32_t timeout_us)
{
if(uniLogGetPherType() == UART_0_FOR_UNILOG)
{
return UART_send(instance, data, num, timeout_us);
}
else//USB
{
#if (RTE_USB_EN == 1)
#if 0
//check ep0 recv data from uldp
if((uldpUsbGetCmpltFlg(NULL)&0x1) == 0x1)
{
uldpUsbEp0RecvHandle();
}
#endif
// to be added: call USB polling send API
extern int ulog_vcom_polling_write(uint32_t instance, uint8_t *data, uint16_t num, uint32_t timeout_us);
return ulog_vcom_polling_write(instance, data, (uint16_t)num, timeout_us);
#else
return 0;
#endif
}
}
/**
\fn eehDumpMediaPollingEp0(uint32_t loopCnt, uint32_t loopInr)
\brief polling EP0 ctrl info and handle it, e.g. VCOM open
\param[in] loopCnt how many loop times
\param[in] loopInr internalval for each loop
\note only called in eeh dump procedure
host will first send request(set/get line coding etc) on every interface(not by EPAT)
then EPAT will open VCOM
serial_vcom1_chkdtr will check setcontrolline state is active
after active, host will not stop and will send more request,
that's why we will loop more times after active
!!but if host send addtional request after this API, will not response.!!
*/
void eehDumpMediaPollingEp0(uint32_t loopCnt, uint32_t loopInr)
{
#if (RTE_USB_EN == 1)
uint32_t loop = 200;
while(loopCnt--)
{
//check ep0 recv data from uldp
if((uldpUsbGetCmpltFlg(NULL)&0x1) == 0x1)
{
uldpUsbEp0RecvHandle();
}
//delay_us(loopInr);
//loop if any pending usb int
usbc_dev_int_handler( );
delay_us(loopInr);
if((loopCnt%500 == 0)&&(uniLogGetPherType() == USB_FOR_UNILOG))//add log per 500ms to avoid host suspend
{
ECPLAT_PRINTF(UNILOG_CCIO, eehDumpMediaPollingEp0_1, P_INFO, "eehDumpMediaPollingEp0:avoid host suspend %d",loopCnt);
uniLogForceOut(true);
}
if(ulog_vcom_chkdtr()==1)
{
while(loop--)
{
//check ep0 recv data from uldp
if((uldpUsbGetCmpltFlg(NULL)&0x1) == 0x1)
{
uldpUsbEp0RecvHandle();
}
//delay_us(loopInr);
//loop if any pending usb int
usbc_dev_int_handler( );
delay_us(loopInr);
}
break;
}
}
#endif
}
/**
\fn eehDumpMediaPollingRndisHalt(uint32_t loopCnt, uint32_t loopInr)
\brief request rndis halt to host, need polling send sucesss or timeout
\param[in] loopCnt how many loop times
\param[in] loopInr internalval for each loop
\note only called in eeh dump procedure
*/
int32_t eehDumpMediaPollingRndisHalt(uint32_t loopCnt, uint32_t loopInr)
{
#if (RTE_USB_EN == 1)
int32_t ret = -1;
uint16_t cntBefore = 0, cntAfter = 0;
extern uint16_t get_rndis_func_notifyok_cnt( void );
extern int rndis0_sig_set_halt(void);
//step1: loop request send ok
while(loopCnt--)
{
ret=rndis0_sig_set_halt();
if(ret == 0)
break;
delay_us(loopInr);
if((loopCnt%500 == 0)&&(uniLogGetPherType() == USB_FOR_UNILOG))//add log per 500ms to avoid host suspend
{
ECPLAT_PRINTF(UNILOG_CCIO, eehDumpMediaPollingRndisHalt_0, P_INFO, "eehDumpMediaPollingRndisHalt0:avoid host suspend %d",loopCnt);
uniLogForceOut(true);
}
}
if(ret < 0)
return ret ;
cntBefore=get_rndis_func_notifyok_cnt();
while(loopCnt--)
{
//loop if any pending usb int
usbc_dev_int_handler( );
delay_us(loopInr);
if((loopCnt%500 == 0)&&(uniLogGetPherType() == USB_FOR_UNILOG))//add log per 500ms to avoid host suspend
{
ECPLAT_PRINTF(UNILOG_CCIO, eehDumpMediaPollingRndisHalt_1, P_INFO, "eehDumpMediaPollingRndisHalt1:avoid host suspend %d",loopCnt);
uniLogForceOut(true);
}
cntAfter = get_rndis_func_notifyok_cnt();
if(cntAfter > cntBefore)
return 0;
}
return -1;
#else
return 0;
#endif
}

View File

@@ -0,0 +1,346 @@
/****************************************************************************
*
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
* File name: hal_i2s.c
* Description: EC618 i2s hal driver source file
* History: Rev1.0 2021-9-18
*
****************************************************************************/
#include "hal_i2s.h"
void es8388MasterInit(void);
void es8388SlaveInit(void);
void nau88c22SlaveInit(void);
void nau88c22MasterInit(void);
void es8311MasterInit(void);
void es8311SlaveInit(void);
extern i2sDrvInterface_t i2sDrvInterface0;
extern i2sDrvInterface_t i2sDrvInterface1;
#if (RTE_I2S0)
static i2sDrvInterface_t *i2sDrv = &CREATE_SYMBOL(i2sDrvInterface, 0); // Choose i2s0
#elif (RTE_I2S1)
static i2sDrvInterface_t *i2sDrv = &CREATE_SYMBOL(i2sDrvInterface, 1); // Choose i2s1
#endif
extern i2sDataFmt_t i2sDataFmt;
extern i2sSlotCtrl_t i2sSlotCtrl;
extern i2sBclkFsCtrl_t i2sBclkFsCtrl;
extern i2sCtrl_t i2sCtrl;
extern i2sDmaCtrl_t i2sDmaCtrl;
static codecType_e codecType; // Record codec type
static i2sMode_e i2sMode;
// Register
void HAL_I2sInit(i2sPowerCtrl_e powerCtrl, i2sCbFunc_fn txCb, i2sCbFunc_fn rxCb)
{
i2sDrv->init(txCb, rxCb);
switch (powerCtrl)
{
case I2S_CLK_DISABLE:
i2sDrv->powerCtrl(I2S_POWER_OFF);
break;
case I2S_CLK_ENABLE:
i2sDrv->powerCtrl(I2S_POWER_FULL);
break;
}
}
void HAL_I2SSetTotalNum(uint32_t totalNum)
{
i2sDrv->ctrl(I2S_CTRL_SET_TOTAL_NUM , totalNum);
}
uint32_t HAL_I2SGetTotalNum()
{
return i2sDrv->getTotalCnt();
}
void HAL_I2SSetPlayRecord(i2sPlayRecord_e playRecord)
{
if (playRecord == PLAY)
{
i2sCtrl.i2sMode = 0x1; // Set I2S controller to send
i2sDmaCtrl.txDmaReqEn = 1;
i2sDmaCtrl.rxDmaReqEn = 0;
}
else if (playRecord == RECORD)
{
i2sCtrl.i2sMode = 0x2; // Set I2S controller to receive
i2sDmaCtrl.rxDmaReqEn = 1; // Enable I2S controller RX DMA
i2sDmaCtrl.txDmaReqEn = 0;
}
i2sDrv->ctrl(I2S_CTRL_I2SCTL , 0);
i2sDrv->ctrl(I2S_CTRL_DMA_CTRL , 0);
}
void HAL_I2sConfig(i2sParamCtrl_t paramCtrl)
{
// 1. Setting parameters per the I2S working mode
i2sMode = paramCtrl.mode;
switch (i2sMode)
{
case MSB_MODE:
i2sDataFmt.dataDly = 0;
i2sBclkFsCtrl.bclkPolarity = 1;
i2sBclkFsCtrl.fsPolarity = 1;
break;
case LSB_MODE:
i2sDataFmt.dataDly = 1;
i2sBclkFsCtrl.bclkPolarity = 1;
i2sBclkFsCtrl.fsPolarity = 1;
break;
case I2S_MODE:
i2sDataFmt.dataDly = 1;
if (paramCtrl.codecType == CODEC_ES8311)
{
i2sBclkFsCtrl.bclkPolarity = 1;
}
else
{
i2sBclkFsCtrl.bclkPolarity = 0;
}
i2sBclkFsCtrl.fsPolarity = 1;
break;
case PCM_MODE:
// Configure codec to PCM mode
i2sBclkFsCtrl.bclkPolarity = 1;
break;
default:
break;
}
// 2. Init codec and I2S controller
switch (paramCtrl.codecType)
{
case CODEC_ES8388:
{
codecType = ES8388;
if (paramCtrl.role == CODEC_MASTER_MODE) // Codec act as master
{
i2sDrv->ctrl(I2S_CTRL_SAMPLE_RATE_SLAVE , paramCtrl.sampleRate); // I2S Set sample rate in slave role
es8388MasterInit();
}
else // Codec act as slave
{
i2sDataFmt.slaveModeEn = 0; // Master mode
i2sDrv->ctrl(I2S_CTRL_DATA_FORMAT , 0);
i2sDrv->ctrl(I2S_CTRL_SAMPLE_RATE_MASTER , paramCtrl.sampleRate); // I2S Set sample rate in master role
es8388SlaveInit();
}
break;
}
case CODEC_NAU88C22:
{
codecType = NAU88C22;
if (paramCtrl.role == CODEC_MASTER_MODE) // Codec act as master
{
i2sDrv->ctrl(I2S_CTRL_SAMPLE_RATE_SLAVE , paramCtrl.sampleRate); // I2S Set sample rate in slave role
nau88c22MasterInit();
}
else // Codec act as slave
{
i2sDataFmt.slaveModeEn = 0; // Master mode
i2sDrv->ctrl(I2S_CTRL_DATA_FORMAT , 0);
i2sDrv->ctrl(I2S_CTRL_SAMPLE_RATE_MASTER , paramCtrl.sampleRate); // I2S Set sample rate in slave role
nau88c22SlaveInit();
}
break;
}
case CODEC_ES7148:
case CODEC_ES7149:
case CODEC_TM8211:
{
// now we only can act as master mode
i2sDataFmt.slaveModeEn = 0; // Master mode
i2sDrv->ctrl(I2S_CTRL_DATA_FORMAT , 0);
i2sDrv->ctrl(I2S_CTRL_SAMPLE_RATE_MASTER , paramCtrl.sampleRate); // I2S Set sample rate in master role
break;
}
case CODEC_ES8311:
{
codecType = ES8311;
if (paramCtrl.role == CODEC_MASTER_MODE) // Codec act as master
{
i2sDrv->ctrl(I2S_CTRL_SAMPLE_RATE_SLAVE , paramCtrl.sampleRate); // I2S Set sample rate in slave role
es8311MasterInit();
}
else // Codec act as slave
{
i2sDataFmt.slaveModeEn = 0; // Master mode
i2sDrv->ctrl(I2S_CTRL_DATA_FORMAT , 0);
i2sDrv->ctrl(I2S_CTRL_SAMPLE_RATE_MASTER , paramCtrl.sampleRate); // I2S Set sample rate in master role
es8311SlaveInit();
}
break;
}
default:
break;
}
// 3. Set frame size
switch (paramCtrl.frameSize)
{
case FRAME_SIZE_16_16:
i2sDataFmt.slotSize = 0xf;
i2sBclkFsCtrl.fsWidth = 0xf;
i2sDataFmt.wordSize = 0xf;
break;
case FRAME_SIZE_16_32:
// I2S controller part
i2sDataFmt.slotSize = 0x1f;
i2sDataFmt.wordSize = 0xf;
i2sBclkFsCtrl.fsWidth = 0x1f;
break;
case FRAME_SIZE_24_32:
// I2S controller part
i2sDataFmt.slotSize = 0x1f;
i2sDataFmt.wordSize = 0x17;
i2sBclkFsCtrl.fsWidth = 0x1f;
break;
case FRAME_SIZE_32_32:
// I2S controller part
i2sDataFmt.slotSize = 0x1f;
i2sDataFmt.wordSize = 0x1f;
i2sBclkFsCtrl.fsWidth = 0x1f;
break;
default:
break;
}
// 4. Select mono or dual-channel
switch(paramCtrl.channelSel)
{
case MONO:
{
i2sSlotCtrl.slotEn = 1;
i2sSlotCtrl.slotNum = 1;
}
break;
case DUAL_CHANNEL:
{
i2sSlotCtrl.slotEn = 3;
i2sSlotCtrl.slotNum = 1;
}
break;
default:
break;
}
// Init part of I2S controller
i2sDrv->ctrl(I2S_CTRL_DATA_FORMAT , 0);
i2sDrv->ctrl(I2S_CTRL_BCLK_FS_CTRL , 0);
i2sDrv->ctrl(I2S_CTRL_SLOT_CTRL , 0);
// 5. Set play or record
HAL_I2SSetPlayRecord(paramCtrl.playRecord);
}
void HAL_I2sTransfer(i2sPlayRecord_e playRecord, uint8_t* memAddr, uint32_t trunkSize)
{
// 5. After other parameters are ready, start the I2S controller
if (playRecord == PLAY) // Play audio
{
i2sDrv->send(memAddr, trunkSize);
}
else // Record audio
{
i2sDrv->recv(memAddr, trunkSize);
}
}
void HAL_I2sSrcAdjustVolumn(int16_t* srcBuf, uint32_t srcTotalNum, uint16_t volScale)
{
int integer = volScale / 10;
int decimal = volScale % 10;
int scale = 0;
int32_t tmp = 0;
uint32_t totalNum = srcTotalNum;
uint32_t step = 0;
while (totalNum)
{
if (volScale < 10)
{
tmp = ((*(srcBuf + step)) * (256 * integer + 26 * decimal)) >> 8;
}
else
{
scale = (256 * integer + 26 * decimal) >> 8;
tmp = (*(srcBuf + step)) * scale;
}
if (tmp > 32767)
{
tmp = 32767;
}
else if (tmp < -32768)
{
tmp = -32768;
}
*(srcBuf + step) = (int16_t)tmp;
step += 1;
totalNum -= 2;
}
}
// Control I2S to start or stop. Note: when app wakeup from sleep1, need to call this api to start MCLK and i2s
void HAL_I2sStartSop(i2sStartStop_e startStop)
{
i2sDrv->ctrl(I2S_CTRL_START_STOP , startStop);
}
#if 0
// Control volumn of codec when play the audio
void HAL_I2sVolumnCtrl(i2sVolumnCtrl_e volumnCtrl, uint8_t step)
{
if (volumnCtrl == VOLUMN_INCREASE)
{
codecCtrlVolume(codecType, TRUE, step); // Increase volumn
}
else
{
codecCtrlVolume(codecType, FALSE, step); // Decrease volumn
}
}
#endif

View File

@@ -0,0 +1,187 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename:
*
* Description:
*
* History: initiated by xxxx
*
* Notes:
*
******************************************************************************/
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#include <stdbool.h>
#include "cmsis_os2.h"
#include "hal_misc.h"
#include "sctdef.h"
#include "ec618.h"
#include "clock.h"
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*
* GLOBAL VARIABLES *
*----------------------------------------------------------------------------*/
extern uint32_t SystemCoreClock;
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTION DECLEARATION *
*----------------------------------------------------------------------------*/
extern uint32_t GPR_getChipFullID(void);
extern uint32_t GPR_getChipRevID(void);
extern uint32_t GPR_getChipID(void);
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTIONS *
*----------------------------------------------------------------------------*/
/*
* cpu cycles delay, every loop spends 2 cpu cycles, so the actual delay is 2*cycles
* Parameter: cycles
*/
#if defined(__CC_ARM)
PLAT_PA_RAMCODE __asm static void delay_cycles(uint32_t cycles)
{
loop
SUBS r0, r0, #1
BNE loop
BX lr
}
#elif defined (__GNUC__)
PLAT_PA_RAMCODE static void delay_cycles(uint32_t cycles)
{
asm volatile(
"mov r0, %0\n\t"
"loop:\n\t"
"SUBS r0, r0, #1\n\t"
"BNE loop\n\t"
: : "r" (cycles)
);
}
#endif
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS *
*----------------------------------------------------------------------------*/
/**
\fn HAL_Get_ChipID(chip_id_sel sel)
\brief Get chip id.
\param[in] HAL_Get_ChipID enum
\note
31-----8 is chip id
7------0 is revision id
sel=CHIP_ID_ONLYID, return chip id
sel=CHIP_ID_REVID, return revision id
sel=CHIP_ID_FULL, return both revision and chip id
*/
uint32_t HAL_Get_ChipID(chip_id_sel sel)
{
uint32_t chipID=0;
switch(sel)
{
case CHIP_ID_ONLYID:
chipID=GPR_getChipID();
break;
case CHIP_ID_REVID:
chipID=GPR_getChipRevID();
break;
case CHIP_ID_FULLID:
chipID=GPR_getChipFullID();
break;
default:
break;
}
return chipID;
}
/**
\fn delay_us(uint32_t us)
\brief delay time in microseconds.
\param[in] number of us
\note Given the maximum cpu frequency is 204.8MHz and the limit in calculation,
* the maximum time can be delayed is 0xFFFFFFFF / 2048 = 2097151 us = 2097 m
*/
PLAT_PA_RAMCODE void delay_us(uint32_t us)
{
uint32_t ticks;
// cpu frequency ranges from 26MHz to 204.8MHz
// first divide 0.1M to get rid of multiply overflow
// considering 3 cpu cycles are taken to execute one loop operation(sub and branch) in delay_cycles function(includ one pre read assembly),
// and 0.1M in first step, so we shall divide another 30 before passing the result to delay_cycles function
// if the delay us is short, it may not be accurate
ticks = SystemCoreClock / 100000U;
ticks = ticks * us / 30U;
delay_cycles(ticks);
}
/**
\fn apmuBootDbgGPIOSet(bool level)
\brief set gpio level in boot flow, for boot time dbg
\param[in] gpio level
\note should set register directly, do not use api
*/
void apmuBootDbgGPIOSet(bool level)
{
#if 0
volatile uint32_t *apb_mp_pclken = (volatile uint32_t *)0x4d000030;
(*apb_mp_pclken) |= ((1<<6) | (1<<7)); // pclk pad and gpio
GPIO_TypeDef *base = (GPIO_TypeDef *)0x4D070000; //gpio instance 0
base->OUTENSET = (1<<7);
base->DATAOUT = (level<<7);
#endif
}
/**
\fn bool apmuGetLongSlpCfg(void)
\brief config the maximum sleep length.
1. We suggest return false to sleep no more than 36hour
2. But when usb is disabled and you do not care about time accuracy,
return true to set maximum sleep time to 1165 hour
\note false: sleep no more than 36.4 hour, true: can sleep 1165 hour
*/
bool apmuGetLongSlpCfg(void)
{
return false;
}
ClockId_e CLOCK_checkClkID(void)
{
return INVALID_CLK;
}

View File

@@ -0,0 +1,326 @@
/******************************************************************************
*(C) Copyright 2018 AirM2M International Ltd.
* All Rights Reserved
******************************************************************************
* Filename: pwrkey.c
*
* Description: power on/off and software debounce
*
* History: initiated by Zhao Weiqi
*
* Notes:
*
******************************************************************************/
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#ifndef FEATURE_BOOTLOADER_PROJECT_ENABLE
#include <string.h>
#include "hal_pwrkey.h"
#include "ec618.h"
#include "FreeRTOS.h"
#include "cmsis_os2.h"
#include "queue.h"
#include "exception_process.h"
#include "reset.h"
#include "apmu_external.h"
#include "slpman.h"
#include DEBUG_LOG_HEADER_FILE
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
#define PWRKEY_TASK_STATK_SIZE 512
#define PWRKEY_EVENT_QUEUE_SIZE 2
#define PWRKEY_KEY_MESSAGE 0x1
#define PWRKEY_LOCK_SLEEP() slpManDrvVoteSleep(SLP_VOTE_PWRKEY, SLP_ACTIVE_STATE)
#define PWRKEY_UNLOCK_SLEEP() slpManDrvVoteSleep(SLP_VOTE_PWRKEY, SLP_SLP1_STATE)
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
typedef struct {
uint32_t messageId;
} pwrKeyQueueMsg_t;
typedef void(* pwrKeyIsrCb)(void);
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTION DECLEARATION *
*----------------------------------------------------------------------------*/
static void pwrKeyLongPressTimerExp(void *argument);
/*----------------------------------------------------------------------------*
* GLOBAL VARIABLES *
*----------------------------------------------------------------------------*/
pwrKeyInfo_t gPwrKeyInfo;
static uint8_t pwrKeyLongPressTimerId = 0;
static uint8_t pwrKeyRepeatTimerId = 0;
static QueueHandle_t pwrKeyEventQueueHandle;
osTimerId_t pwrKeyLongPressTimer;
osTimerId_t pwrKeyRepeatTimer;
pwrKeyIsrCb pwrKeyIsrCallback = NULL;
/*----------------------------------------------------------------------------*
* PRIVATE FUNCTIONS *
*----------------------------------------------------------------------------*/
void pwrKeySendKeyStatus(void)
{
uint32_t msgId = PWRKEY_KEY_MESSAGE;
if (pwrKeyEventQueueHandle)
{
if (pdTRUE != xQueueSend(pwrKeyEventQueueHandle, &msgId, 1000))
{
ECPLAT_PRINTF(UNILOG_PMU, pwrKeySendKeyStatus_1, P_VALUE, "Power Key message send error");
}
}
else
{
ECPLAT_PRINTF(UNILOG_PMU, pwrKeySendKeyStatus_2, P_VALUE, "Power Key queue not ready");
}
}
void pwrKeySendKeyStatusInIsr(void)
{
BaseType_t xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
uint32_t msgId = PWRKEY_KEY_MESSAGE;
if (pwrKeyEventQueueHandle)
{
if (pdTRUE != xQueueSendFromISR(pwrKeyEventQueueHandle, &msgId, &xHigherPriorityTaskWoken))
{
ECPLAT_PRINTF(UNILOG_PMU, pwrKeySendKeyStatusInIsr_1, P_VALUE, "Power Key message send in isr error");
}
}
else
{
ECPLAT_PRINTF(UNILOG_PMU, pwrKeySendKeyStatusInIsr_2, P_VALUE, "Power Key queue not ready in isr");
}
if(xHigherPriorityTaskWoken)
{
portYIELD_FROM_ISR(pdTRUE);
}
}
static void pwrKeyQueueInit(void)
{
pwrKeyEventQueueHandle = xQueueCreate(PWRKEY_EVENT_QUEUE_SIZE, sizeof(pwrKeyQueueMsg_t));
if(pwrKeyEventQueueHandle == NULL)
{
ECPLAT_PRINTF(UNILOG_PMU, pwrKeyTask_1, P_VALUE, "Power Key task queue init error");
}
}
static void pwrKeyTask(void *arg)
{
uint32_t msgId = 0;
pwrKeyPressStatus keyStatus = PWRKEY_RELEASE;
while(1)
{
if (xQueueReceive(pwrKeyEventQueueHandle, &msgId, portMAX_DELAY))
{
switch(msgId)
{
case PWRKEY_KEY_MESSAGE:
keyStatus = pwrKeyPopKey(&gPwrKeyInfo);
if(gPwrKeyInfo.pwrKeyCallback != NULL)
{
gPwrKeyInfo.pwrKeyCallback(keyStatus);
}
if(keyStatus == PWRKEY_PRESS)
{
if(pwrKeyLongPressTimer == NULL)
pwrKeyLongPressTimer = osTimerNew((osTimerFunc_t)pwrKeyLongPressTimerExp, osTimerOnce, (void *)(uint32_t)pwrKeyLongPressTimerId, NULL);
osTimerStart(pwrKeyLongPressTimer, gPwrKeyInfo.delayCfg.longPressTimeout);
}
break;
default:
break;
}
}
}
}
static void pwrKeyTaskInit(void)
{
osThreadAttr_t task_attr;
memset(&task_attr,0,sizeof(task_attr));
task_attr.name = "pwrKeyTask";
task_attr.stack_size = PWRKEY_TASK_STATK_SIZE;
task_attr.priority = osPriorityNormal1;
osThreadNew(pwrKeyTask, NULL, &task_attr);
}
static void pwrKeyLongPressTimerExp(void *argument)
{
if(gPwrKeyInfo.curStatus == PWRKEY_PRESS)
{
gPwrKeyInfo.curStatus = PWRKEY_LONGPRESS;
pwrKeyPushKey(&gPwrKeyInfo, PWRKEY_LONGPRESS);
pwrKeySendKeyStatus();
if(pwrKeyRepeatTimer == NULL)
{
pwrKeyRepeatTimer = osTimerNew((osTimerFunc_t)pwrKeyLongPressTimerExp, osTimerOnce, (void *)(uint32_t)pwrKeyRepeatTimerId, NULL);
}
osTimerStart(pwrKeyRepeatTimer, gPwrKeyInfo.delayCfg.repeatTimeout);
}
else if(gPwrKeyInfo.curStatus == PWRKEY_LONGPRESS)
{
pwrKeyPushKey(&gPwrKeyInfo, PWRKEY_REPEAT);
pwrKeySendKeyStatus();
EC_ASSERT(pwrKeyRepeatTimer != NULL, 0, 0, 0);
osTimerStart(pwrKeyRepeatTimer, gPwrKeyInfo.delayCfg.repeatTimeout);
}
}
static void pwrkeyIntProcess(void)
{
bool pinlevel = pwrKeyGetPinLevel();
PWRKEY_LOCK_SLEEP();
if((gPwrKeyInfo.workMode == PWRKEY_WAKEUP_LOWACTIVE_MODE) ||
(gPwrKeyInfo.workMode == PWRKEY_PWRON_MODE))
{
if(pinlevel == true)
{
// release
gPwrKeyInfo.curStatus = PWRKEY_RELEASE;
pwrKeyPushKey(&gPwrKeyInfo, PWRKEY_RELEASE);
PWRKEY_UNLOCK_SLEEP();
pwrKeySendKeyStatusInIsr();
}
else
{
gPwrKeyInfo.curStatus = PWRKEY_PRESS;
pwrKeyPushKey(&gPwrKeyInfo, PWRKEY_PRESS);
pwrKeySendKeyStatusInIsr();
}
}
else if(gPwrKeyInfo.workMode == PWRKEY_WAKEUP_HIGHACTIVE_MODE)
{
if(pinlevel == true)
{
gPwrKeyInfo.curStatus = PWRKEY_PRESS;
pwrKeyPushKey(&gPwrKeyInfo, PWRKEY_PRESS);
pwrKeySendKeyStatusInIsr();
}
else
{
gPwrKeyInfo.curStatus = PWRKEY_RELEASE;
pwrKeyPushKey(&gPwrKeyInfo, PWRKEY_RELEASE);
PWRKEY_UNLOCK_SLEEP();
pwrKeySendKeyStatusInIsr();
}
}
}
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS *
*----------------------------------------------------------------------------*/
/* example for pwrKeyCallback :
void powerKeyStatusUpdate(pwrKeyPressStatus status)
{
ECPLAT_PRINTF(UNILOG_PMU, powerKeyStatusUpdate_1, P_VALUE, "PowerKey Status update to = %d", status);
if(status == PWRKEY_LONGPRESS)
{
pwrKeyStartPowerOff();
}
}
*/
void pwrKeyIntHandler(void)
{
if(pwrKeyIsrCallback != NULL)
pwrKeyIsrCallback();
}
void pwrKeyInit(pwrKeyWorkMode workMode, bool pullUpEn, pwrKeyDly_t dlyCfg, pwrKeyCallback_t Callback)
{
bool pinlevel = pwrKeyGetPinLevel();
memset(&gPwrKeyInfo, 0, sizeof(gPwrKeyInfo));
gPwrKeyInfo.delayCfg = dlyCfg;
gPwrKeyInfo.workMode = workMode;
gPwrKeyInfo.curStatus = PWRKEY_RELEASE;
gPwrKeyInfo.pwrKeyCallback = Callback;
pwrKeyHwInit(pullUpEn);
if(workMode == PWRKEY_PWRON_MODE)
{
if(pinlevel == false)
{
gPwrKeyInfo.curStatus = PWRKEY_PRESS;
}
}
else if(workMode == PWRKEY_WAKEUP_LOWACTIVE_MODE)
{
if(pinlevel == false)
{
gPwrKeyInfo.curStatus = PWRKEY_PRESS;
}
}
else if(workMode == PWRKEY_WAKEUP_HIGHACTIVE_MODE)
{
if(pinlevel == true)
{
gPwrKeyInfo.curStatus = PWRKEY_PRESS;
}
}
pwrKeyIsrCallback = pwrkeyIntProcess;
pwrKeyQueueInit();
pwrKeyTaskInit();
NVIC_EnableIRQ(PwrkeyWakeup_IRQn);
}
void pwrKeyDeinit(bool pullUpEn)
{
memset(&gPwrKeyInfo, 0, sizeof(gPwrKeyInfo));
pwrKeyHwDeinit(pullUpEn);
NVIC_DisableIRQ(PwrkeyWakeup_IRQn);
pwrKeyIsrCallback = NULL;
}
#endif

View File

@@ -0,0 +1,196 @@
/****************************************************************************
*
* Copy right: 2022-, Copyrigths of AirM2M Ltd.
* File name: hal_uartDump.c
* Description: source file for dumping info through UART when exception occurs
* Damn it, too many dependencies are pulled into this module
* History: Rev1.0 2022-1-17
*
****************************************************************************/
#include "uart.h"
#include "bsp_usart.h"
#include "bsp_lpusart.h"
#include "plat_config.h"
#include "apmu_external.h"
// Doesn't matter this variable is initialized or not since it'll be set in HAL_UartDumpPortInit
static uint8_t gCurrentUartDumpPort = 0xFF;
void HAL_UartDumpPortInit(void)
{
#ifdef __USER_CODE__
#else
uint32_t uartDumpPort = BSP_GetPlatConfigItemValue(PLAT_CONFIG_ITEM_UART_DUMP_PORT);
uint32_t uartBaudRate = 0;
#if RTE_UART0 == 1
extern ARM_DRIVER_USART Driver_USART0;
#endif
#if RTE_UART1 == 1
extern ARM_DRIVER_USART Driver_USART1;
extern ARM_DRIVER_USART Driver_LPUSART1;
#endif
#if RTE_UART2 == 1
extern ARM_DRIVER_USART Driver_USART2;
#endif
switch(uartDumpPort)
{
case 0:
#if RTE_UART0 == 1
uartBaudRate = Driver_USART0.GetBaudRate();
#endif
// Means uart has already been initialized
if((apmuGetImageType() == 1) && (uartBaudRate != 0))
{
UART_init(0, uartBaudRate, false);
gCurrentUartDumpPort = uartDumpPort;
}
else
{
// Add custom setting(pinmux & baudrate) here !!!!!!
#if 0
PadConfig_t config;
PAD_getDefaultConfig(&config);
config.mux = RTE_UART0_TX_FUNC;
config.pullSelect = PAD_PULL_INTERNAL;
config.pullUpEnable = PAD_PULL_UP_ENABLE;
config.pullDownEnable = PAD_PULL_DOWN_DISABLE;
PAD_setPinConfig(RTE_UART0_TX_BIT, &config);
UART_init(0, 115200, false);
gCurrentUartDumpPort = uartDumpPort;
#endif
}
break;
case 1:
#if RTE_UART1 == 1
if(apmuGetImageType() == 1)
{
uartBaudRate = Driver_USART1.GetBaudRate();
if(uartBaudRate == 0)
{
uartBaudRate = Driver_LPUSART1.GetBaudRate();
}
}
#endif
// Means uart has already been initialized
if((apmuGetImageType() == 1) && (uartBaudRate != 0))
{
UART_init(1, uartBaudRate, false);
gCurrentUartDumpPort = uartDumpPort;
}
else
{
// Add custom setting(pinmux & baudrate) here !!!!!!
#if 0
PadConfig_t config;
PAD_getDefaultConfig(&config);
config.mux = RTE_UART1_TX_FUNC;
config.pullSelect = PAD_PULL_INTERNAL;
config.pullUpEnable = PAD_PULL_UP_ENABLE;
config.pullDownEnable = PAD_PULL_DOWN_DISABLE;
PAD_setPinConfig(RTE_UART1_TX_BIT, &config);
UART_init(1, 115200, false);
gCurrentUartDumpPort = uartDumpPort;
#endif
}
break;
case 2:
#if RTE_UART2 == 1
uartBaudRate = Driver_USART2.GetBaudRate();
#endif
// Means uart has already been initialized
if((apmuGetImageType() == 1) && (uartBaudRate != 0))
{
UART_init(2, uartBaudRate, false);
gCurrentUartDumpPort = uartDumpPort;
}
else
{
// Add custom setting(pinmux & baudrate) here !!!!!!
#if 0
PadConfig_t config;
PAD_getDefaultConfig(&config);
config.mux = RTE_UART2_TX_FUNC;
config.pullSelect = PAD_PULL_INTERNAL;
config.pullUpEnable = PAD_PULL_UP_ENABLE;
config.pullDownEnable = PAD_PULL_DOWN_DISABLE;
PAD_setPinConfig(RTE_UART2_TX_BIT, &config);
UART_init(2, 115200, false);
gCurrentUartDumpPort = uartDumpPort;
#endif
}
break;
// means uart dump function is disabled
default:
gCurrentUartDumpPort = 0xFF;
return;
}
#endif
}
/**
\brief Check validation of uart dump port
\return true if current dump port is valid, otherwise false
*/
bool HAL_UartDumpPortCheck(void)
{
return (gCurrentUartDumpPort < USART_INSTANCE_NUM) ? true : false;
}
/**
\brief Send data to uart dump port in polling way
\param[in] data Pointer to buffer with data to be sent to
\param[in] num Number of data items to send
\param[in] timeout_us timeout value in unit of us
\return num of data items sent in the internal of timeout
*/
uint32_t HAL_UartDumpPortSend(const uint8_t *data, uint32_t num, uint32_t timeout_us)
{
if(gCurrentUartDumpPort < USART_INSTANCE_NUM)
{
return UART_send(gCurrentUartDumpPort, data, num, timeout_us);
}
else
{
return 0;
}
}