mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-21 10:25:54 +08:00
更新硬件SDK
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
#ifndef BSP_CODECDRV_H
|
||||
#define BSP_CODECDRV_H
|
||||
|
||||
#include "i2s.h"
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ES8388, ///< Codec ES8388
|
||||
NAU88C22, ///< Codec NAU88C22
|
||||
ES7148, ///< Codec ES7148
|
||||
ES7149, ///< Codec ES7149
|
||||
ES8311, ///< Codec ES8311
|
||||
}codecType_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t regAddr; ///< Register addr
|
||||
uint16_t regVal; ///< Register value
|
||||
}i2sI2cCfg_t;
|
||||
|
||||
|
||||
/**
|
||||
\brief Write value to codec via I2C.
|
||||
\param[in] codecType The codec type you use.
|
||||
\param[in] regAddr I2C register addr.
|
||||
\param[in] regVal I2C register value that need to write.
|
||||
\return
|
||||
*/
|
||||
void codecWriteVal(codecType_e codecType, uint8_t regAddr, uint16_t regVal);
|
||||
uint8_t codecReadVal(codecType_e codecType, uint8_t regAddr);
|
||||
//void codecCtrlVolume(codecType_e codecType, bool raise, uint8_t step);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef BSP_H
|
||||
#define BSP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "version.h"
|
||||
#include "Driver_Common.h"
|
||||
#include "Driver_I2C.h"
|
||||
#include "Driver_SPI.h"
|
||||
#include "Driver_USART.h"
|
||||
#include "RTE_Device.h"
|
||||
#include "pad.h"
|
||||
#include "gpio.h"
|
||||
#include "ic.h"
|
||||
#include "dma.h"
|
||||
#include "clock.h"
|
||||
|
||||
#define STRING_EOL "\r\n"
|
||||
#define BOARD_NAME "EC618_EVK"
|
||||
|
||||
#define SDK_VERSION "EC618_SW_V"SDK_MAJOR_VERSION"."SDK_MINOR_VERSION"."SDK_PATCH_VERSION
|
||||
#define EVB_VERSION "EC618_HW_V"EVB_MAJOR_VERSION"."EVB_MINOR_VERSION
|
||||
#define VERSION_INFO "-- SDK Version: "SDK_VERSION" -- "STRING_EOL"-- EVB Version: "EVB_VERSION" -- "STRING_EOL
|
||||
|
||||
#define BSP_HEADER STRING_EOL"-- Board: "BOARD_NAME " -- "STRING_EOL \
|
||||
VERSION_INFO \
|
||||
"-- Compiled: "__DATE__" "__TIME__" -- "STRING_EOL
|
||||
|
||||
#define ATI_VERSION_INFO STRING_EOL"-- Board: "BOARD_NAME " -- "STRING_EOL \
|
||||
"-- SDK Version: "SDK_VERSION" -- "STRING_EOL
|
||||
|
||||
#define SOFTVERSION "V"SDK_MAJOR_VERSION"."SDK_MINOR_VERSION"."SDK_PATCH_VERSION
|
||||
|
||||
|
||||
#define CREATE_SYMBOL(name, port) name##port
|
||||
|
||||
/** @brief UART port index
|
||||
* | UART port | Hardware Flow Control |
|
||||
* |-----------|-----------------------|
|
||||
* | UART0 | Y |
|
||||
* | UART1 | Y |
|
||||
* | UART2 | N |
|
||||
*/
|
||||
typedef enum usart_port
|
||||
{
|
||||
PORT_USART_0, /**< USART port 0. */
|
||||
PORT_USART_1, /**< USART port 1. */
|
||||
PORT_USART_2, /**< USART port 2. */
|
||||
PORT_USART_MAX, /**< The total number of USART ports (invalid UART port number). */
|
||||
PORT_USART_INVALID /**< USART invalid. */
|
||||
} usart_port_t;
|
||||
|
||||
extern ARM_DRIVER_USART *UsartPrintHandle;
|
||||
extern ARM_DRIVER_USART *UsartUnilogHandle;
|
||||
extern ARM_DRIVER_USART *UsartAtCmdHandle;
|
||||
|
||||
/** @brief IRQ Callback functions
|
||||
*/
|
||||
typedef void (*IRQ_Callback_t)();
|
||||
|
||||
|
||||
uint8_t* getBuildInfo(void);
|
||||
uint8_t* getATIVersionInfo(void);
|
||||
uint8_t* getVersionInfo(void);
|
||||
void FlushUnilogOutput(void);
|
||||
void SetUnilogUart(usart_port_t port, uint32_t baudrate, bool startRecv);
|
||||
void BSP_CommonInit(void);
|
||||
void setOSState(uint8_t state);
|
||||
uint8_t * getDebugDVersion(void);
|
||||
void delay_us(uint32_t us);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BSP_H */
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef BF30A2_H
|
||||
#define BF30A2_H
|
||||
|
||||
#define BF30A2_I2C_ADDR 0x6e
|
||||
|
||||
uint16_t bf30a2GetRegCnt(char* regName);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
#ifndef __CAMERA_DRV_H__
|
||||
#define __CAMERA_DRV_H__
|
||||
|
||||
#include "cspi.h"
|
||||
#include "sp0A39.h"
|
||||
#include "sp0821.h"
|
||||
#include "gc6123.h"
|
||||
#include "gc032A.h"
|
||||
#include "bf30a2.h"
|
||||
#include "gc6153.h"
|
||||
|
||||
#ifdef __USER_CODE__
|
||||
#ifndef CAM_CHAIN_COUNT
|
||||
#define CAMERA_ENABLE_BF30A2 1
|
||||
#define BF30A2_1SDR 1
|
||||
#define CAM_CHAIN_COUNT CAM_8W
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
\addtogroup cam_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t regAddr; ///< Sensor I2C register address
|
||||
uint8_t regVal; ///< Sensor I2C register value
|
||||
}camI2cCfg_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LSB_MODE = 0, ///< Little endian
|
||||
MSB_MODE = 1, ///< Big endian
|
||||
}endianMode_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIRE_1 = 0, ///< 1 wire
|
||||
WIRE_2 = 1, ///< 2 wire
|
||||
}wireNum_e;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SEQ_0 = 0, ///< rxd[0] 6 4 2 0
|
||||
///< rxd[1] 7 5 3 1
|
||||
SEQ_1 = 1, ///< rxd[1] 6 4 2 0
|
||||
///< rxd[0] 7 5 3 1
|
||||
}rxSeq_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CSPI_0 = 0,
|
||||
CSPI_1 = 1,
|
||||
}cspiInstance_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CSPI_START = 1, ///< cspi enable
|
||||
CSPI_STOP = 0, ///< Cspi disable
|
||||
}cspiStartStop_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CSPI_INT_ENABLE = 1, ///< cspi interrupt enable
|
||||
CSPI_INT_DISABLE = 0, ///< Cspi interrupt disable
|
||||
}cspiIntEnable_e;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
endianMode_e endianMode; ///< Endian mode
|
||||
wireNum_e wireNum; ///< Wire numbers
|
||||
rxSeq_e rxSeq; ///< Bit sequence in 2 wire mode
|
||||
uint8_t cpol;
|
||||
uint8_t cpha;
|
||||
uint8_t yOnly;
|
||||
uint8_t rowScaleRatio;
|
||||
uint8_t colScaleRatio;
|
||||
uint8_t scaleBytes;
|
||||
}camParamCfg_t;
|
||||
|
||||
typedef void (*camCbEvent_fn) (uint32_t event); ///< Camera callback event.
|
||||
typedef void (*camIrq_fn)(void); ///< Camera irq
|
||||
|
||||
|
||||
/**
|
||||
\brief Init camera, include pinMux, and enable clock.
|
||||
\param[in] dataAddr Mem addr to store picture.
|
||||
\param[in] cb Indicate that a picture has been taken.
|
||||
\return
|
||||
*/
|
||||
void camInit(void* dataAddr, camCbEvent_fn cb);
|
||||
|
||||
/**
|
||||
\brief Receive the picture has been taken.
|
||||
\param[out] dataIn The buffer which is used to store the picture.
|
||||
\return
|
||||
*/
|
||||
void camRecv(uint8_t * dataIn);
|
||||
|
||||
/**
|
||||
\brief Init sensor's registers.
|
||||
\return
|
||||
*/
|
||||
void camRegCfg(void);
|
||||
|
||||
/**
|
||||
\brief Write some parameters into the sensor.
|
||||
\param[in] regInfo Sensor I2C addr and value.
|
||||
\return
|
||||
*/
|
||||
void camWriteReg(camI2cCfg_t* regInfo);
|
||||
|
||||
/**
|
||||
\brief Read from the sensor's I2C address.
|
||||
\param[in] regAddr Sensor's I2C register address.
|
||||
\return
|
||||
*/
|
||||
uint8_t camReadReg(uint8_t regAddr);
|
||||
|
||||
/**
|
||||
\brief Start or stop Camera controller.
|
||||
\param[in] startStop If true, start camera controller. If false, stop camera controller.
|
||||
\return
|
||||
*/
|
||||
void camStartStop(cspiStartStop_e startStop);
|
||||
|
||||
/**
|
||||
\brief Register irq for cspi.
|
||||
\param[in] instance cspi0 or cspi1.
|
||||
\param[in] irqCb irq cb.
|
||||
\return
|
||||
*/
|
||||
void camRegisterIRQ(cspiInstance_e instance, camIrq_fn irqCb);
|
||||
|
||||
/**
|
||||
\brief Get cspi status.
|
||||
\param[in] instance cspi0 or cspi1.
|
||||
\return
|
||||
*/
|
||||
uint32_t camGetCspiStats(cspiInstance_e instance);
|
||||
|
||||
/**
|
||||
\brief Clear cspi interrupt status.
|
||||
\param[in] instance cspi0 or cspi1.
|
||||
\param[in] mask which bit needs to clear.
|
||||
\return
|
||||
*/
|
||||
void camClearIntStats(cspiInstance_e instance, uint32_t mask);
|
||||
|
||||
/**
|
||||
\brief Set memory addr which is used to store picture of camera.
|
||||
\param[in] dataAddr data addr.
|
||||
\return
|
||||
*/
|
||||
void camSetMemAddr(uint32_t dataAddr);
|
||||
|
||||
/**
|
||||
\brief Enable or disable interrupt of cspi.
|
||||
\param[in] intEnable interrupt enable or not.
|
||||
\return
|
||||
*/
|
||||
void cspiIntEnable(cspiIntEnable_e intEnable);
|
||||
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef GC032A_H
|
||||
#define GC032A_H
|
||||
|
||||
#define GC032A_I2C_ADDR 0x21
|
||||
|
||||
uint16_t gc032aGetRegCnt(char* regName);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef GC6123_H
|
||||
#define GC6123_H
|
||||
|
||||
#define GC6123_I2C_ADDR 0x40
|
||||
|
||||
uint16_t gc6123GetRegCnt(char* regName);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef GC6153_H
|
||||
#define GC6153_H
|
||||
|
||||
#define GC6153_I2C_ADDR 0x40
|
||||
|
||||
uint16_t gc6153GetRegCnt(char* regName);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef __I2C_GPIO_H__
|
||||
#define __I2C_GPIO_H__
|
||||
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
|
||||
// sda pin definition. gpio16
|
||||
#define SDA_GPIO_INSTANCE (1)
|
||||
#define SDA_GPIO_PIN (0)
|
||||
#define SDA_GPIO_ADDR (31)
|
||||
#define SDA_PAD_ALT_FUNC (PAD_MUX_ALT0)
|
||||
|
||||
// scl pin definition. gpio17
|
||||
#define SCL_GPIO_INSTANCE (1)
|
||||
#define SCL_GPIO_PIN (1)
|
||||
#define SCL_GPIO_ADDR (32)
|
||||
#define SCL_PAD_ALT_FUNC (PAD_MUX_ALT0)
|
||||
|
||||
#define I2C_SDA_0 do {GPIO_pinWrite(SDA_GPIO_INSTANCE, 1 << SDA_GPIO_PIN, 0);}while(0)
|
||||
#define I2C_SDA_1 do {GPIO_pinWrite(SDA_GPIO_INSTANCE, 1 << SDA_GPIO_PIN, 1 << SDA_GPIO_PIN);}while(0)
|
||||
|
||||
#define I2C_SCL_0 do {GPIO_pinWrite(SCL_GPIO_INSTANCE, 1 << SCL_GPIO_PIN, 0);}while(0)
|
||||
#define I2C_SCL_1 do {GPIO_pinWrite(SCL_GPIO_INSTANCE, 1 << SCL_GPIO_PIN, 1 << SCL_GPIO_PIN);}while(0)
|
||||
|
||||
|
||||
void i2cGpioInit();
|
||||
uint8_t i2cReadByte();
|
||||
void i2cWritebyte(uint8_t byte);
|
||||
void i2cStop();
|
||||
void i2cStart();
|
||||
void i2cAck();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef SP0821_H
|
||||
#define SP0821_H
|
||||
|
||||
#define SP0821_I2C_ADDR 0x43
|
||||
|
||||
uint16_t sp0821GetRegCnt(char* regName);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef SP0A39_H
|
||||
#define SP0A39_H
|
||||
|
||||
#define SP0A39_I2C_ADDR 0x21
|
||||
|
||||
uint16_t sp0a39GetRegCnt(char* regName);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2020-, Copyrigths of AirM2M Ltd.
|
||||
* File name: eepRom.h
|
||||
* Description: EC618 eepRom driver file
|
||||
* History: Rev1.0 2020-12-17
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _EEPROM_EC618_H
|
||||
#define _EEPROM_EC618_H
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
#include "oneWire.h"
|
||||
|
||||
/**
|
||||
\addtogroup eepRom_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief ROM Operation Command */
|
||||
#define ROM_READ_CMD 0x33
|
||||
#define ROM_MATCH_CMD 0x55
|
||||
#define ROM_SKIP_CMD 0xCC
|
||||
#define ROM_SEARCH_CMD 0xF0
|
||||
|
||||
/** \brief Memory Operation Command */
|
||||
#define MEM_READ_CMD 0xF0
|
||||
#define SCRATCHPAD_READ_CMD 0xAA
|
||||
#define SCRATCHPAD_WRITE_CMD 0x0F
|
||||
#define SCRATCHPAD_COPY_CMD 0x55
|
||||
|
||||
/** \brief EEPROM Status */
|
||||
#define EEPROMDRV_OK (0)
|
||||
#define EEPROMDRV_RESET_ERR (-1)
|
||||
#define EEPROMDRV_RESETPD_ERR (-2)
|
||||
#define EEPROMDRV_ROMREAD_ERR (-3)
|
||||
#define EEPROMDRV_ROMMATCH_ERR (-4)
|
||||
#define EEPROMDRV_ROMSKIP_ERR (-5)
|
||||
#define EEPROMDRV_ROMSEARCH_ERR (-6)
|
||||
#define EEPROMDRV_MEMREAD_ERR (-7)
|
||||
#define EEPROMDRV_SCRATCHPADREAD_ERR (-8)
|
||||
#define EEPROMDRV_SCRATCHPADWRITE_ERR (-9)
|
||||
#define EEPROMDRV_SCRATCHPADCOPY_ERR (-10)
|
||||
|
||||
/**
|
||||
\fn int32_t eePromReadRom(uint8_t* romCode)
|
||||
\brief EEPROM read ROM code
|
||||
\param[out] romCode ROM infomation read back.
|
||||
\return read ROM status
|
||||
*/
|
||||
int32_t eePromReadRom(uint8_t* romCode);
|
||||
|
||||
/**
|
||||
\fn eePromReadMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer)
|
||||
\brief EEPROM read memory.
|
||||
\param[in] targetAddr The target address of EEPROM.
|
||||
\param[in] len Length of this read.
|
||||
\param[out] buffer Data read back.
|
||||
\return read memory status
|
||||
*/
|
||||
int32_t eePromReadMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer);
|
||||
|
||||
/**
|
||||
\fn int32_t eePromWriteMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer)
|
||||
\brief EEPROM write memory
|
||||
\param[in] targetAddr The target address of EEPROM.
|
||||
\param[in] len Length of this write.
|
||||
\param[in] buffer Data needs to write into memory.
|
||||
\return Write memory status
|
||||
*/
|
||||
int32_t eePromWriteMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer);
|
||||
|
||||
void eepRomInit(OwModeSel_e mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "stdint.h"
|
||||
#include "bsp.h"
|
||||
|
||||
#define SPI_INSTANCE SPI0
|
||||
#define SPI_APB_CLOCK PCLK_SPI0
|
||||
#define SPI_FUNC_CLOCK FCLK_SPI0
|
||||
#define SPI_DMA_TX_REQID DMA_REQUEST_SPI0_TX // DMA SPI Request ID
|
||||
#define LCD_DMA_DESCRIPTOR_CHAIN_NUM 20 // 30w pixel
|
||||
#define LCD_TRANSFER_SIZE_ONCE 480//7680 // less than 8k
|
||||
|
||||
|
||||
|
||||
#define HEIGHT (129)
|
||||
#define WIDTH (128)
|
||||
|
||||
#define SPI_BUS_SPEED (1000000) // 13M
|
||||
|
||||
#define SPI_FLAG_TIMEOUT (0x1000)
|
||||
|
||||
|
||||
// SPI cs pin definition
|
||||
#define CS_GPIO_INSTANCE (0)
|
||||
#define CS_GPIO_PIN (8)
|
||||
#define CS_GPIO_ADDR (23)
|
||||
#define CS_PAD_ALT_FUNC (PAD_MUX_ALT0)
|
||||
|
||||
// SPI clk pin definition
|
||||
#define CLK_GPIO_INSTANCE (0)
|
||||
#define CLK_GPIO_PIN (11)
|
||||
#define CLK_GPIO_ADDR (26)
|
||||
#define CLK_PAD_ALT_FUNC (PAD_MUX_ALT1)
|
||||
|
||||
// SPI mosi pin definition
|
||||
#define MOSI_GPIO_INSTANCE (0)
|
||||
#define MOSI_GPIO_PIN (9)
|
||||
#define MOSI_GPIO_ADDR (24)
|
||||
#define MOSI_PAD_ALT_FUNC (PAD_MUX_ALT1)
|
||||
|
||||
// SPI miso pin definition
|
||||
#define MISO_GPIO_INSTANCE (0)
|
||||
#define MISO_GPIO_PIN (10)
|
||||
#define MISO_GPIO_ADDR (25)
|
||||
#define MISO_PAD_ALT_FUNC (PAD_MUX_ALT1)
|
||||
|
||||
|
||||
// LCD rst pin definition
|
||||
#define RST_GPIO_INSTANCE (1)
|
||||
#define RST_GPIO_PIN (4)
|
||||
#define RST_GPIO_ADDR (40)
|
||||
#define RST_PAD_ALT_FUNC (PAD_MUX_ALT0)
|
||||
|
||||
// LCD ds pin definition
|
||||
#define DS_GPIO_INSTANCE (1)
|
||||
#define DS_GPIO_PIN (12)
|
||||
#define DS_GPIO_ADDR (48)
|
||||
#define DS_PAD_ALT_FUNC (PAD_MUX_ALT0)
|
||||
|
||||
// LCD en pin definition
|
||||
#define EN_GPIO_INSTANCE (1)
|
||||
#define EN_GPIO_PIN (5)
|
||||
#define EN_GPIO_ADDR (41)
|
||||
#define EN_PAD_ALT_FUNC (PAD_MUX_ALT0)
|
||||
|
||||
|
||||
void st7571_init(void);
|
||||
void displayPic_60x80(uint8_t *p);
|
||||
void st7571CleanScreen(void);
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#include "stdint.h"
|
||||
#include "bsp.h"
|
||||
|
||||
#define SPI_INSTANCE SPI0
|
||||
#define SPI_APB_CLOCK PCLK_SPI0
|
||||
#define SPI_FUNC_CLOCK FCLK_SPI0
|
||||
#define SPI_DMA_TX_REQID DMA_REQUEST_SPI0_TX // DMA SPI Request ID
|
||||
#define LCD_DMA_DESCRIPTOR_CHAIN_NUM 20 // 30w pixel
|
||||
#define LCD_TRANSFER_SIZE_ONCE 480//7680 // less than 8k
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define SPI_BUS_SPEED (1000000) // 13M
|
||||
|
||||
#define SPI_FLAG_TIMEOUT (0x1000)
|
||||
|
||||
#define HEIGHT (320)
|
||||
#define WIDTH (240)
|
||||
#define RED (0xf800)
|
||||
#define GREEN (0x07e0)
|
||||
#define BLUE (0x001f)
|
||||
#define YELLOW (0xffe0)
|
||||
#define WHITE (0xffff)
|
||||
#define BLACK (0x0000)
|
||||
#define PURPLE (0xf81f)
|
||||
|
||||
|
||||
// SPI cs pin definition
|
||||
#define CS_GPIO_INSTANCE (0)
|
||||
#define CS_GPIO_PIN (8)
|
||||
#define CS_GPIO_ADDR (23)
|
||||
#define CS_PAD_ALT_FUNC (PAD_MUX_ALT0)
|
||||
|
||||
// SPI clk pin definition
|
||||
#define CLK_GPIO_INSTANCE (0)
|
||||
#define CLK_GPIO_PIN (11)
|
||||
#define CLK_GPIO_ADDR (26)
|
||||
#define CLK_PAD_ALT_FUNC (PAD_MUX_ALT1)
|
||||
|
||||
// SPI mosi pin definition
|
||||
#define MOSI_GPIO_INSTANCE (0)
|
||||
#define MOSI_GPIO_PIN (9)
|
||||
#define MOSI_GPIO_ADDR (24)
|
||||
#define MOSI_PAD_ALT_FUNC (PAD_MUX_ALT1)
|
||||
|
||||
// SPI miso pin definition
|
||||
#define MISO_GPIO_INSTANCE (0)
|
||||
#define MISO_GPIO_PIN (10)
|
||||
#define MISO_GPIO_ADDR (25)
|
||||
#define MISO_PAD_ALT_FUNC (PAD_MUX_ALT1)
|
||||
|
||||
|
||||
// LCD rst pin definition
|
||||
#define RST_GPIO_INSTANCE (1)
|
||||
#define RST_GPIO_PIN (1)
|
||||
#define RST_GPIO_ADDR (32)
|
||||
#define RST_PAD_ALT_FUNC (PAD_MUX_ALT0)
|
||||
|
||||
// LCD ds pin definition
|
||||
#define DS_GPIO_INSTANCE (1)
|
||||
#define DS_GPIO_PIN (0)
|
||||
#define DS_GPIO_ADDR (31)
|
||||
#define DS_PAD_ALT_FUNC (PAD_MUX_ALT0)
|
||||
|
||||
void st7789v2_init(void);
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
#ifndef IMAGE_PROCESS_H
|
||||
#define IMAGE_PROCESS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/**
|
||||
\brief Convert yuv422 to rgb565, used in color screen.
|
||||
\param[in] inbuf source memory.
|
||||
\param[out] outbuf output memory.
|
||||
\param[in] width source picture width.
|
||||
\param[in] height source picture height.
|
||||
\return
|
||||
*/
|
||||
void yuv422ToRgb565(const void* inbuf, void* outbuf, int width, int height);
|
||||
|
||||
/**
|
||||
\brief Scale the picture. Now this api can only zoom out the picture.
|
||||
\param[in] ratio Zoom out ratio.
|
||||
\param[in] inPtr Data source.
|
||||
\param[in] width Source data width.
|
||||
\param[in] height Source data height.
|
||||
\param[out] outPtr Output data address.
|
||||
\return
|
||||
*/
|
||||
void scalePic(uint8_t ratio, uint8_t* inPtr, uint16_t width, uint16_t height, uint8_t *outPtr);
|
||||
|
||||
/**
|
||||
\brief Clockwise rotate 90 degree.
|
||||
\param[in,out] mem Data source.
|
||||
\param[in] width Source picture width.
|
||||
\param[in] height Source picture height.
|
||||
\return
|
||||
*/
|
||||
void imageRotate(uint8_t* mem, uint32_t width, uint32_t height);
|
||||
|
||||
/**
|
||||
\brief Organize the bytes as horizontal or vertical.
|
||||
\param[in] inPut Src data.
|
||||
\param[in] pageLen The pageNum you want for these data, this param is set by you.
|
||||
\param[in] width The width you want for these data, this param is set by you.
|
||||
\param[out] outPut Output buffer.
|
||||
\param[in] horizotal These data you want to array them as horizontal or vertical.
|
||||
\return
|
||||
*/
|
||||
void storeByteIntoArray(uint8_t *inPut, uint8_t pageLen, uint16_t width, uint8_t *outPut, bool horizotal);
|
||||
|
||||
/**
|
||||
\brief Merge 8bytes into one byte, used in 1-bit LCD.
|
||||
\param[in] p Src data.
|
||||
\param[out] outPut Output buffer.
|
||||
\param[in] width Source data width.
|
||||
\param[out] height Source data height.
|
||||
\param[in] horizotal Fetch the data by row or by column.
|
||||
\param[in] inByteRevert Within the byte, positive or reverse the bit sequence.
|
||||
\return index How many bytes has been returned, for debug use
|
||||
*/
|
||||
uint16_t merge8Bytes2OneByte(uint8_t* p, uint8_t *outPut, uint16_t width, uint16_t height, bool horizotal, bool inByteRevert);
|
||||
|
||||
/**
|
||||
\brief Binary the source picture.
|
||||
\param[in] inPut Src data.
|
||||
\param[in] width Source picture width.
|
||||
\param[in] height Source picture height.
|
||||
\param[out] outPut Output buffer.
|
||||
\return
|
||||
*/
|
||||
void calBinary(uint8_t* inPut, uint16_t width, uint16_t height, uint8_t* outPut);
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* IMAGE_PROCESS_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
#ifndef BSP_LCD_H
|
||||
#define BSP_LCD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
|
||||
// Only need to choose which LCD you use
|
||||
#define ST7789V2_ENABLE 0
|
||||
#define ST7571_ENABLE 1
|
||||
|
||||
|
||||
|
||||
|
||||
#if (ST7789V2_ENABLE)
|
||||
#include "st7789v2.h"
|
||||
#endif
|
||||
|
||||
#if (ST7571_ENABLE)
|
||||
#include "st7571.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define SPI SPI_INSTANCE
|
||||
#define SPI_CS_LOW do {GPIO_pinWrite(SPI_CS_GPIO_INSTANCE, 1 << SPI_CS_GPIO_PIN, 0);}while(0)
|
||||
#define SPI_CS_HIGH do {GPIO_pinWrite(SPI_CS_GPIO_INSTANCE, 1 << SPI_CS_GPIO_PIN, 1 << SPI_CS_GPIO_PIN);}while(0)
|
||||
#define LCD_DS_LOW do {GPIO_pinWrite(LCD_DS_GPIO_INSTANCE, 1 << LCD_DS_GPIO_PIN, 0);}while(0)
|
||||
#define LCD_DS_HIGH do {GPIO_pinWrite(LCD_DS_GPIO_INSTANCE, 1 << LCD_DS_GPIO_PIN, 1 << LCD_DS_GPIO_PIN);}while(0)
|
||||
#define LCD_RST_LOW do {GPIO_pinWrite(LCD_RST_GPIO_INSTANCE, 1 << LCD_RST_GPIO_PIN, 0);}while(0)
|
||||
#define LCD_RST_HIGH do {GPIO_pinWrite(LCD_RST_GPIO_INSTANCE, 1 << LCD_RST_GPIO_PIN, 1 << LCD_RST_GPIO_PIN);}while(0)
|
||||
|
||||
#define SPI_SEND_DATA(data) do {SPI->DR = data;}while(0)
|
||||
#define SPI_READ_DATA (SPI->DR)
|
||||
#define SPI_WAIT_TX_DONE do {}while(!((SPI->SR & (SPI_SR_BSY_Msk | SPI_SR_TFE_Msk)) == SPI_SR_TFE_Msk))
|
||||
#define SPI_IS_BUSY do {}while((SPI->SR & SPI_SR_BSY_Msk) == SPI_SR_BSY_Msk)
|
||||
|
||||
#define SPI_START_DMA_CHANNEL(channel) do {*((uint32_t*)(0x4d1f0000 + (channel << 2))) |= 0x80000000;}while(0)
|
||||
#define SPI_STOP_DMA_CHANNEL(channel) do {*((uint32_t*)(0x4d1f0000 + (channel << 2))) &= ~0x80000000;}while(0)
|
||||
#define SPI_ENABLE_TX_DMA do {SPI->DMACR |= SPI_DMACR_TXDMAE_Msk;}while(0)
|
||||
|
||||
// Spi cs pin
|
||||
#define SPI_CS_GPIO_INSTANCE (CS_GPIO_INSTANCE)
|
||||
#define SPI_CS_GPIO_PIN (CS_GPIO_PIN)
|
||||
#define SPI_CS_PAD_ADDR (CS_GPIO_ADDR)
|
||||
#define SPI_CS_PAD_ALT_FUNC (CS_PAD_ALT_FUNC)
|
||||
|
||||
// Spi clk pin
|
||||
#define SPI_CLK_GPIO_INSTANCE (CLK_GPIO_INSTANCE)
|
||||
#define SPI_CLK_GPIO_PIN (CLK_GPIO_PIN)
|
||||
#define SPI_CLK_PAD_ADDR (CLK_GPIO_ADDR)
|
||||
#define SPI_CLK_PAD_ALT_FUNC (CLK_PAD_ALT_FUNC)
|
||||
|
||||
// Spi mosi pin
|
||||
#define SPI_MOSI_GPIO_INSTANCE (MOSI_GPIO_INSTANCE)
|
||||
#define SPI_MOSI_GPIO_PIN (MOSI_GPIO_PIN)
|
||||
#define SPI_MOSI_PAD_ADDR (MOSI_GPIO_ADDR)
|
||||
#define SPI_MOSI_PAD_ALT_FUNC (MOSI_PAD_ALT_FUNC)
|
||||
|
||||
// Spi miso pin
|
||||
#define SPI_MISO_GPIO_INSTANCE (MISO_GPIO_INSTANCE)
|
||||
#define SPI_MISO_GPIO_PIN (MISO_GPIO_PIN)
|
||||
#define SPI_MISO_PAD_ADDR (MISO_GPIO_ADDR)
|
||||
#define SPI_MISO_PAD_ALT_FUNC (MISO_PAD_ALT_FUNC)
|
||||
|
||||
|
||||
// Lcd rst pin
|
||||
#define LCD_RST_GPIO_INSTANCE (RST_GPIO_INSTANCE)
|
||||
#define LCD_RST_GPIO_PIN (RST_GPIO_PIN)
|
||||
#define LCD_RST_PAD_ADDR (RST_GPIO_ADDR)
|
||||
#define LCD_RST_PAD_ALT_FUNC (RST_PAD_ALT_FUNC)
|
||||
|
||||
// Lcd ds pin
|
||||
#define LCD_DS_GPIO_INSTANCE (DS_GPIO_INSTANCE)
|
||||
#define LCD_DS_GPIO_PIN (DS_GPIO_PIN)
|
||||
#define LCD_DS_PAD_ADDR (DS_GPIO_ADDR)
|
||||
#define LCD_DS_PAD_ALT_FUNC (DS_PAD_ALT_FUNC)
|
||||
|
||||
#if (ST7571_ENABLE)
|
||||
// Lcd en pin
|
||||
#define LCD_EN_GPIO_INSTANCE (EN_GPIO_INSTANCE)
|
||||
#define LCD_EN_GPIO_PIN (EN_GPIO_PIN)
|
||||
#define LCD_EN_PAD_ADDR (EN_GPIO_ADDR)
|
||||
#define LCD_EN_PAD_ALT_FUNC (EN_PAD_ALT_FUNC)
|
||||
#endif
|
||||
|
||||
typedef void (*pTxCb)(uint32_t event);
|
||||
|
||||
uint8_t lcdReadData(void);
|
||||
void lcdReadId(void);
|
||||
void lcdWriteCmd(uint8_t cmd);
|
||||
void lcdWriteData(uint8_t data);
|
||||
void lcdInit(pTxCb txCb);
|
||||
void mDelay(uint32_t mDelay);
|
||||
//void lcdWriteData16(uint16_t data);
|
||||
//void lcdDispColor(uint16_t color);
|
||||
void lcdDispWindows(void);
|
||||
//void lcdWriteDataDma(uint16_t color);
|
||||
void lcdWriteSetup(uint8_t * dataBuf, uint16_t dataCnt);
|
||||
void lcdWriteCtrl(bool startOrStop);
|
||||
void lcdClearScreen();
|
||||
void lcdDispPic(uint8_t * pic);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* BSP_LCD_H */
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef _NTC_H
|
||||
#define _NTC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Get NTC temperature
|
||||
|
||||
Vref(AIO1 output 1200000 uV)
|
||||
v
|
||||
|
|
||||
|
|
||||
+-+
|
||||
| |
|
||||
| | R = 10 Kohm
|
||||
| |
|
||||
+-+
|
||||
|--------->(AIO2)
|
||||
+-+
|
||||
| |
|
||||
| | Rntc
|
||||
| |
|
||||
+-+
|
||||
|
|
||||
-----
|
||||
--- (GND)
|
||||
-
|
||||
|
||||
\param[in] adcInputVoltage ADC input voltage in unit of uV
|
||||
\return temperature in unit of mili degree centigrade
|
||||
*/
|
||||
int32_t ntcGetTemperature(int32_t adcInputVoltage);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _NTC_H */
|
||||
@@ -0,0 +1,506 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
|
||||
* File name: plat_config.h
|
||||
* Description: platform configuration header file
|
||||
* History: Rev1.0 2019-01-18
|
||||
* Rev1.1 2019-11-27 Reimplement file operations with OSA APIs(LFS wrapper), not directly using LFS APIs in case of file system replacement
|
||||
* Rev1.2 2020-01-01 Separate plat config into two parts, FS and raw flash
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _PLAT_CONFIG_H
|
||||
#define _PLAT_CONFIG_H
|
||||
|
||||
#include "Driver_Common.h"
|
||||
#include "cmsis_compiler.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define FS_PLAT_CONFIG_FILE_CURRENT_VERSION (0)
|
||||
|
||||
#define RAW_FLASH_PLAT_CONFIG_FILE_CURRENT_VERSION (1)
|
||||
|
||||
|
||||
/** \brief config file header typedef */
|
||||
__PACKED_STRUCT _config_file_header
|
||||
{
|
||||
uint16_t fileBodySize; /**< size of file body, in unit of byte */
|
||||
uint8_t version; /**< file version, this field shall be updated when file structure is changed */
|
||||
uint8_t checkSum; /**< check sum value of file body */
|
||||
};
|
||||
typedef struct _config_file_header config_file_header_t;
|
||||
|
||||
/** \brief typedef of platform configuration stored in fs */
|
||||
typedef __PACKED_UNION _EPAT_atPortFrameFormat
|
||||
{
|
||||
uint32_t wholeValue;
|
||||
__PACKED_STRUCT _config
|
||||
{
|
||||
uint32_t dataBits : 3;
|
||||
uint32_t parity : 2;
|
||||
uint32_t stopBits : 2;
|
||||
uint32_t flowControl : 3;
|
||||
} config;
|
||||
} atPortFrameFormat_t;
|
||||
|
||||
|
||||
|
||||
// ulg port enum
|
||||
typedef enum
|
||||
{
|
||||
PLAT_CFG_ULG_PORT_USB=0,
|
||||
PLAT_CFG_ULG_PORT_UART,
|
||||
PLAT_CFG_ULG_PORT_MIX,
|
||||
PLAT_CFG_ULG_PORT_MAX
|
||||
} PlatCfgUlgPort_e;
|
||||
|
||||
|
||||
|
||||
/** \brief typedef of platform configuration stored in fs */
|
||||
typedef __PACKED_STRUCT _NVM_EPAT_plat_config
|
||||
{
|
||||
/** PM on/off flag
|
||||
* valid value:
|
||||
* 0x504D5544 -- PM is disabled, "PMUD"
|
||||
* 0x504D5545 -- PM is enabled, "PMUE"
|
||||
*/
|
||||
uint32_t enablePM;
|
||||
|
||||
/** sleep mode
|
||||
* valid value:
|
||||
* 0 -- dummy
|
||||
* 1 -- dummy
|
||||
*/
|
||||
uint8_t sleepMode;
|
||||
|
||||
/** wait n ms before sleep, when wakeup from pad
|
||||
* valid value:
|
||||
* 0 -- do not wait
|
||||
* x -- wait x ms
|
||||
*/
|
||||
uint32_t slpWaitTime;
|
||||
|
||||
/** AT baudrate,for AP only
|
||||
* should be equal to 'atPortBaudRate' in struct plat_config_raw_flash_t
|
||||
*/
|
||||
uint32_t atPortBaudRate;
|
||||
|
||||
/** AT port frame format*/
|
||||
atPortFrameFormat_t atPortFrameFormat;
|
||||
|
||||
/** ECQSCLK config
|
||||
* valid value:
|
||||
* 0 -- ECQSCLK set to 0
|
||||
* 1 -- ECQSCLK set to 1
|
||||
*/
|
||||
uint8_t ecSclkCfg;
|
||||
} plat_config_fs_t;
|
||||
|
||||
|
||||
/** \brief typedef of platform configuration stored in raw flash --old v0*/
|
||||
__PACKED_STRUCT _plat_config_raw_flash_v0
|
||||
{
|
||||
/** action to perform when assert or hard fault occurs
|
||||
* valid value:
|
||||
* 0 -- dump full exception info to flash and EPAT tool then trapped in endless loop(while(1))
|
||||
* 1 -- print necessary exception info then reset
|
||||
* 2 -- dump full exception info to flash then reset
|
||||
* 3 -- dump full exception info to flash and EPAT tool then reset
|
||||
* 4 -- reset directly
|
||||
* 10 -- enable uart help dump and dump full exception info to flash and EPAT tool then trapped in endless loop(while(1))
|
||||
* 13 -- enable uart help dump and dump full exception info to flash and EPAT tool, and then reset
|
||||
*/
|
||||
uint8_t faultAction;
|
||||
|
||||
/** port select for dump info output when exception occurs
|
||||
* valid value:
|
||||
* 0,1,2,3,(4) -- specify which port
|
||||
* 0xff -- disable this function
|
||||
*/
|
||||
uint8_t uartDumpPort;
|
||||
|
||||
/** WDT start/stop control
|
||||
* valid value:
|
||||
* 0 -- stop WDT
|
||||
* 1 -- start WDT
|
||||
*/
|
||||
uint8_t startWDT;
|
||||
|
||||
/** unilog on/off flag
|
||||
* valid value:
|
||||
* 0 -- unilog is disabled
|
||||
* 1 -- only sw log is enabled
|
||||
* 2 -- All log is enabled
|
||||
*/
|
||||
uint8_t logControl;
|
||||
|
||||
/** uart baudrate for unilog output */
|
||||
uint32_t uartBaudRate;
|
||||
|
||||
/** debug trace log level setting, refer to 'DebugTraceLevelType_e' */
|
||||
uint32_t logLevel;
|
||||
|
||||
/** unilog output port select
|
||||
* valid value:
|
||||
* 0 -- USB
|
||||
* 1 -- UART
|
||||
* 2 -- MIX(for future use UART/USB dynamic select)
|
||||
**/
|
||||
PlatCfgUlgPort_e logPortSel;
|
||||
|
||||
/** RNDIS enum control
|
||||
* valid value:
|
||||
* 0 -- enable USB init and enum RNDIS
|
||||
* 1 -- enable USB init but not enum RNDIS
|
||||
* 2 -- disable USB init
|
||||
*/
|
||||
uint8_t usbCtrl;
|
||||
|
||||
/** usb software trace control
|
||||
* valid value:
|
||||
* 0 -- disable all usb software trace
|
||||
* 1 -- enable all usb software trace
|
||||
* others -- misc usb software trace
|
||||
*/
|
||||
uint8_t usbSwTrace;
|
||||
|
||||
|
||||
|
||||
/** USB sleep mask
|
||||
* valid value:
|
||||
* 0 -- usb should vote to enter sleep
|
||||
* 1 -- do not consider usb vote before sleep
|
||||
*/
|
||||
uint8_t usbSlpMask;
|
||||
|
||||
/** USB sleep thd
|
||||
* valid value:
|
||||
* set the minimal time to sleep, when usbSlpMask=1
|
||||
*/
|
||||
uint16_t usbSlpThd;
|
||||
|
||||
/** pwrkey mode
|
||||
* valid value:
|
||||
* 1 power key mode
|
||||
* 0 normal key mode
|
||||
*/
|
||||
uint8_t pwrKeyMode;
|
||||
};
|
||||
|
||||
// fota urc port type
|
||||
typedef enum
|
||||
{
|
||||
PLAT_CFG_FOTA_URC_PORT_USB=0,
|
||||
PLAT_CFG_FOTA_URC_PORT_UART,
|
||||
PLAT_CFG_FOTA_URC_PORT_MAXTYPE
|
||||
} PlatCfgFotaUrcPortType_e;
|
||||
|
||||
#define PLAT_CFG_FOTA_URC_USB_PORT_IDX_MIN 0
|
||||
#define PLAT_CFG_FOTA_URC_USB_PORT_IDX_MAX 2
|
||||
|
||||
#define PLAT_CFG_FOTA_URC_UART_PORT_IDX_MIN 0
|
||||
#define PLAT_CFG_FOTA_URC_UART_PORT_IDX_MAX 1
|
||||
|
||||
|
||||
#define PLAT_CFG_RAW_FLASH_RSVD_SIZE 21
|
||||
|
||||
/** \brief typedef of platform configuration stored in raw flash */
|
||||
__PACKED_STRUCT _plat_config_raw_flash
|
||||
{
|
||||
/** action to perform when assert or hard fault occurs
|
||||
* valid value:
|
||||
* 0 -- dump full exception info to flash and EPAT tool then trapped in endless loop(while(1))
|
||||
* 1 -- print necessary exception info then reset
|
||||
* 2 -- dump full exception info to flash then reset
|
||||
* 3 -- dump full exception info to flash and EPAT tool then reset
|
||||
* 4 -- reset directly
|
||||
* 10 -- enable uart help dump and dump full exception info to flash and EPAT tool then trapped in endless loop(while(1))
|
||||
* 13 -- enable uart help dump and dump full exception info to flash and EPAT tool, and then reset
|
||||
*/
|
||||
uint8_t faultAction;
|
||||
|
||||
/** port select for dump info output when exception occurs
|
||||
* valid value:
|
||||
* 0,1,2,3,(4) -- specify which port
|
||||
* 0xff -- disable this function
|
||||
*/
|
||||
uint8_t uartDumpPort;
|
||||
|
||||
|
||||
/** WDT start/stop control
|
||||
* valid value:
|
||||
* 0 -- stop WDT
|
||||
* 1 -- start WDT
|
||||
*/
|
||||
uint8_t startWDT;
|
||||
|
||||
/** unilog on/off flag
|
||||
* valid value:
|
||||
* 0 -- unilog is disabled
|
||||
* 1 -- only sw log is enabled
|
||||
* 2 -- All log is enabled
|
||||
*/
|
||||
uint8_t logControl;
|
||||
|
||||
/** uart baudrate for unilog output */
|
||||
uint32_t uartBaudRate;
|
||||
|
||||
/** debug trace log level setting, refer to 'DebugTraceLevelType_e' */
|
||||
uint32_t logLevel;
|
||||
|
||||
/** unilog output port select
|
||||
* valid value:
|
||||
* 0 -- USB
|
||||
* 1 -- UART
|
||||
* 2 -- MIX(for future use UART/USB dynamic select)
|
||||
**/
|
||||
PlatCfgUlgPort_e logPortSel;
|
||||
|
||||
/** RNDIS enum control
|
||||
* valid value:
|
||||
* 0 -- enable USB init and enum RNDIS
|
||||
* 1 -- enable USB init but not enum RNDIS
|
||||
* 2 -- disable USB init
|
||||
*/
|
||||
uint8_t usbCtrl;
|
||||
|
||||
/** usb software trace control
|
||||
* valid value:
|
||||
* 0 -- disable all usb software trace
|
||||
* 1 -- enable all usb software trace
|
||||
* others -- misc usb software trace
|
||||
*/
|
||||
uint8_t usbSwTrace;
|
||||
|
||||
|
||||
|
||||
/** USB sleep mask
|
||||
* valid value:
|
||||
* 0 -- usb should vote to enter sleep
|
||||
* 1 -- do not consider usb vote before sleep
|
||||
*/
|
||||
uint8_t usbSlpMask;
|
||||
|
||||
/** USB sleep thd
|
||||
* valid value:
|
||||
* set the minimal time to sleep, when usbSlpMask=1
|
||||
*/
|
||||
uint16_t usbSlpThd;
|
||||
|
||||
/** pwrkey mode
|
||||
* valid value:
|
||||
* 1 power key mode
|
||||
* 0 normal key mode
|
||||
*/
|
||||
uint8_t pwrKeyMode;
|
||||
|
||||
/** USB VBUS MODE Enable,Disable Flag
|
||||
* valid value:
|
||||
* 0 -- usb vbus mode disable
|
||||
* 1 -- usb vbus mode enable
|
||||
*/
|
||||
uint8_t usbVBUSModeEn;
|
||||
|
||||
/** USB VBUS MODE Wakup Pad Index
|
||||
* valid value:
|
||||
* 0,1,2,3,4,5 PAD IDX FOR USB VBUS WKUP PAD
|
||||
*/
|
||||
uint8_t usbVBUSWkupPad;
|
||||
|
||||
/** USB NET IF SEL
|
||||
* valid value:
|
||||
* 0----RNDIS,default
|
||||
* 1----ECM
|
||||
*/
|
||||
uint8_t usbNet;
|
||||
|
||||
/** USB VCOM EN bitmap
|
||||
* valid value:
|
||||
* bit0---vcom0
|
||||
* bit1---vcom1
|
||||
* ----
|
||||
* ----
|
||||
*/
|
||||
uint8_t usbVcomEnBitMap;
|
||||
|
||||
/** AT/fotaURC baudrate, for AP & BL*/
|
||||
uint32_t atPortBaudRate;
|
||||
|
||||
/** FOTA URC output port select
|
||||
* valid value(Bit4-7):
|
||||
* 0 -- USB
|
||||
* 1 -- UART
|
||||
**
|
||||
* valid value(Bit0-3):
|
||||
* 0-2 -- USB
|
||||
* 0-1 -- UART
|
||||
**/
|
||||
uint8_t fotaUrcPortSel;
|
||||
|
||||
/** pmuInCdrx
|
||||
* valid value:
|
||||
* 0----
|
||||
* 1----
|
||||
*/
|
||||
uint8_t pmuInCdrx;
|
||||
|
||||
/** slpLimitEn
|
||||
* valid value:
|
||||
* 0---- disable
|
||||
* 1---- enable
|
||||
*/
|
||||
uint8_t slpLimitEn;
|
||||
|
||||
/** slpLimitTime
|
||||
* valid value:
|
||||
* 0---0xFFFFFFFF
|
||||
*/
|
||||
uint32_t slpLimitTime;
|
||||
|
||||
/* 'PLAT_CFG_RAW_FLASH_RSVD_SIZE' bytes rsvd for future */
|
||||
uint8_t resv[PLAT_CFG_RAW_FLASH_RSVD_SIZE];
|
||||
};
|
||||
|
||||
typedef struct _plat_config_raw_flash plat_config_raw_flash_t;//current
|
||||
typedef struct _plat_config_raw_flash_v0 plat_config_raw_flash_v0_t;//old v0
|
||||
|
||||
/** \brief typedef of platform info layout stored in raw flash */
|
||||
__PACKED_STRUCT _plat_info_layout
|
||||
{
|
||||
config_file_header_t header; /**< raw flash plat config header */
|
||||
plat_config_raw_flash_t config; /**< raw flash plat config body */
|
||||
uint32_t fsAssertCount; /**< count for monitoring FS assert, when it reaches specific number, FS region will be re-formated */
|
||||
};
|
||||
typedef struct _plat_info_layout plat_info_layout_t;
|
||||
|
||||
/** @brief List of platform configuration items used to set/get sepecific setting */
|
||||
typedef enum _plat_config_id
|
||||
{
|
||||
PLAT_CONFIG_ITEM_FAULT_ACTION = 0, /**< faultAction item */
|
||||
PLAT_CONFIG_ITEM_UART_DUMP_PORT, /**< uartDumpPort item */
|
||||
PLAT_CONFIG_ITEM_START_WDT, /**< startWDT item */
|
||||
PLAT_CONFIG_ITEM_LOG_CONTROL, /**< logControl item */
|
||||
PLAT_CONFIG_ITEM_LOG_BAUDRATE, /**< uart baudrate for log output */
|
||||
PLAT_CONFIG_ITEM_LOG_LEVEL, /**< logLevel item */
|
||||
PLAT_CONFIG_ITEM_ENABLE_PM, /**< enablePM item */
|
||||
PLAT_CONFIG_ITEM_SLEEP_MODE, /**< sleepMode item */
|
||||
PLAT_CONFIG_ITEM_WAIT_SLEEP, /**< wait ms before sleep */
|
||||
PLAT_CONFIG_ITEM_AT_PORT_BAUDRATE, /**< AT port baudrate */
|
||||
PLAT_CONFIG_ITEM_AT_PORT_FRAME_FORMAT, /**< AT port frame format */
|
||||
PLAT_CONFIG_ITEM_ECSCLK_CFG, /**< ECSCLK config */
|
||||
PLAT_CONFIG_ITEM_LOG_PORT_SEL, /**< ULG output port select */
|
||||
PLAT_CONFIG_ITEM_USB_CTRL, /**< USB control */
|
||||
PLAT_CONFIG_ITEM_USB_SW_TRACE_FLAG, /**< USB control */
|
||||
PLAT_CONFIG_ITEM_USB_SLEEP_MASK, /**< USB Sleep Vote Mask */
|
||||
PLAT_CONFIG_ITEM_USB_SLEEP_THD, /**< USB Sleep Thread */
|
||||
PLAT_CONFIG_ITEM_PWRKEY_MODE, /**< PWRKEY Mode */
|
||||
PLAT_CONFIG_ITEM_USB_VBUS_MODE_EN, /**< USB VBUS MODE ENABLE, DISABLE*/
|
||||
PLAT_CONFIG_ITEM_USB_VBUS_WKUP_PAD, /**< USB VBUS MODE WKUP PAD INDEX*/
|
||||
PLAT_CONFIG_ITEM_USB_NET, /**< USB NET Select*/
|
||||
PLAT_CONFIG_ITEM_USB_VCOM_EN_BMP, /**< USB VCOM Enabled Bitmap*/
|
||||
PLAT_CONFIG_ITEM_FOTA_URC_PORT_SEL, /**< FOTA URC Port Select*/
|
||||
PLAT_CONFIG_ITEM_PMUINCDRX, /**< PMUINCDRX Select*/
|
||||
PLAT_CONFIG_ITEM_SLP_LIMIT_EN, /**< enable sleep time limit*/
|
||||
PLAT_CONFIG_ITEM_SLP_LIMIT_TIME, /**< set maximum sleep time in mili second*/
|
||||
PLAT_CONFIG_ITEM_TOTAL_NUMBER /**< total number of items */
|
||||
} plat_config_id_t;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\fn void BSP_SavePlatConfigToFs(void)
|
||||
\brief Save platform configuration into FS
|
||||
\return void
|
||||
*/
|
||||
void BSP_SavePlatConfigToFs(void);
|
||||
|
||||
/**
|
||||
\fn void BSP_LoadPlatConfigFromFs(void)
|
||||
\brief Load platform configuration from FS
|
||||
\return void
|
||||
*/
|
||||
void BSP_LoadPlatConfigFromFs(void);
|
||||
|
||||
/**
|
||||
\fn plat_config_fs_t* BSP_GetFsPlatConfig(void)
|
||||
\brief Get FS platform configuration variable pointer
|
||||
\return pointer to internal platform configuration loaded from FS
|
||||
*/
|
||||
plat_config_fs_t* BSP_GetFsPlatConfig(void);
|
||||
|
||||
/**
|
||||
\fn void BSP_SavePlatConfigToRawFlash(void)
|
||||
\brief Save platform configuration into raw flash
|
||||
\return void
|
||||
*/
|
||||
void BSP_SavePlatConfigToRawFlash(void);
|
||||
|
||||
/**
|
||||
\fn void BSP_LoadPlatConfigFromRawFlash(void)
|
||||
\brief Load platform configuration from raw flash
|
||||
\return void
|
||||
*/
|
||||
void BSP_LoadPlatConfigFromRawFlash(void);
|
||||
|
||||
/**
|
||||
\fn plat_config_raw_flash_t* BSP_GetRawFlashPlatConfig(void)
|
||||
\brief Get raw flash platform configuration variable pointer
|
||||
\return pointer to internal platform configuration loaded from raw flash
|
||||
*/
|
||||
plat_config_raw_flash_t* BSP_GetRawFlashPlatConfig(void);
|
||||
|
||||
/**
|
||||
\fn uint32_t BSP_GetPlatConfigItemValue(plat_config_id_t id)
|
||||
\brief Get value of specific platform configuration item
|
||||
\param[in] id id of platform configuration item, \ref plat_config_id_t
|
||||
\return value of current configuration item
|
||||
*/
|
||||
uint32_t BSP_GetPlatConfigItemValue(plat_config_id_t id);
|
||||
|
||||
/**
|
||||
\fn void BSP_SetPlatConfigItemValue(plat_config_id_t id, uint32_t value)
|
||||
\brief Set value of specific platform configuration item
|
||||
\param[in] id id of platform configuration item, \ref plat_config_id_t
|
||||
\param[in] value value of configuration item to set
|
||||
\return void
|
||||
*/
|
||||
void BSP_SetPlatConfigItemValue(plat_config_id_t id, uint32_t value);
|
||||
|
||||
/**
|
||||
\fn uint32_t BSP_GetFSAssertCount(void)
|
||||
\brief Fetch current 'fsAssertCount' value from PLAT_INFO region
|
||||
\return current fsAssertCount value
|
||||
*/
|
||||
uint32_t BSP_GetFSAssertCount(void);
|
||||
|
||||
/**
|
||||
\fn void BSP_SetFSAssertCount(uint32_t value);
|
||||
\brief Update 'fsAssertCount' value
|
||||
\param[in] value new value assigned to 'fsAssertCount'
|
||||
\return void
|
||||
\note Internal use only on FS assert occurs
|
||||
*/
|
||||
void BSP_SetFSAssertCount(uint32_t value);
|
||||
|
||||
/**
|
||||
\fn void BSP_SetFsPorDefaultValue(void);
|
||||
\brief when por happened some data may retore to it's default
|
||||
\return void
|
||||
*/
|
||||
void BSP_SetFsPorDefaultValue(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PLAT_CONFIG_H */
|
||||
@@ -0,0 +1,172 @@
|
||||
#include "codecDrv.h"
|
||||
|
||||
void delay_us(uint32_t us);
|
||||
|
||||
extern ARM_DRIVER_I2C Driver_I2C0;
|
||||
static ARM_DRIVER_I2C *i2cDrvInstance = &CREATE_SYMBOL(Driver_I2C, 0);
|
||||
|
||||
void codecI2cInit()
|
||||
{
|
||||
i2cDrvInstance->Initialize(NULL);
|
||||
i2cDrvInstance->PowerControl(ARM_POWER_FULL);
|
||||
i2cDrvInstance->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_STANDARD);
|
||||
i2cDrvInstance->Control(ARM_I2C_BUS_CLEAR, 0);
|
||||
}
|
||||
|
||||
void codecI2cWrite(char* codecName, uint8_t slaveAddr, i2sI2cCfg_t* i2cCfg)
|
||||
{
|
||||
uint8_t cmd[2] = {0, 0};
|
||||
uint8_t regAddr = i2cCfg->regAddr;
|
||||
uint16_t regData = i2cCfg->regVal;
|
||||
|
||||
if (strcmp(codecName, "es8388") == 0)
|
||||
{
|
||||
cmd[0] = regAddr;
|
||||
cmd[1] = regData & 0xff;
|
||||
|
||||
}
|
||||
else if (strcmp(codecName, "NAU88C22") == 0)
|
||||
{
|
||||
cmd[0] = (regAddr << 1) | ((regData & 0x100) >> 8);
|
||||
cmd[1] = regData & 0xff;
|
||||
}
|
||||
else if(strcmp(codecName, "es8311") == 0)
|
||||
{
|
||||
cmd[0] = regAddr;
|
||||
cmd[1] = regData & 0xff;
|
||||
}
|
||||
|
||||
i2cDrvInstance->MasterTransmit(slaveAddr, cmd, 2, false);
|
||||
//delay_us(30 * 1000); // need to add delay in app layer which call it
|
||||
}
|
||||
|
||||
uint8_t codecI2cRead(uint8_t slaveAddr, uint8_t regAddr)
|
||||
{
|
||||
uint8_t a;
|
||||
a = regAddr;
|
||||
uint8_t readData;
|
||||
i2cDrvInstance->MasterTransmit(slaveAddr, (uint8_t *)&a, 1, true);
|
||||
i2cDrvInstance->MasterReceive(slaveAddr, &readData, 1, false);
|
||||
return readData;
|
||||
}
|
||||
|
||||
uint16_t es8388GetFs(void);
|
||||
uint16_t es8311GetFs(void);
|
||||
|
||||
uint16_t codecGetFs(codecType_e codecType)
|
||||
{
|
||||
switch (codecType)
|
||||
{
|
||||
case ES8388:
|
||||
return es8388GetFs();
|
||||
|
||||
case NAU88C22:
|
||||
return 1;
|
||||
|
||||
case ES7148:
|
||||
return 1;
|
||||
|
||||
case ES7149:
|
||||
return 1;
|
||||
|
||||
case ES8311:
|
||||
return es8311GetFs();
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
\fn void codecCtrlVolume(uint8_t raise, uint8_t step)
|
||||
\brief Raise or decrease volume.
|
||||
\param[in] codecType codec type.
|
||||
\param[in] raise true means raise volume; false means decrease volume.
|
||||
\param[in] step Raise or decrease vlume'samplitude everytime.
|
||||
\return none.
|
||||
*/
|
||||
void codecCtrlVolume(codecType_e codecType, bool raise, uint8_t step)
|
||||
{
|
||||
i2sI2cCfg_t i2cCfg = {0,0,0};
|
||||
|
||||
switch (codecType)
|
||||
{
|
||||
case ES8388:
|
||||
{
|
||||
i2cCfg.regAddr = 0x1b;
|
||||
raise? (i2cCfg.regVal += step) : (i2cCfg.regVal -= step);
|
||||
i2cCfg.delayMs = 1;
|
||||
|
||||
codecI2cWrite("es8388", ES8388_IICADDR, (i2sI2cCfg_t*)&i2cCfg); // register27. Digital part
|
||||
codecI2cWrite("es8388", ES8388_IICADDR, (i2sI2cCfg_t*)&i2cCfg); // register49. Analog part
|
||||
return;
|
||||
}
|
||||
|
||||
case NAU88C22:
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void codecWriteVal(codecType_e codecType, uint8_t regAddr, uint16_t regVal)
|
||||
{
|
||||
i2sI2cCfg_t i2cCfg;
|
||||
|
||||
i2cCfg.regAddr = regAddr;
|
||||
i2cCfg.regVal = regVal;
|
||||
|
||||
switch (codecType)
|
||||
{
|
||||
case ES8388:
|
||||
{
|
||||
codecI2cWrite("es8388", ES8388_IICADDR, (i2sI2cCfg_t*)&i2cCfg);
|
||||
return;
|
||||
}
|
||||
|
||||
case NAU88C22:
|
||||
{
|
||||
codecI2cWrite("NAU88C22", NAU88C22_IICADDR, (i2sI2cCfg_t*)&i2cCfg);
|
||||
return;
|
||||
}
|
||||
case ES7148:
|
||||
{
|
||||
return;
|
||||
}
|
||||
case ES7149:
|
||||
{
|
||||
return;
|
||||
}
|
||||
case ES8311:
|
||||
{
|
||||
codecI2cWrite("es8311", ES8311_IICADDR, (i2sI2cCfg_t*)&i2cCfg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t codecReadVal(codecType_e codecType, uint8_t regAddr)
|
||||
{
|
||||
uint8_t dataRead = 0x55;
|
||||
switch (codecType)
|
||||
{
|
||||
case ES8388:
|
||||
{
|
||||
dataRead = codecI2cRead(ES8388_IICADDR, regAddr);
|
||||
break;
|
||||
}
|
||||
case ES8311:
|
||||
{
|
||||
dataRead = codecI2cRead(ES8311_IICADDR, regAddr);
|
||||
break;
|
||||
}
|
||||
case ES7148:
|
||||
case ES7149:
|
||||
case NAU88C22:
|
||||
break;
|
||||
}
|
||||
|
||||
return dataRead;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
#include "i2s.h"
|
||||
|
||||
#define ES8311_FS_NUM 256
|
||||
|
||||
|
||||
i2sI2cCfg_t es8311_regInfo[] =
|
||||
{
|
||||
|
||||
{0x45,0x00},
|
||||
{0x01,0x30},
|
||||
{0x02,0x10},
|
||||
|
||||
|
||||
//Ratio=MCLK/LRCK=256:12M288-48K;4M096-16K; 2M048-8K
|
||||
{0x02,0x00},//MCLK DIV=1
|
||||
{0x03,0x10},
|
||||
{0x16,0x24},
|
||||
{0x04,0x20},
|
||||
{0x05,0x00},
|
||||
{0x06,(0<<5) + 4 -1},//(0x06,(SCLK_INV<<5) + SCLK_DIV -1);
|
||||
{0x07,0x00},
|
||||
{0x08,0xFF},
|
||||
|
||||
|
||||
{0x09,(0<<7) + 0x00 + (0x00<<2)},//(0x09,(DACChannelSel<<7) + Format + (Format_Len<<2));
|
||||
{0x0A,0x00 + (0x00<<2)},//(0x0A,Format + (Format_Len<<2));
|
||||
|
||||
|
||||
|
||||
{0x0B,0x00},
|
||||
{0x0C,0x00},
|
||||
|
||||
// {0x10,(0x1C*0) + (0x60*0x01) + 0x03}, //(0x10,(0x1C*DACHPModeOn) + (0x60*VDDA_VOLTAGE) + 0x03); //VDDA_VOLTAGE=1.8V close es8311MasterInit 3.3PWR setting
|
||||
{0x10,(0x1C*0) + (0x60*0x00) + 0x03}, //(0x10,(0x1C*DACHPModeOn) + (0x60*VDDA_VOLTAGE) + 0x03); //VDDA_VOLTAGE=3.3V open es8311MasterInit 3.3PWR setting
|
||||
|
||||
{0x11,0x7F},
|
||||
|
||||
{0x00,0x80 + (0<<6)},//Slave Mode (0x00,0x80 + (MSMode_MasterSelOn<<6));//Slave Mode
|
||||
|
||||
{0x0D,0x01},
|
||||
|
||||
{0x01,0x3F + (0x00<<7)},//(0x01,0x3F + (MCLK<<7));
|
||||
|
||||
{0x14,(0<<6) + (1<<4) + 0},//选择CH1输入+30DB GAIN (0x14,(Dmic_Selon<<6) + (ADCChannelSel<<4) + ADC_PGA_GAIN);
|
||||
|
||||
{0x12,0x28},
|
||||
{0x13,0x00 + (0<<4)}, //(0x13,0x00 + (DACHPModeOn<<4));
|
||||
|
||||
{0x0E,0x02},
|
||||
{0x0F,0x44},
|
||||
{0x15,0x00},
|
||||
{0x1B,0x0A},
|
||||
{0x1C,0x6A},
|
||||
{0x37,0x48},
|
||||
{0x44,(0 <<7)}, //(0x44,(ADC2DAC_Sel <<7));
|
||||
{0x17,210},//(0x17,ADC_Volume);
|
||||
{0x32,100},//(0x32,DAC_Volume);
|
||||
|
||||
|
||||
};
|
||||
|
||||
uint16_t es8311GetRegCnt(char* regName)
|
||||
{
|
||||
if (strcmp(regName, "es8311_master") == 0)
|
||||
{
|
||||
return (sizeof(es8311_regInfo) / sizeof(es8311_regInfo[0]));
|
||||
}
|
||||
else if (strcmp(regName, "es8311_slave") == 0)
|
||||
{
|
||||
return (sizeof(es8311_regInfo) / sizeof(es8311_regInfo[0]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void codecI2cInit(void);
|
||||
void codecI2cWrite(char* codecName, uint8_t slaveAddr, i2sI2cCfg_t* i2sI2cCfg);
|
||||
uint8_t codecI2cRead(uint8_t slaveAddr, uint8_t regAddr);
|
||||
|
||||
|
||||
|
||||
void es8311MasterInit()
|
||||
{
|
||||
uint8_t dataRead = 0xff;
|
||||
codecI2cInit();
|
||||
|
||||
for (int i = 0; i < es8311GetRegCnt("es8311_master"); i++)
|
||||
{
|
||||
codecI2cWrite("es8311", ES8311_IICADDR, (i2sI2cCfg_t*)&es8311_regInfo[i]);
|
||||
delay_us(10000);
|
||||
}
|
||||
|
||||
|
||||
#if 1
|
||||
for (int i = 0; i < es8311GetRegCnt("es8311_master"); i++)
|
||||
{
|
||||
dataRead = codecI2cRead(ES8311_IICADDR, es8311_regInfo[i].regAddr);
|
||||
printf("reg = 0x%02x, val = 0x%02x\n", es8311_regInfo[i].regAddr, dataRead);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void es8311SlaveInit()
|
||||
{
|
||||
// uint8_t dataRead = 0xff;
|
||||
es8311MasterInit();
|
||||
|
||||
i2sI2cCfg_t i2sI2cCfg;
|
||||
i2sI2cCfg.regAddr = 0x80;
|
||||
i2sI2cCfg.regVal = 0<<6; // Bit7 --> 1: master(default); 0: slave
|
||||
codecI2cWrite("es8311", ES8311_IICADDR, (i2sI2cCfg_t*)&i2sI2cCfg);
|
||||
|
||||
#if 0
|
||||
for (int i = 0; i < es8311GetRegCnt("es8311_slave"); i++)
|
||||
{
|
||||
dataRead = codecI2cRead(ES8311_IICADDR, es8311_regInfo[i].regAddr);
|
||||
printf("reg = 0x%02x, val = 0x%02x\n", es8311_regInfo[i].regAddr, dataRead);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uint16_t es8311GetFs()
|
||||
{
|
||||
|
||||
return ES8311_FS_NUM;
|
||||
}
|
||||
|
||||
void es8311SetMode(i2sMode_e mode)
|
||||
{
|
||||
uint8_t val = 0;
|
||||
switch(mode)
|
||||
{
|
||||
case MSB_MODE:
|
||||
val = 0x0F;
|
||||
break;
|
||||
|
||||
case I2S_MODE:
|
||||
val = 0x0C;
|
||||
|
||||
break;
|
||||
|
||||
case LSB_MODE:
|
||||
val = 0x0D;
|
||||
break;
|
||||
|
||||
case PCM_MODE:
|
||||
val = 0x2F;
|
||||
break;
|
||||
}
|
||||
codecWriteVal(CODEC_ES8311, 0x09, val);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
#include "i2s.h"
|
||||
|
||||
#define ES8388_FS_NUM 256
|
||||
|
||||
|
||||
i2sI2cCfg_t es8388_regInfo[] =
|
||||
{
|
||||
{0x00,0x80},
|
||||
{0x00,0x06},
|
||||
{0x02,0xf3},
|
||||
{0x35,0xa0},
|
||||
{0x36,0x08},
|
||||
|
||||
{0x08,0x84}, // Bit7: 1 means master(default); 0 means slave; 0x84: master 32bit; 0x86: master 16bit
|
||||
{0x0d,0x02}, // 256 ratio
|
||||
{0x18,0x02}, // 256 ratio
|
||||
|
||||
{0x07,0x7c},
|
||||
{0x2b,0x80},
|
||||
{0x2d,0x10},
|
||||
{0x00,0x30},
|
||||
{0x01,0x00},
|
||||
{0x03,0x00},
|
||||
{0x06,0xff},
|
||||
{0x09,0x88}, // Analog PGA: +24dB
|
||||
{0x0a,0xfc},
|
||||
{0x0b,0x02},
|
||||
{0x0c,0x0D}, // 0x0d: 16bit Left; 0x0c: 16bit I2S; 0x0e: 16bit Right; 0x0f: 16bit PCM;
|
||||
{0x10,0x00}, // digital gain ADCL
|
||||
{0x11,0x00}, // digital gain ADCR
|
||||
{0x12,0x05},
|
||||
{0x17,0x1B}, // 0x1b: 16bit Left; 0x19: 16bit I2S; 0x1d: 16bit Right; 0x1f: 16bit PCM;
|
||||
{0x19,0x76},
|
||||
{0x1a,0x45}, // digital gain DACL
|
||||
{0x1b,0x00}, // digital gain DACR
|
||||
{0x26,0x12},
|
||||
{0x2e,0x00},
|
||||
{0x2f,0x00},
|
||||
{0x30,0x00},
|
||||
{0x31,0x00},
|
||||
{0x02,0x00},
|
||||
{0x00,0x37},
|
||||
{0x01,0x20},
|
||||
{0x27,0xb8},
|
||||
{0x2a,0xb8},
|
||||
{0x04,0x3c},
|
||||
{0x00,0x36},
|
||||
{0x19,0x72},
|
||||
{0x2e,0x1e},
|
||||
{0x2f,0x1e},
|
||||
{0x30,0x1e},
|
||||
{0x31,0x1e},
|
||||
};
|
||||
|
||||
uint16_t es8388GetRegCnt(char* regName)
|
||||
{
|
||||
if (strcmp(regName, "es8388_master") == 0)
|
||||
{
|
||||
return (sizeof(es8388_regInfo) / sizeof(es8388_regInfo[0]));
|
||||
}
|
||||
else if (strcmp(regName, "es8388_slave") == 0)
|
||||
{
|
||||
return (sizeof(es8388_regInfo) / sizeof(es8388_regInfo[0]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void codecI2cInit(void);
|
||||
void codecI2cWrite(char* codecName, uint8_t slaveAddr, i2sI2cCfg_t* i2sI2cCfg);
|
||||
uint8_t codecI2cRead(uint8_t slaveAddr, uint8_t regAddr);
|
||||
|
||||
|
||||
|
||||
void es8388MasterInit()
|
||||
{
|
||||
//uint8_t dataRead = 0xff;
|
||||
|
||||
codecI2cInit();
|
||||
|
||||
for (int i = 0; i < es8388GetRegCnt("es8388_master"); i++)
|
||||
{
|
||||
codecI2cWrite("es8388", ES8388_IICADDR, (i2sI2cCfg_t*)&es8388_regInfo[i]);
|
||||
//delay_us(10000);
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (int i = 0; i < es8388GetRegCnt("es8388_master"); i++)
|
||||
{
|
||||
dataRead = codecI2cRead(ES8388_IICADDR, es8388_regInfo[i].regAddr);
|
||||
printf("reg = 0x%02x, val = 0x%02x\n", es8388_regInfo[i].regAddr, dataRead);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void es8388SlaveInit()
|
||||
{
|
||||
//uint8_t dataRead = 0xff;
|
||||
es8388MasterInit();
|
||||
|
||||
i2sI2cCfg_t i2sI2cCfg;
|
||||
i2sI2cCfg.regAddr = 0x08;
|
||||
i2sI2cCfg.regVal = 0<<7; // Bit7 --> 1: master(default); 0: slave
|
||||
codecI2cWrite("es8388", ES8388_IICADDR, (i2sI2cCfg_t*)&i2sI2cCfg);
|
||||
|
||||
#if 0
|
||||
for (int i = 0; i < es8388GetRegCnt("es8388_slave"); i++)
|
||||
{
|
||||
dataRead = codecI2cRead(ES8388_IICADDR, es8388_regInfo[i].regAddr);
|
||||
printf("reg = 0x%02x, val = 0x%02x\n", es8388_regInfo[i].regAddr, dataRead);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uint16_t es8388GetFs()
|
||||
{
|
||||
return ES8388_FS_NUM;
|
||||
}
|
||||
|
||||
void es8388SetMode(i2sMode_e mode)
|
||||
{
|
||||
uint8_t val = 0;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case MSB_MODE:
|
||||
val = 0x1b;
|
||||
break;
|
||||
|
||||
case I2S_MODE:
|
||||
val = 0x19;
|
||||
break;
|
||||
|
||||
case LSB_MODE:
|
||||
val = 0x1d;
|
||||
break;
|
||||
|
||||
case PCM_MODE:
|
||||
val = 0x1f;
|
||||
break;
|
||||
}
|
||||
|
||||
codecWriteVal(CODEC_ES8388, 0x17, val);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "i2s.h"
|
||||
|
||||
#define NAU88C22_FS_NUM 256
|
||||
|
||||
|
||||
i2sI2cCfg_t NAU88C22_slaveRegInfo[] =
|
||||
{
|
||||
{0x00,0x000},
|
||||
{0x01,0x1FD},
|
||||
{0x02,0x1BF},
|
||||
{0x03,0x1EF},
|
||||
//{0x04,0x008},
|
||||
{0x06,0x000},
|
||||
|
||||
{0x0A,0x008},
|
||||
//{0x0B,0x1FF},
|
||||
//{0x0C,0x1FF},
|
||||
|
||||
{0x2C,0x033},
|
||||
{0x2D,0x012},
|
||||
{0x2E,0x012},
|
||||
|
||||
{0x32,0x001},
|
||||
{0x33,0x001},
|
||||
{0x34,0x139},
|
||||
{0x35,0x139},
|
||||
|
||||
};
|
||||
|
||||
uint16_t NAU88C22GetRegCnt(char* regName)
|
||||
{
|
||||
if (strcmp(regName, "NAU88C22_slave") == 0)
|
||||
{
|
||||
return (sizeof(NAU88C22_slaveRegInfo) / sizeof(NAU88C22_slaveRegInfo[0]));
|
||||
}
|
||||
else if (strcmp(regName, "NAU88C22_master") == 0)
|
||||
{
|
||||
return (sizeof(NAU88C22_slaveRegInfo) / sizeof(NAU88C22_slaveRegInfo[0]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void codecI2cInit(void);
|
||||
void codecI2cWrite(char* codecName, uint8_t slaveAddr, i2sI2cCfg_t* i2sI2cCfg);
|
||||
uint8_t codecI2cRead(uint8_t slaveAddr, uint8_t regAddr);
|
||||
|
||||
|
||||
void nau88c22MasterInit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void nau88c22SlaveInit()
|
||||
{
|
||||
uint8_t dataRead = 0xff;
|
||||
|
||||
codecI2cInit();
|
||||
|
||||
for (int i = 0; i < NAU88C22GetRegCnt("NAU88C22_slave"); i++)
|
||||
{
|
||||
codecI2cWrite("NAU88C22", NAU88C22_IICADDR, (i2sI2cCfg_t*)&NAU88C22_slaveRegInfo[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NAU88C22GetRegCnt("NAU88C22_slave"); i++)
|
||||
{
|
||||
dataRead = codecI2cRead(NAU88C22_IICADDR, NAU88C22_slaveRegInfo[i].regAddr);
|
||||
printf("reg = 0x%02x, val = 0x%02x\n", NAU88C22_slaveRegInfo[i].regAddr, dataRead);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t NAU88C22GetFs()
|
||||
{
|
||||
return NAU88C22_FS_NUM;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2018 Copyrigths of AirM2M Ltd.
|
||||
* File name: bsp.c
|
||||
* Description:
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "Driver_Common.h"
|
||||
#include "clock.h"
|
||||
#include "bsp.h"
|
||||
#include "system_ec618.h"
|
||||
#include DEBUG_LOG_HEADER_FILE
|
||||
#include "ec_string.h"
|
||||
#include "mem_map.h"
|
||||
#if FEATURE_CCIO_ENABLE
|
||||
#include "uart_device.h"
|
||||
#endif
|
||||
#include "dbversion.h"
|
||||
#include "clock.h"
|
||||
#include "hal_adcproxy.h"
|
||||
#include "apmu_external.h"
|
||||
|
||||
extern ARM_DRIVER_USART Driver_USART0;
|
||||
extern ARM_DRIVER_USART Driver_USART1;
|
||||
|
||||
ARM_DRIVER_USART *UsartPrintHandle = NULL;
|
||||
ARM_DRIVER_USART *UsartUnilogHandle = NULL;
|
||||
ARM_DRIVER_USART *UsartAtCmdHandle = NULL;
|
||||
|
||||
static uint8_t OSState = 0; // OSState = 0 os not start, OSState = 1 os started
|
||||
extern void trimAdcSetGolbalVar(void);
|
||||
|
||||
void BSP_InitUartDriver(ARM_DRIVER_USART *drvHandler,
|
||||
ARM_POWER_STATE powerMode,
|
||||
uint32_t settings,
|
||||
uint32_t baudRate,
|
||||
ARM_USART_SignalEvent_t cb_event)
|
||||
{
|
||||
if(drvHandler)
|
||||
{
|
||||
drvHandler->Initialize(cb_event);
|
||||
drvHandler->PowerControl(powerMode);
|
||||
drvHandler->Control(settings, baudRate);
|
||||
}
|
||||
}
|
||||
|
||||
void BSP_DeinitUartDriver(ARM_DRIVER_USART *drvHandler)
|
||||
{
|
||||
if(drvHandler)
|
||||
{
|
||||
drvHandler->PowerControl(ARM_POWER_OFF);
|
||||
drvHandler->Uninitialize();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined ( __GNUC__ )
|
||||
|
||||
/*
|
||||
* retarget for _write implementation
|
||||
* Parameter: ch: character will be out
|
||||
*/
|
||||
int io_putchar(int ch)
|
||||
{
|
||||
if (UsartPrintHandle != NULL)
|
||||
UsartPrintHandle->SendPolling((uint8_t*)&ch, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* retarget for _read implementation
|
||||
* Parameter: ch: character will be read
|
||||
*/
|
||||
int io_getchar()
|
||||
{
|
||||
uint8_t ch = 0;
|
||||
if (UsartPrintHandle != NULL)
|
||||
UsartPrintHandle->Receive(&ch, 1);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
|
||||
int fgetc(FILE *f)
|
||||
{
|
||||
uint8_t ch = 0;
|
||||
if (UsartPrintHandle != NULL)
|
||||
UsartPrintHandle->Receive(&ch, 1);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
__attribute__((weak,noreturn))
|
||||
void __aeabi_assert (const char *expr, const char *file, int line) {
|
||||
printf("Assert, expr:%s, file: %s, line: %d\r\n", expr, file, line);
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
void __assert_func(const char *filename, int line, const char *assert_func, const char *expr)
|
||||
{
|
||||
for(uint8_t i = 0; i<5; i++)
|
||||
{
|
||||
uniLogFlushOut();
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, assert_func_1, P_ERROR, "Assert, expr:%s, file: %s, line: %d\r\n", expr, filename, line);
|
||||
}
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#elif defined (__CC_ARM)
|
||||
|
||||
/*
|
||||
* retarget for printf implementation
|
||||
* Parameter: ch: character will be out
|
||||
* f: not used
|
||||
*/
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
if (UsartPrintHandle != NULL)
|
||||
UsartPrintHandle->SendPolling((uint8_t*)&ch,1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* retarget for scanf implementation
|
||||
* Parameter: f: not used
|
||||
*/
|
||||
int fgetc(FILE *f)
|
||||
{
|
||||
uint8_t ch = 0;
|
||||
if (UsartPrintHandle != NULL)
|
||||
UsartPrintHandle->Receive(&ch,1);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
__attribute__((weak,noreturn))
|
||||
void __aeabi_assert (const char *expr, const char *file, int line) {
|
||||
printf("Assert, expr:%s, file: %s, line: %d\r\n", expr, file, line);
|
||||
while(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
uint32_t GET_PMU_RAWFLASH_OFFSET(void)
|
||||
{
|
||||
return FLASH_MEM_BACKUP_ADDR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setOSState(uint8_t state)
|
||||
{
|
||||
OSState = state;
|
||||
}
|
||||
|
||||
PLAT_PA_RAMCODE uint8_t getOSState(void) //1 os started. 0 no OS or OS not started yet
|
||||
{
|
||||
return OSState;
|
||||
}
|
||||
|
||||
|
||||
uint8_t* getBuildInfo(void)
|
||||
{
|
||||
return (uint8_t *)BSP_HEADER;
|
||||
}
|
||||
|
||||
uint8_t* getVersionInfo(void)
|
||||
{
|
||||
return (uint8_t *)VERSION_INFO;
|
||||
}
|
||||
|
||||
uint8_t* getATIVersionInfo(void)
|
||||
{
|
||||
return (uint8_t *)ATI_VERSION_INFO;
|
||||
}
|
||||
|
||||
//move here since this is an common and opensource place
|
||||
uint8_t* getDebugDVersion(void)
|
||||
{
|
||||
return (uint8_t*)DB_VERSION_UNIQ_ID;
|
||||
}
|
||||
|
||||
#ifdef UINILOG_FEATURE_ENABLE
|
||||
/**
|
||||
\fn void logToolCommandHandle(uint8_t *atcmd_buffer, uint32_t len)
|
||||
\brief handle downlink command sent from unilog tool EPAT
|
||||
if need to handle more command in future, add command-handler table
|
||||
\param[in] event UART event, note used in this function
|
||||
\param[in] cmd_buffer command received from UART
|
||||
\param[in] len command length
|
||||
\returns void
|
||||
*/
|
||||
void logToolCommandHandle(uint32_t event, uint8_t *cmd_buffer, uint32_t len)
|
||||
{
|
||||
(void)event;
|
||||
|
||||
uint8_t * LogDbVserion=getDebugDVersion();
|
||||
|
||||
if(ec_strnstr((const char *)cmd_buffer, "^logversion", len))
|
||||
{
|
||||
|
||||
ECPLAT_PRINTF(UNILOG_PLA_INTERNAL_CMD, get_log_version, P_SIG, "LOGVERSION:%s",LogDbVserion);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
ECPLAT_PRINTF(UNILOG_PLA_STRING, get_log_version_1, P_ERROR, "%s", "invalid command from EPAT");
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* unilog entity is removed for the reason of BSP small image.
|
||||
* for more implementation details, pls refer to
|
||||
* gCustSerlEntity[CUST_ENTITY_UNILOG] in ccio_provider.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* set unilog uart port
|
||||
* Parameter: port: for unilog
|
||||
* Parameter: baudrate: uart baudrate
|
||||
*/
|
||||
#ifdef __USER_CODE__
|
||||
void SetUnilogUartOrg(usart_port_t port, uint32_t baudrate, bool startRecv)
|
||||
#else
|
||||
void SetUnilogUart(usart_port_t port, uint32_t baudrate, bool startRecv)
|
||||
#endif
|
||||
{
|
||||
ARM_POWER_STATE powerMode = ARM_POWER_FULL;
|
||||
uint32_t ctrlSetting = ARM_USART_MODE_ASYNCHRONOUS | ARM_USART_DATA_BITS_8 | \
|
||||
ARM_USART_PARITY_NONE | ARM_USART_STOP_BITS_1 | \
|
||||
ARM_USART_FLOW_CONTROL_NONE;
|
||||
|
||||
if (port == PORT_USART_0)
|
||||
{
|
||||
#if (RTE_UART0)
|
||||
UsartUnilogHandle = &CREATE_SYMBOL(Driver_USART, 0);
|
||||
#endif
|
||||
}
|
||||
else if (port == PORT_USART_1)
|
||||
{
|
||||
#if (RTE_UART1)
|
||||
UsartUnilogHandle = &CREATE_SYMBOL(Driver_USART, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (UsartUnilogHandle == NULL) return;
|
||||
|
||||
#ifdef FEATURE_CCIO_ENABLE
|
||||
UartDevConf_t uartDevConf;
|
||||
UartHwConf_t *uartHwConf = &uartDevConf.hwConf;
|
||||
|
||||
memset(&uartDevConf, 0, sizeof(UartDevConf_t));
|
||||
|
||||
uartHwConf->powerMode = powerMode;
|
||||
uartHwConf->ctrlSetting = ctrlSetting;
|
||||
uartHwConf->baudRate = baudrate;
|
||||
|
||||
uartDevConf.drvHandler = UsartUnilogHandle;
|
||||
uartDevConf.mainUsage = CSIO_DT_DIAG;
|
||||
uartDevConf.speedType = CCIO_ST_HIGH;
|
||||
if(startRecv)
|
||||
{
|
||||
uartDevConf.bmCreateFlag = CCIO_TASK_FLAG_RX;
|
||||
}
|
||||
else
|
||||
{
|
||||
uartDevConf.bmCreateFlag = CCIO_TASK_FLAG_NONE;
|
||||
}
|
||||
|
||||
uartDevCreate(port, &uartDevConf);
|
||||
#else
|
||||
BSP_InitUartDriver(UsartUnilogHandle, powerMode, ctrlSetting, baudrate, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void FlushUnilogOutput(void)
|
||||
{
|
||||
uniLogFlushOut();
|
||||
|
||||
if(UsartUnilogHandle == NULL)
|
||||
return;
|
||||
UsartUnilogHandle->Control(ARM_USART_CONTROL_FLUSH_TX, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void BSP_CommonInit(void)
|
||||
{
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
PAD_driverInit();
|
||||
|
||||
GPR_initialize();
|
||||
|
||||
trimAdcSetGolbalVar();
|
||||
|
||||
apmuInit();
|
||||
|
||||
//interrupt config
|
||||
IC_PowupInit();
|
||||
|
||||
if(apmuGetAPBootFlag() == 0) // power on
|
||||
{
|
||||
apmuSetCPFastBoot(false); // set cp fast boot in case of cp dap wakeup
|
||||
}
|
||||
|
||||
cpADCInit(); // enable adc ref output, need stable time
|
||||
|
||||
BOOT_TIMESTAMP_SET(1, 3);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
#include "cameraDrv.h"
|
||||
|
||||
camI2cCfg_t bf30a2_1sdrRegInfo[] =
|
||||
{
|
||||
{0xf2,0x01},//soft reset
|
||||
{0xcf,0xb0},//power up
|
||||
{0x12,0x20},//MTK:20 ZX:10 RDA:40
|
||||
{0x15,0x80},
|
||||
{0x6b,0x71},
|
||||
{0x00,0x40},
|
||||
{0x04,0x00},
|
||||
{0x06,0x26},
|
||||
{0x08,0x07},
|
||||
{0x1c,0x12},
|
||||
{0x20,0x20},
|
||||
{0x21,0x20},
|
||||
{0x34,0x02},
|
||||
{0x35,0x02},
|
||||
{0x36,0x21},
|
||||
{0x37,0x13},
|
||||
{0xca,0x23},
|
||||
{0xcb,0x22},
|
||||
{0xcc,0x89},
|
||||
{0xcd,0x4c},
|
||||
{0xce,0x6b},
|
||||
{0xa0,0x8e},
|
||||
{0x01,0x1b},
|
||||
{0x02,0x1d},
|
||||
{0x13,0x08},
|
||||
{0x87,0x13},
|
||||
{0x8b,0x08},
|
||||
{0x70,0x1f},
|
||||
{0x71,0x40},
|
||||
{0x72,0x0a},
|
||||
{0x73,0x62},
|
||||
{0x74,0xa2},
|
||||
{0x75,0xbf},
|
||||
{0x76,0x02},
|
||||
{0x77,0xcc},
|
||||
{0x40,0x32},
|
||||
{0x41,0x28},
|
||||
{0x42,0x26},
|
||||
{0x43,0x1d},
|
||||
{0x44,0x1a},
|
||||
{0x45,0x14},
|
||||
{0x46,0x11},
|
||||
{0x47,0x0f},
|
||||
{0x48,0x0e},
|
||||
{0x49,0x0d},
|
||||
{0x4B,0x0c},
|
||||
{0x4C,0x0b},
|
||||
{0x4E,0x0a},
|
||||
{0x4F,0x09},
|
||||
{0x50,0x09},
|
||||
{0x24,0x50},
|
||||
{0x25,0x36},
|
||||
{0x80,0x00},
|
||||
{0x81,0x20},
|
||||
{0x82,0x40},
|
||||
{0x83,0x30},
|
||||
{0x84,0x50},
|
||||
{0x85,0x30},
|
||||
{0x86,0xD8},
|
||||
{0x89,0x45},
|
||||
{0x8a,0x33},
|
||||
{0x8f,0x81},
|
||||
{0x91,0xff},
|
||||
{0x92,0x08},
|
||||
{0x94,0x82},
|
||||
{0x95,0xfd},
|
||||
{0x9a,0x20},
|
||||
{0x9e,0xbc},
|
||||
{0xf0,0x8f},
|
||||
{0x51,0x06},
|
||||
{0x52,0x25},
|
||||
{0x53,0x2b},
|
||||
{0x54,0x0F},
|
||||
{0x57,0x2A},
|
||||
{0x58,0x22},
|
||||
{0x59,0x2c},
|
||||
{0x23,0x33},
|
||||
{0xa1,0x93},
|
||||
{0xa2,0x0f},
|
||||
{0xa3,0x2a},
|
||||
{0xa4,0x08},
|
||||
{0xa5,0x26},
|
||||
{0xa7,0x80},
|
||||
{0xa8,0x80},
|
||||
{0xa9,0x1e},
|
||||
{0xaa,0x19},
|
||||
{0xab,0x18},
|
||||
{0xae,0x50},
|
||||
{0xaf,0x04},
|
||||
{0xc8,0x10},
|
||||
{0xc9,0x15},
|
||||
{0xd3,0x0c},
|
||||
{0xd4,0x16},
|
||||
{0xee,0x06},
|
||||
{0xef,0x04},
|
||||
{0x55,0x34},
|
||||
{0x56,0x9c},
|
||||
{0xb1,0x98},
|
||||
{0xb2,0x98},
|
||||
{0xb3,0xc4},
|
||||
{0xb4,0x0C},
|
||||
{0xa0,0x8f},
|
||||
{0x13,0x07},
|
||||
};
|
||||
|
||||
uint16_t bf30a2GetRegCnt(char* regName)
|
||||
{
|
||||
if (strcmp(regName, "bf30a2_1sdr") == 0)
|
||||
{
|
||||
return (sizeof(bf30a2_1sdrRegInfo) / sizeof(bf30a2_1sdrRegInfo[0]));
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#include "cameraDrv.h"
|
||||
#include "quirc.h"
|
||||
|
||||
static volatile bool isTransferDone;
|
||||
extern void delay_us(uint32_t);
|
||||
struct quirc *qr;
|
||||
uint8_t* pic0Internal = NULL;
|
||||
|
||||
|
||||
static void camRecvCb(uint32_t event)
|
||||
{
|
||||
if(event & ARM_SPI_EVENT_TRANSFER_COMPLETE)
|
||||
{
|
||||
isTransferDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool decodeBegin(uint8_t* result)
|
||||
{
|
||||
int num_codes=0, w, h;
|
||||
struct quirc_code code;
|
||||
struct quirc_data data;
|
||||
quirc_decode_error_t err;
|
||||
|
||||
quirc_begin(qr, &w, &h);
|
||||
quirc_end(qr);
|
||||
num_codes = quirc_count(qr);
|
||||
|
||||
if (num_codes != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
quirc_extract(qr, 0, &code);
|
||||
/* Decoding stage */
|
||||
err = quirc_decode(&code, &data);
|
||||
if (err)
|
||||
{
|
||||
return false;
|
||||
//printf("D F2: %s\n", quirc_strerror(err));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(result, data.payload, data.payload_len);
|
||||
return true;
|
||||
//printf("Data: %s\n", data.payload);
|
||||
}
|
||||
}
|
||||
|
||||
void camPrepare(uint8_t* pic0)
|
||||
{
|
||||
pic0Internal = pic0;
|
||||
|
||||
// Camera register part
|
||||
camRegCfg(); // Only need to init once
|
||||
|
||||
// Quirc part
|
||||
qr = quirc_new();
|
||||
quirc_init(qr, pic0, 320, 240);
|
||||
}
|
||||
|
||||
bool camBegin(bool start, uint8_t* result)
|
||||
{
|
||||
uint32_t timeOut_ms = 5000;
|
||||
|
||||
if (start)
|
||||
{
|
||||
camInit(camRecvCb);
|
||||
|
||||
camStart(true);
|
||||
camRecv(pic0Internal);
|
||||
|
||||
do
|
||||
{
|
||||
delay_us(1000);
|
||||
}
|
||||
while((isTransferDone == false) && --timeOut_ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
camStart(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isTransferDone)
|
||||
{
|
||||
isTransferDone = false;
|
||||
|
||||
return decodeBegin(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error: camera doesn't take picture fail
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,403 @@
|
||||
#include "cameraDrv.h"
|
||||
|
||||
extern cspiDrvInterface_t cspiDrvInterface0;
|
||||
extern cspiDrvInterface_t cspiDrvInterface1;
|
||||
|
||||
extern camI2cCfg_t sp0A39Cfg[];
|
||||
extern camI2cCfg_t sp0821Cfg[];
|
||||
extern camI2cCfg_t gc6123Cfg[];
|
||||
extern camI2cCfg_t gc032ACfg[];
|
||||
extern camI2cCfg_t bf30a2Cfg[];
|
||||
extern cspiCtrl_t cspiCtrl;
|
||||
extern cspiIntCtrl_t cspiIntCtrl;
|
||||
extern cspiDataFmt_t cspiDataFmt;
|
||||
|
||||
extern ARM_DRIVER_I2C Driver_I2C0;
|
||||
static ARM_DRIVER_I2C *i2cDrvInstance = &CREATE_SYMBOL(Driver_I2C, 0);
|
||||
|
||||
#define EIGEN_CSPI(n) ((CSPI_TypeDef *) (MP_I2S0_BASE_ADDR + 0x1000*n))
|
||||
|
||||
|
||||
#if (CAMERA_ENABLE_SP0A39)
|
||||
#if (SP0A39_2SDR)
|
||||
char* regName = "sp0a39_2sdr";
|
||||
#elif (SP0A39_1SDR)
|
||||
char* regName = "sp0a39_1sdr";
|
||||
#endif
|
||||
|
||||
#elif (CAMERA_ENABLE_SP0821)
|
||||
#if (SP0821_2SDR)
|
||||
char* regName = "sp0821_2sdr";
|
||||
#elif (SP0821_1SDR)
|
||||
char* regName = "sp0821_1sdr";
|
||||
#endif
|
||||
|
||||
#elif (CAMERA_ENABLE_GC6123)
|
||||
#if (GC6123_2SDR)
|
||||
char* regName = "gc6123_2sdr";
|
||||
#elif (GC6123_1SDR)
|
||||
char* regName = "gc6123_1sdr";
|
||||
#endif
|
||||
|
||||
#elif (CAMERA_ENABLE_GC032A)
|
||||
#if (GC032A_2SDR)
|
||||
char* regName = "gc032a_2sdr";
|
||||
#elif (GC032A_1SDR)
|
||||
char* regName = "gc032a_1sdr";
|
||||
#endif
|
||||
#elif (CAMERA_ENABLE_BF30A2)
|
||||
#if (BF30A2_1SDR)
|
||||
char* regName = "bf30a2_1sdr";
|
||||
#endif
|
||||
#elif (CAMERA_ENABLE_GC6153)
|
||||
#if (GC6153_1SDR)
|
||||
char* regName = "gc6153_1sdr";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static uint8_t slaveAddr;
|
||||
static uint16_t regCnt;
|
||||
static camI2cCfg_t* regInfo = NULL;
|
||||
|
||||
#if (RTE_CSPI1 == 1)
|
||||
static cspiDrvInterface_t *cspiDrv = &CREATE_SYMBOL(cspiDrvInterface, 1);
|
||||
#else
|
||||
static cspiDrvInterface_t *cspiDrv = &CREATE_SYMBOL(cspiDrvInterface, 0);
|
||||
#endif
|
||||
extern void delay_us(uint32_t us);
|
||||
|
||||
void findRegInfo(char* regName, uint8_t* slaveAddr, uint16_t* regCnt, camI2cCfg_t** regInfo)
|
||||
{
|
||||
if (strcmp(regName, "sp0a39_2sdr") == 0)
|
||||
{
|
||||
extern camI2cCfg_t sp0A39_2sdrRegInfo[];
|
||||
*regInfo = sp0A39_2sdrRegInfo;
|
||||
*slaveAddr = SP0A39_I2C_ADDR;
|
||||
*regCnt = sp0a39GetRegCnt(regName);
|
||||
}
|
||||
else if (strcmp(regName, "sp0a39_1sdr") == 0)
|
||||
{
|
||||
extern camI2cCfg_t sp0A39_1sdrRegInfo[];
|
||||
*regInfo = sp0A39_1sdrRegInfo;
|
||||
*slaveAddr = SP0A39_I2C_ADDR;
|
||||
*regCnt = sp0a39GetRegCnt(regName);
|
||||
}
|
||||
else if (strcmp(regName, "sp0821_2sdr") == 0)
|
||||
{
|
||||
extern camI2cCfg_t sp0821_2sdrRegInfo[];
|
||||
*regInfo = sp0821_2sdrRegInfo;
|
||||
*slaveAddr = SP0821_I2C_ADDR;
|
||||
*regCnt = sp0821GetRegCnt(regName);
|
||||
}
|
||||
else if (strcmp(regName, "sp0821_1sdr") == 0)
|
||||
{
|
||||
extern camI2cCfg_t sp0821_1sdrRegInfo[];
|
||||
*regInfo = sp0821_1sdrRegInfo;
|
||||
*slaveAddr = SP0821_I2C_ADDR;
|
||||
*regCnt = sp0821GetRegCnt(regName);
|
||||
}
|
||||
else if (strcmp(regName, "gc6123_2sdr") == 0)
|
||||
{
|
||||
extern camI2cCfg_t gc6123_2sdrRegInfo[];
|
||||
*regInfo = gc6123_2sdrRegInfo;
|
||||
*slaveAddr = GC6123_I2C_ADDR;
|
||||
*regCnt = gc6123GetRegCnt(regName);
|
||||
}
|
||||
else if (strcmp(regName, "gc6123_1sdr") == 0)
|
||||
{
|
||||
extern camI2cCfg_t gc6123_1sdrRegInfo[];
|
||||
*regInfo = gc6123_1sdrRegInfo;
|
||||
*slaveAddr = GC6123_I2C_ADDR;
|
||||
*regCnt = gc6123GetRegCnt(regName);
|
||||
}
|
||||
else if (strcmp(regName, "gc032a_2sdr") == 0)
|
||||
{
|
||||
extern camI2cCfg_t gc032A_2sdrRegInfo[];
|
||||
*regInfo = gc032A_2sdrRegInfo;
|
||||
*slaveAddr = GC032A_I2C_ADDR;
|
||||
*regCnt = gc032aGetRegCnt(regName);
|
||||
}
|
||||
else if (strcmp(regName, "gc032a_1sdr") == 0)
|
||||
{
|
||||
extern camI2cCfg_t gc032A_1sdrRegInfo[];
|
||||
*regInfo = gc032A_1sdrRegInfo;
|
||||
*slaveAddr = GC032A_I2C_ADDR;
|
||||
*regCnt = gc032aGetRegCnt(regName);
|
||||
}
|
||||
else if (strcmp(regName, "bf30a2_1sdr") == 0)
|
||||
{
|
||||
extern camI2cCfg_t bf30a2_1sdrRegInfo[];
|
||||
*regInfo = bf30a2_1sdrRegInfo;
|
||||
*slaveAddr = BF30A2_I2C_ADDR;
|
||||
*regCnt = bf30a2GetRegCnt(regName);
|
||||
}
|
||||
else if (strcmp(regName, "gc6153_1sdr") == 0)
|
||||
{
|
||||
extern camI2cCfg_t gc6153_1sdrRegInfo[];
|
||||
*regInfo = gc6153_1sdrRegInfo;
|
||||
*slaveAddr = GC6153_I2C_ADDR;
|
||||
*regCnt = gc6153GetRegCnt(regName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void camI2cInit()
|
||||
{
|
||||
i2cDrvInstance->Initialize(NULL);
|
||||
i2cDrvInstance->PowerControl(ARM_POWER_FULL);
|
||||
i2cDrvInstance->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_STANDARD);
|
||||
i2cDrvInstance->Control(ARM_I2C_BUS_CLEAR, 0);
|
||||
|
||||
// Backup some info about this sensor
|
||||
findRegInfo(regName, &slaveAddr, ®Cnt, ®Info);
|
||||
}
|
||||
|
||||
void camI2cWrite(uint8_t slaveAddr, uint8_t regAddr, uint8_t regData, uint32_t num)
|
||||
{
|
||||
uint8_t tempBuffer[2];
|
||||
|
||||
tempBuffer[0] = regAddr;
|
||||
tempBuffer[1] = regData;
|
||||
i2cDrvInstance->MasterTransmit(slaveAddr, tempBuffer, num, false);
|
||||
}
|
||||
|
||||
uint8_t camI2cRead(uint8_t slaveAddr, uint8_t regAddr)
|
||||
{
|
||||
uint8_t a;
|
||||
a = regAddr;
|
||||
uint8_t readData;
|
||||
i2cDrvInstance->MasterTransmit(slaveAddr, (uint8_t *)&a, 1, true);
|
||||
i2cDrvInstance->MasterReceive(slaveAddr, &readData, 1, false);
|
||||
return readData;
|
||||
}
|
||||
|
||||
uint8_t camReadReg(uint8_t regAddr)
|
||||
{
|
||||
uint8_t recvData;
|
||||
|
||||
recvData = camI2cRead(slaveAddr, regAddr);
|
||||
return recvData;
|
||||
}
|
||||
|
||||
void camWriteReg(camI2cCfg_t* regInfo)
|
||||
{
|
||||
camI2cWrite(slaveAddr, regInfo->regAddr, regInfo->regVal, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void camRegCfg()
|
||||
{
|
||||
//uint8_t dataRead;
|
||||
|
||||
camI2cInit();
|
||||
|
||||
// Configure all the registers about this sensor
|
||||
for (int i=0; i < regCnt; i++)
|
||||
{
|
||||
camI2cWrite(slaveAddr, regInfo[i].regAddr, regInfo[i].regVal, 2);
|
||||
delay_us(10000); // delay 10ms
|
||||
|
||||
#if 0
|
||||
dataRead = camI2cRead(slaveAddr, regInfo[i].regAddr);
|
||||
printf("reg addr=0x%02x, reg val=0x%02x\n", regInfo[i].regAddr, dataRead);
|
||||
delay_us(15000);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void camInterfaceCfg(camParamCfg_t* config)
|
||||
{
|
||||
cspiDataFmt.endianMode = config->endianMode;
|
||||
cspiCtrl.rxWid = config->wireNum;
|
||||
cspiCtrl.rxdSeq = config->rxSeq;
|
||||
cspiCtrl.cpol = config->cpol;
|
||||
cspiCtrl.cpha = config->cpha;
|
||||
cspiCtrl.fillYonly = config->yOnly;
|
||||
cspiCtrl.rowScaleRatio = config->rowScaleRatio;
|
||||
cspiCtrl.colScaleRatio = config->colScaleRatio;
|
||||
cspiCtrl.scaleBytes = config->scaleBytes;
|
||||
}
|
||||
|
||||
void camSetMemAddr(uint32_t dataAddr)
|
||||
{
|
||||
cspiDrv->ctrl(CSPI_CTRL_MEM_ADDR , dataAddr); // register the recv memory
|
||||
}
|
||||
|
||||
void camInit(void* dataAddr, cspiCbEvent_fn cb)
|
||||
{
|
||||
camResolution_e camResolution;
|
||||
|
||||
#if 0 // if used in os environment, use this api to adjust voltage
|
||||
slpManNormalIOVoltSet(IOVOLT_3_00V);
|
||||
#else // used in environment without os
|
||||
// set all pin io to 2.7V since camera max voltage is 2.7V
|
||||
GPR_clockEnable(PCLK_PMDIG);
|
||||
*(uint32_t*)0x4d020018 = 1;
|
||||
*(uint32_t*)0x4d040308 = 7; // 1:2.7V 7:3V
|
||||
#endif
|
||||
|
||||
// Need to enable cspi first to make camera clock working
|
||||
camParamCfg_t camParamCfg;
|
||||
|
||||
#if (CAMERA_ENABLE_SP0A39)
|
||||
#if (SP0A39_2SDR)
|
||||
camParamCfg.wireNum = WIRE_2;
|
||||
#elif (SP0A39_1SDR)
|
||||
camParamCfg.wireNum = WIRE_1;
|
||||
#endif
|
||||
camParamCfg.endianMode = LSB_MODE;
|
||||
camParamCfg.rxSeq = SEQ_0;
|
||||
camParamCfg.cpha = 1;
|
||||
camParamCfg.cpol = 0;
|
||||
camResolution = CAM_CHAIN_COUNT;
|
||||
|
||||
#elif (CAMERA_ENABLE_SP0821)
|
||||
#if (SP0821_2SDR)
|
||||
camParamCfg.wireNum = WIRE_2;
|
||||
#elif (SP0821_1SDR)
|
||||
camParamCfg.wireNum = WIRE_1;
|
||||
#endif
|
||||
camParamCfg.endianMode = LSB_MODE;
|
||||
camParamCfg.rxSeq = SEQ_0;
|
||||
camParamCfg.cpha = 1;
|
||||
camParamCfg.cpol = 0;
|
||||
camResolution = CAM_CHAIN_COUNT;
|
||||
|
||||
#elif (CAMERA_ENABLE_GC6123)
|
||||
#if (GC6123_2SDR)
|
||||
camParamCfg.wireNum = WIRE_2;
|
||||
#elif (GC6123_1SDR)
|
||||
camParamCfg.wireNum = WIRE_1;
|
||||
#endif
|
||||
camParamCfg.endianMode = LSB_MODE;
|
||||
camParamCfg.rxSeq = SEQ_1;
|
||||
camParamCfg.cpha = 1;
|
||||
camParamCfg.cpol = 0;
|
||||
camParamCfg.yOnly = 1;
|
||||
camParamCfg.rowScaleRatio = 0;
|
||||
camParamCfg.colScaleRatio = 0;
|
||||
camParamCfg.scaleBytes = 0;
|
||||
camResolution = CAM_CHAIN_COUNT;
|
||||
|
||||
#elif (CAMERA_ENABLE_GC032A)
|
||||
#if (GC032A_2SDR)
|
||||
camParamCfg.wireNum = WIRE_2;
|
||||
#elif (GC032A_1SDR)
|
||||
camParamCfg.wireNum = WIRE_1;
|
||||
#endif
|
||||
camParamCfg.endianMode = LSB_MODE;
|
||||
camParamCfg.rxSeq = SEQ_0;
|
||||
camParamCfg.cpha = 0;
|
||||
camParamCfg.cpol = 0;
|
||||
camResolution = CAM_CHAIN_COUNT;
|
||||
if (camResolution == CAM_30W)
|
||||
{
|
||||
camParamCfg.yOnly = 0;
|
||||
camParamCfg.rowScaleRatio = 0;
|
||||
camParamCfg.colScaleRatio = 0;
|
||||
camParamCfg.scaleBytes = 0;
|
||||
}
|
||||
else // CAM_8W
|
||||
{
|
||||
camParamCfg.yOnly = 1;
|
||||
camParamCfg.rowScaleRatio = 1;
|
||||
camParamCfg.colScaleRatio = 1;
|
||||
camParamCfg.scaleBytes = 1;
|
||||
}
|
||||
|
||||
#elif (CAMERA_ENABLE_BF30A2)
|
||||
#if (BF30A2_1SDR)
|
||||
camParamCfg.wireNum = WIRE_1;
|
||||
#endif
|
||||
camParamCfg.endianMode = LSB_MODE;
|
||||
camParamCfg.rxSeq = SEQ_0;
|
||||
camParamCfg.cpha = 0;
|
||||
camParamCfg.cpol = 0;
|
||||
camParamCfg.yOnly = 1;
|
||||
camParamCfg.rowScaleRatio = 0;
|
||||
camParamCfg.colScaleRatio = 0;
|
||||
camParamCfg.scaleBytes = 0;
|
||||
camResolution = CAM_CHAIN_COUNT;
|
||||
#elif (CAMERA_ENABLE_GC6153)
|
||||
#if (GC6153_1SDR)
|
||||
camParamCfg.wireNum = WIRE_1;
|
||||
#endif
|
||||
camParamCfg.endianMode = LSB_MODE;
|
||||
camParamCfg.rxSeq = SEQ_1;
|
||||
camParamCfg.cpha = 1;
|
||||
camParamCfg.cpol = 0;
|
||||
camParamCfg.yOnly = 1;
|
||||
camParamCfg.rowScaleRatio = 0;
|
||||
camParamCfg.colScaleRatio = 0;
|
||||
camParamCfg.scaleBytes = 0;
|
||||
camResolution = CAM_CHAIN_COUNT;
|
||||
#endif
|
||||
|
||||
camInterfaceCfg(&camParamCfg);
|
||||
|
||||
cspiDrv->ctrl(CSPI_CTRL_MEM_ADDR , (uint32_t)dataAddr); // register the recv memory
|
||||
cspiDrv->init(cb);
|
||||
|
||||
cspiDrv->powerCtrl(CSPI_POWER_FULL);
|
||||
cspiDrv->ctrl(CSPI_CTRL_DATA_FORMAT , 0); // control cspi
|
||||
cspiDrv->ctrl(CSPI_CTRL_RXTOR , 0);
|
||||
cspiDrv->ctrl(CSPI_CTRL_FRAME_INFO0 , 0);
|
||||
cspiDrv->ctrl(CSPI_CTRL_INT_CTRL , 0);
|
||||
|
||||
cspiDrv->ctrl(CSPI_CTRL_CSPICTL , 0);
|
||||
cspiDrv->ctrl(CSPI_CTRL_DMA_CTRL , 0);
|
||||
cspiDrv->ctrl(CSPI_CTRL_RESOLUTION_SET , camResolution);
|
||||
cspiDrv->ctrl(CSPI_CTRL_BUS_SPEED, (camFrequence_e)CAM_25_5_M); // cspi working frequency
|
||||
}
|
||||
|
||||
void camStartStop(cspiStartStop_e startStop)
|
||||
{
|
||||
cspiDrv->ctrl(CSPI_CTRL_START_STOP , (uint32_t)startStop);
|
||||
}
|
||||
|
||||
void cspiIntEnable(cspiIntEnable_e intEnable)
|
||||
{
|
||||
cspiIntCtrl.frameStartIntEn = intEnable;
|
||||
cspiDrv->ctrl(CSPI_CTRL_INT_CTRL , 0); // cspi interrupt enable or disable
|
||||
}
|
||||
|
||||
void camFlush()
|
||||
{
|
||||
cspiDrv->ctrl(CSPI_CTRL_FLUSH_RX_FIFO , 0); // flush rx fifo
|
||||
}
|
||||
|
||||
void camRegisterIRQ(cspiInstance_e instance, camIrq_fn irqCb)
|
||||
{
|
||||
IRQn_Type irqNum;
|
||||
|
||||
if (instance == CSPI_0)
|
||||
{
|
||||
irqNum = PXIC0_I2S0_IRQn;
|
||||
}
|
||||
else
|
||||
{
|
||||
irqNum = PXIC0_I2S1_IRQn;
|
||||
}
|
||||
|
||||
XIC_SetVector(irqNum, irqCb);
|
||||
XIC_EnableIRQ(irqNum);
|
||||
}
|
||||
|
||||
PLAT_FM_RAMCODE void camRecv(uint8_t * dataAddr)
|
||||
{
|
||||
cspiDrv->ctrl(CSPI_CTRL_MEM_ADDR , (uint32_t)dataAddr); // register the recv memory
|
||||
cspiDrv->recv();
|
||||
}
|
||||
|
||||
uint32_t camGetCspiStats(cspiInstance_e instance)
|
||||
{
|
||||
return EIGEN_CSPI(instance)->STAS;
|
||||
}
|
||||
|
||||
void camClearIntStats(cspiInstance_e instance, uint32_t mask)
|
||||
{
|
||||
EIGEN_CSPI(instance)->STAS = mask;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,666 @@
|
||||
#include "cameraDrv.h"
|
||||
|
||||
camI2cCfg_t gc032A_2sdrRegInfo[] =
|
||||
{
|
||||
{0xf3,0x83},
|
||||
{0xf5,0x0c},
|
||||
{0xf7,0x01},// gavin 20160820
|
||||
{0xf8,0x01},
|
||||
{0xf9,0x4e},
|
||||
{0xfa,0x10}, // gavin 20160820
|
||||
{0xfc,0x02},
|
||||
{0xfe,0x02},
|
||||
{0x81,0x03},
|
||||
{0xfe,0x00},
|
||||
{0x77,0x64},
|
||||
{0x78,0x40},
|
||||
{0x79,0x60},
|
||||
/*Analog&Cisctl*/
|
||||
{0xfe,0x00},
|
||||
{0x03,0x01},
|
||||
{0x04,0xc2},
|
||||
{0x05,0x01},
|
||||
{0x06,0xb8},
|
||||
{0x07,0x00},
|
||||
{0x08,0x08},
|
||||
{0x0a,0x00},
|
||||
{0x0c,0x00},
|
||||
{0x0d,0x01},
|
||||
{0x0e,0xe8},
|
||||
{0x0f,0x02},
|
||||
{0x10,0x88},
|
||||
{0x17,0x54},
|
||||
{0x19,0x08},
|
||||
{0x1a,0x0a},
|
||||
{0x1f,0x40},
|
||||
{0x20,0x30},
|
||||
{0x2e,0x80},
|
||||
{0x2f,0x2b},
|
||||
{0x30,0x1a},
|
||||
{0xfe,0x02},
|
||||
{0x03,0x02},
|
||||
{0x05,0xd7},
|
||||
{0x06,0x60},
|
||||
{0x08,0x80},
|
||||
{0x12,0x89},
|
||||
|
||||
/*SPI*/
|
||||
{0xfe,0x03},
|
||||
{0x51,0x01},
|
||||
{0x52,0x58}, // DDR Disable gavin 20160820
|
||||
{0x53,0x24}, // Disable CRC
|
||||
{0x54,0x20},
|
||||
{0x55,0x00},
|
||||
{0x59,0x10},
|
||||
{0x5a,0x00},
|
||||
{0x5b,0x80},
|
||||
{0x5c,0x02},
|
||||
{0x5d,0xe0},
|
||||
{0x5e,0x01},
|
||||
{0x64,0x04}, //SCK Always OFF , gavin 20160820
|
||||
|
||||
/*blk*/
|
||||
{0xfe,0x00},
|
||||
{0x18,0x02},
|
||||
{0xfe,0x02},
|
||||
{0x40,0x22},
|
||||
{0x45,0x00},
|
||||
{0x46,0x00},
|
||||
{0x49,0x20},
|
||||
{0x4b,0x3c},
|
||||
{0x50,0x20},
|
||||
{0x42,0x10},
|
||||
|
||||
/*isp*/
|
||||
{0xfe,0x01},
|
||||
{0x0a,0xc5},
|
||||
{0x45,0x00},
|
||||
{0xfe,0x00},
|
||||
{0x40,0xff},
|
||||
{0x41,0x25},
|
||||
{0x42,0xcf},
|
||||
{0x43,0x10},
|
||||
{0x44,0x83},
|
||||
{0x46,0x22},
|
||||
{0x49,0x03},
|
||||
{0x52,0x02},
|
||||
{0x54,0x00},
|
||||
{0xfe,0x02},
|
||||
{0x22,0xf6},
|
||||
|
||||
/*Shading*/
|
||||
{0xfe,0x01},
|
||||
{0xc1,0x38},
|
||||
{0xc2,0x4c},
|
||||
{0xc3,0x00},
|
||||
{0xc4,0x32},
|
||||
{0xc5,0x24},
|
||||
{0xc6,0x16},
|
||||
{0xc7,0x08},
|
||||
{0xc8,0x08},
|
||||
{0xc9,0x00},
|
||||
{0xca,0x20},
|
||||
{0xdc,0x8a},
|
||||
{0xdd,0xa0},
|
||||
{0xde,0xa6},
|
||||
{0xdf,0x75},
|
||||
|
||||
/*AWB*//*20170110*/
|
||||
{0xfe, 0x01},
|
||||
{0x7c, 0x09},
|
||||
{0x65, 0x06},
|
||||
{0x7c, 0x08},
|
||||
{0x56, 0xf4},
|
||||
{0x66, 0x0f},
|
||||
{0x67, 0x84},
|
||||
{0x6b, 0x80},
|
||||
{0x6d, 0x12},
|
||||
{0x6e, 0xb0},
|
||||
{0xfe, 0x01},
|
||||
{0x90, 0x00},
|
||||
{0x91, 0x00},
|
||||
{0x92, 0xf4},
|
||||
{0x93, 0xd5},
|
||||
{0x95, 0x0f},
|
||||
{0x96, 0xf4},
|
||||
{0x97, 0x2d},
|
||||
{0x98, 0x0f},
|
||||
{0x9a, 0x2d},
|
||||
{0x9b, 0x0f},
|
||||
{0x9c, 0x59},
|
||||
{0x9d, 0x2d},
|
||||
{0x9f, 0x67},
|
||||
{0xa0, 0x59},
|
||||
{0xa1, 0x00},
|
||||
{0xa2, 0x00},
|
||||
{0x86, 0x00},
|
||||
{0x87, 0x00},
|
||||
{0x88, 0x00},
|
||||
{0x89, 0x00},
|
||||
{0xa4, 0x00},
|
||||
{0xa5, 0x00},
|
||||
{0xa6, 0xd4},
|
||||
{0xa7, 0x9f},
|
||||
{0xa9, 0xd4},
|
||||
{0xaa, 0x9f},
|
||||
{0xab, 0xac},
|
||||
{0xac, 0x9f},
|
||||
{0xae, 0xd4},
|
||||
{0xaf, 0xac},
|
||||
{0xb0, 0xd4},
|
||||
{0xb1, 0xa3},
|
||||
{0xb3, 0xd4},
|
||||
{0xb4, 0xac},
|
||||
{0xb5, 0x00},
|
||||
{0xb6, 0x00},
|
||||
{0x8b, 0x00},
|
||||
{0x8c, 0x00},
|
||||
{0x8d, 0x00},
|
||||
{0x8e, 0x00},
|
||||
{0x94, 0x50},
|
||||
{0x99, 0xa6},
|
||||
{0x9e, 0xaa},
|
||||
{0xa3, 0x0a},
|
||||
{0x8a, 0x00},
|
||||
{0xa8, 0x50},
|
||||
{0xad, 0x55},
|
||||
{0xb2, 0x55},
|
||||
{0xb7, 0x05},
|
||||
{0x8f, 0x00},
|
||||
{0xb8, 0xb3},
|
||||
{0xb9, 0xb6},
|
||||
|
||||
/*CC*/
|
||||
{0xfe,0x01},
|
||||
{0xd0,0x40},
|
||||
{0xd1,0xf8},
|
||||
{0xd2,0x00},
|
||||
{0xd3,0xfa},
|
||||
{0xd4,0x45},
|
||||
{0xd5,0x02},
|
||||
{0xd6,0x30},
|
||||
{0xd7,0xfa},
|
||||
{0xd8,0x08},
|
||||
{0xd9,0x08},
|
||||
{0xda,0x58},
|
||||
{0xdb,0x02},
|
||||
{0xfe,0x00},
|
||||
|
||||
/*Gamma*/
|
||||
{0xfe,0x00},
|
||||
{0xba,0x00},
|
||||
{0xbb,0x04},
|
||||
{0xbc,0x0a},
|
||||
{0xbd,0x0e},
|
||||
{0xbe,0x22},
|
||||
{0xbf,0x30},
|
||||
{0xc0,0x3d},
|
||||
{0xc1,0x4a},
|
||||
{0xc2,0x5d},
|
||||
{0xc3,0x6b},
|
||||
{0xc4,0x7a},
|
||||
{0xc5,0x85},
|
||||
{0xc6,0x90},
|
||||
{0xc7,0xa5},
|
||||
{0xc8,0xb5},
|
||||
{0xc9,0xc2},
|
||||
{0xca,0xcc},
|
||||
{0xcb,0xd5},
|
||||
{0xcc,0xde},
|
||||
{0xcd,0xea},
|
||||
{0xce,0xf5},
|
||||
{0xcf,0xff},
|
||||
|
||||
/*Auto Gamma*/
|
||||
{0xfe,0x00},
|
||||
{0x5a,0x08},
|
||||
{0x5b,0x0f},
|
||||
{0x5c,0x15},
|
||||
{0x5d,0x1c},
|
||||
{0x5e,0x28},
|
||||
{0x5f,0x36},
|
||||
{0x60,0x45},
|
||||
{0x61,0x51},
|
||||
{0x62,0x6a},
|
||||
{0x63,0x7d},
|
||||
{0x64,0x8d},
|
||||
{0x65,0x98},
|
||||
{0x66,0xa2},
|
||||
{0x67,0xb5},
|
||||
{0x68,0xc3},
|
||||
{0x69,0xcd},
|
||||
{0x6a,0xd4},
|
||||
{0x6b,0xdc},
|
||||
{0x6c,0xe3},
|
||||
{0x6d,0xf0},
|
||||
{0x6e,0xf9},
|
||||
{0x6f,0xff},
|
||||
|
||||
/*Gain*/
|
||||
{0xfe,0x00},
|
||||
{0x70,0x50},
|
||||
|
||||
/*AEC*/
|
||||
{0xfe,0x00},
|
||||
{0x4f,0x01},
|
||||
{0xfe,0x01},
|
||||
{0x0d,0x00},//08 add 20170110
|
||||
{0x12,0xa0},
|
||||
{0x13,0x3a},
|
||||
{0x44,0x04},
|
||||
{0x1f,0x30},
|
||||
{0x20,0x40},
|
||||
{0x26,0x9a},
|
||||
{0x3e,0x20},
|
||||
{0x3f,0x2d},
|
||||
{0x40,0x40},
|
||||
{0x41,0x5b},
|
||||
{0x42,0x82},
|
||||
{0x43,0xb7},
|
||||
{0x04,0x0a},
|
||||
{0x02,0x79},
|
||||
{0x03,0xc0},
|
||||
|
||||
/*measure window*/
|
||||
{0xfe,0x01},
|
||||
{0xcc,0x08},
|
||||
{0xcd,0x08},
|
||||
{0xce,0xa4},
|
||||
{0xcf,0xec},
|
||||
|
||||
/*DNDD*/
|
||||
{0xfe,0x00},
|
||||
{0x81,0xb8},
|
||||
{0x82,0x12},
|
||||
{0x83,0x0a},
|
||||
{0x84,0x01},
|
||||
{0x86,0x50},
|
||||
{0x87,0x18},
|
||||
{0x88,0x10},
|
||||
{0x89,0x70},
|
||||
{0x8a,0x20},
|
||||
{0x8b,0x10},
|
||||
{0x8c,0x08},
|
||||
{0x8d,0x0a},
|
||||
|
||||
/*Intpee*/
|
||||
{0xfe,0x00},
|
||||
{0x8f,0xaa},
|
||||
{0x90,0x9c},
|
||||
{0x91,0x52},
|
||||
{0x92,0x03},
|
||||
{0x93,0x03},
|
||||
{0x94,0x08},
|
||||
{0x95,0x44},
|
||||
{0x97,0x00},
|
||||
{0x98,0x00},
|
||||
|
||||
/*ASDE*/
|
||||
{0xfe,0x00},
|
||||
{0xa1,0x30},
|
||||
{0xa2,0x41},
|
||||
{0xa4,0x30},
|
||||
{0xa5,0x20},
|
||||
{0xaa,0x30},
|
||||
{0xac,0x32},
|
||||
|
||||
/*YCP*/
|
||||
{0xfe,0x00},
|
||||
{0xd1,0x3c},
|
||||
{0xd2,0x3c},
|
||||
{0xd3,0x38},
|
||||
{0xd6,0xf4},
|
||||
{0xd7,0x1d},
|
||||
{0xdd,0x73},
|
||||
{0xde,0x84},
|
||||
{0xfe,0x00},
|
||||
{0x05,0x01},
|
||||
{0x06,0xad},
|
||||
{0x07,0x00},
|
||||
{0x08,0x10},
|
||||
{0xfe,0x01},
|
||||
{0x25,0x00},
|
||||
{0x26,0x4d},
|
||||
{0x27,0x01},
|
||||
{0x28,0xce},
|
||||
{0x29,0x03},
|
||||
{0x2a,0x02},
|
||||
{0x2b,0x03},
|
||||
{0x2c,0x9c},
|
||||
{0x2d,0x04},
|
||||
{0x2e,0x36},
|
||||
{0x2f,0x04},
|
||||
{0x30,0xd0},
|
||||
{0x31,0x05},
|
||||
{0x32,0x6a},
|
||||
{0x33,0x06},
|
||||
{0x34,0x04},
|
||||
{0xfe,0x00},
|
||||
};
|
||||
|
||||
camI2cCfg_t gc032A_1sdrRegInfo[] =
|
||||
{
|
||||
{0xf3,0x83}, //sync_output_en data_output_en
|
||||
{0xf5,0x0c},
|
||||
{0xf7,0x01},
|
||||
{0xf8,0x01},
|
||||
{0xf9,0x4e},
|
||||
{0xfa,0x30},
|
||||
{0xfc,0x02},
|
||||
{0xfe,0x02},
|
||||
{0x81,0x03}, // doesn't show 0x81 addr
|
||||
/*Analog*/
|
||||
{0xfe,0x00},
|
||||
{0x03,0x01}, // exposure high
|
||||
{0x04,0xc2}, // exposure low
|
||||
{0x05,0x01},
|
||||
{0x06,0x91},
|
||||
{0x07,0x00},
|
||||
{0x08,0x10},
|
||||
{0x0a,0x04},
|
||||
{0x0c,0x04},
|
||||
{0x0d,0x01},
|
||||
{0x0e,0xe8}, // height: 488
|
||||
{0x0f,0x02},
|
||||
{0x10,0x88}, // width: 652 VGA: 640*480
|
||||
{0x17,0x54},
|
||||
{0x19,0x04},
|
||||
{0x1a,0x0a},
|
||||
{0x1f,0x40},
|
||||
{0x20,0x30},
|
||||
{0x2e,0x80},
|
||||
{0x2f,0x2b},
|
||||
{0x30,0x1a},
|
||||
{0xfe,0x02},
|
||||
{0x03,0x02},
|
||||
{0x05,0xd7},
|
||||
{0x06,0x60},
|
||||
{0x08,0x80},
|
||||
{0x12,0x89},
|
||||
/*blk*/
|
||||
{0xfe,0x00},
|
||||
{0x18,0x02},
|
||||
{0xfe,0x02},
|
||||
{0x40,0x22},
|
||||
{0x45,0x00},
|
||||
{0x46,0x00},
|
||||
{0x49,0x20},
|
||||
{0x4b,0x3c},
|
||||
{0x50,0x20},
|
||||
{0x42,0x10},
|
||||
/*isp*/
|
||||
{0xfe,0x01},
|
||||
{0x0a,0xc5},
|
||||
{0x45,0x00},
|
||||
{0xfe,0x00},
|
||||
{0x40,0xff},
|
||||
{0x41,0x25},
|
||||
{0x42,0x83},
|
||||
{0x43,0x10},
|
||||
{0x44,0x83},
|
||||
{0x46,0x26},
|
||||
{0x49,0x03},
|
||||
{0x4f,0x01},
|
||||
{0xde,0x84},
|
||||
{0xfe,0x02},
|
||||
{0x22,0xf6},
|
||||
/*Shading*/
|
||||
{0xfe,0x00},
|
||||
{0x77,0x65},
|
||||
{0x78,0x40},
|
||||
{0x79,0x52},
|
||||
{0xfe,0x01},
|
||||
{0xc1,0x3c},
|
||||
{0xc2,0x50},
|
||||
{0xc3,0x00},
|
||||
{0xc4,0x32},
|
||||
{0xc5,0x24},
|
||||
{0xc6,0x16},
|
||||
{0xc7,0x08},
|
||||
{0xc8,0x08},
|
||||
{0xc9,0x00},
|
||||
{0xca,0x20},
|
||||
{0xdc,0x7a},
|
||||
{0xdd,0x7a},
|
||||
{0xde,0xa6},
|
||||
{0xdf,0x60},
|
||||
/*AWB*/
|
||||
{0xfe,0x01},
|
||||
{0x7c,0x09},
|
||||
{0x65,0x06},
|
||||
{0x7c,0x08},
|
||||
{0x56,0xf4},
|
||||
{0x66,0x0f},
|
||||
{0x67,0x84},
|
||||
{0x6b,0x80},
|
||||
{0x6d,0x12},
|
||||
{0x6e,0xb0},
|
||||
{0x86,0x00},
|
||||
{0x87,0x00},
|
||||
{0x88,0x00},
|
||||
{0x89,0x00},
|
||||
{0x8a,0x00},
|
||||
{0x8b,0x00},
|
||||
{0x8c,0x00},
|
||||
{0x8d,0x00},
|
||||
{0x8e,0x00},
|
||||
{0x8f,0x00},
|
||||
{0x90,0xef},
|
||||
{0x91,0xe1},
|
||||
{0x92,0x0c},
|
||||
{0x93,0xef},
|
||||
{0x94,0x65},
|
||||
{0x95,0x1f},
|
||||
{0x96,0x0c},
|
||||
{0x97,0x2d},
|
||||
{0x98,0x20},
|
||||
{0x99,0xaa},
|
||||
{0x9a,0x3f},
|
||||
{0x9b,0x2c},
|
||||
{0x9c,0x5f},
|
||||
{0x9d,0x3e},
|
||||
{0x9e,0xaa},
|
||||
{0x9f,0x67},
|
||||
{0xa0,0x60},
|
||||
{0xa1,0x00},
|
||||
{0xa2,0x00},
|
||||
{0xa3,0x0a},
|
||||
{0xa4,0xb6},
|
||||
{0xa5,0xac},
|
||||
{0xa6,0xc1},
|
||||
{0xa7,0xac},
|
||||
{0xa8,0x55},
|
||||
{0xa9,0xc3},
|
||||
{0xaa,0xa4},
|
||||
{0xab,0xba},
|
||||
{0xac,0xa8},
|
||||
{0xad,0x55},
|
||||
{0xae,0xc8},
|
||||
{0xaf,0xb9},
|
||||
{0xb0,0xd4},
|
||||
{0xb1,0xc3},
|
||||
{0xb2,0x55},
|
||||
{0xb3,0xd8},
|
||||
{0xb4,0xce},
|
||||
{0xb5,0x00},
|
||||
{0xb6,0x00},
|
||||
{0xb7,0x05},
|
||||
{0xb8,0xd6},
|
||||
{0xb9,0x8c},
|
||||
/*CC*/
|
||||
{0xfe,0x01},
|
||||
{0xd0,0x40},
|
||||
{0xd1,0xf8},
|
||||
{0xd2,0x00},
|
||||
{0xd3,0xfa},
|
||||
{0xd4,0x45},
|
||||
{0xd5,0x02},
|
||||
{0xd6,0x30},
|
||||
{0xd7,0xfa},
|
||||
{0xd8,0x08},
|
||||
{0xd9,0x08},
|
||||
{0xda,0x58},
|
||||
{0xdb,0x02},
|
||||
{0xfe,0x00},
|
||||
/*Gamma*/
|
||||
{0xfe,0x00},
|
||||
{0xba,0x00},
|
||||
{0xbb,0x04},
|
||||
{0xbc,0x0a},
|
||||
{0xbd,0x0e},
|
||||
{0xbe,0x22},
|
||||
{0xbf,0x30},
|
||||
{0xc0,0x3d},
|
||||
{0xc1,0x4a},
|
||||
{0xc2,0x5d},
|
||||
{0xc3,0x6b},
|
||||
{0xc4,0x7a},
|
||||
{0xc5,0x85},
|
||||
{0xc6,0x90},
|
||||
{0xc7,0xa5},
|
||||
{0xc8,0xb5},
|
||||
{0xc9,0xc2},
|
||||
{0xca,0xcc},
|
||||
{0xcb,0xd5},
|
||||
{0xcc,0xde},
|
||||
{0xcd,0xea},
|
||||
{0xce,0xf5},
|
||||
{0xcf,0xff},
|
||||
/*Auto Ga*/
|
||||
{0xfe,0x00},
|
||||
{0x5a,0x08},
|
||||
{0x5b,0x0f},
|
||||
{0x5c,0x15},
|
||||
{0x5d,0x1c},
|
||||
{0x5e,0x28},
|
||||
{0x5f,0x36},
|
||||
{0x60,0x45},
|
||||
{0x61,0x51},
|
||||
{0x62,0x6a},
|
||||
{0x63,0x7d},
|
||||
{0x64,0x8d},
|
||||
{0x65,0x98},
|
||||
{0x66,0xa2},
|
||||
{0x67,0xb5},
|
||||
{0x68,0xc3},
|
||||
{0x69,0xcd},
|
||||
{0x6a,0xd4},
|
||||
{0x6b,0xdc},
|
||||
{0x6c,0xe3},
|
||||
{0x6d,0xf0},
|
||||
{0x6e,0xf9},
|
||||
{0x6f,0xff},
|
||||
/*Gain*/
|
||||
{0xfe,0x00},
|
||||
{0x70,0x50},
|
||||
/*AEC*/
|
||||
{0xfe,0x00},
|
||||
{0x4f,0x01},
|
||||
{0xfe,0x01},
|
||||
{0x12,0xa0},
|
||||
{0x13,0x3a},
|
||||
{0x44,0x04},
|
||||
{0x1f,0x30},
|
||||
{0x20,0x40},
|
||||
{0x26,0x14},
|
||||
{0x27,0x01},
|
||||
{0x28,0xf4},
|
||||
{0x29,0x02},
|
||||
{0x2a,0x3a},
|
||||
{0x2b,0x02},
|
||||
{0x2c,0xac},
|
||||
{0x2d,0x02},
|
||||
{0x2e,0xf8},
|
||||
{0x2f,0x0b},
|
||||
{0x30,0x6e},
|
||||
{0x31,0x0e},
|
||||
{0x32,0x70},
|
||||
{0x33,0x12},
|
||||
{0x34,0x0c},
|
||||
{0x3c,0x00},
|
||||
{0x3e,0x20},
|
||||
{0x3f,0x2d},
|
||||
{0x40,0x40},
|
||||
{0x41,0x5b},
|
||||
{0x42,0x82},
|
||||
{0x43,0xb7},
|
||||
{0x04,0x0a},
|
||||
{0x02,0x79},
|
||||
{0x03,0xc0},
|
||||
/*measure*/
|
||||
{0xcc,0x08},
|
||||
{0xcd,0x08},
|
||||
{0xce,0xa4},
|
||||
{0xcf,0xec},
|
||||
/*DNDD*/
|
||||
{0xfe,0x00},
|
||||
{0x81,0xb8},
|
||||
{0x82,0x12},
|
||||
{0x83,0x0a},
|
||||
{0x84,0x01},
|
||||
{0x86,0x50},
|
||||
{0x87,0x18},
|
||||
{0x88,0x10},
|
||||
{0x89,0x70},
|
||||
{0x8a,0x20},
|
||||
{0x8b,0x10},
|
||||
{0x8c,0x08},
|
||||
{0x8d,0x0a},
|
||||
/*Intpee*/
|
||||
{0xfe,0x00},
|
||||
{0x8f,0xaa},
|
||||
{0x90,0x9c},
|
||||
{0x91,0x52},
|
||||
{0x92,0x03},
|
||||
{0x93,0x03},
|
||||
{0x94,0x08},
|
||||
{0x95,0x44},
|
||||
{0x97,0x00},
|
||||
{0x98,0x00},
|
||||
/*ASDE*/
|
||||
{0xfe,0x00},
|
||||
{0xa1,0x30},
|
||||
{0xa2,0x41},
|
||||
{0xa4,0x30},
|
||||
{0xa5,0x20},
|
||||
{0xaa,0x30},
|
||||
{0xac,0x32},
|
||||
/*YCP*/
|
||||
{0xfe,0x00},
|
||||
{0xd1,0x3c},
|
||||
{0xd2,0x3c},
|
||||
{0xd3,0x38},
|
||||
{0xd6,0xf4},
|
||||
{0xd7,0x1d},
|
||||
{0xdd,0x73},
|
||||
{0xde,0x84},
|
||||
/*SPI*/
|
||||
{0xfe,0x03}, // registers in REGF3
|
||||
{0x51,0x01},
|
||||
{0x52,0x0a}, // Y: 266
|
||||
{0x53,0x20}, // ֻ<><D6BB>2bit<69><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0x20?
|
||||
{0x54,0x20}, // X: 0x220 = 544
|
||||
{0x55,0x00},
|
||||
{0x59,0x10},
|
||||
{0x5a,0x00}, // sync format<61><74>
|
||||
{0x5b,0x80},
|
||||
{0x5c,0x02}, // image width<74><68>640
|
||||
{0x5d,0xe0},
|
||||
{0x5e,0x01}, // image height<68><74>480
|
||||
};
|
||||
|
||||
uint16_t gc032aGetRegCnt(char* regName)
|
||||
{
|
||||
if (strcmp(regName, "gc032a_2sdr") == 0)
|
||||
{
|
||||
return (sizeof(gc032A_2sdrRegInfo) / sizeof(gc032A_2sdrRegInfo[0]));
|
||||
}
|
||||
else if (strcmp(regName, "gc032a_1sdr") == 0)
|
||||
{
|
||||
return (sizeof(gc032A_1sdrRegInfo) / sizeof(gc032A_1sdrRegInfo[0]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
#include "cameraDrv.h"
|
||||
|
||||
camI2cCfg_t gc6123_2sdrRegInfo[] =
|
||||
{
|
||||
{0xfe, 0xa0},
|
||||
{0xfe, 0xa0},
|
||||
{0xfe, 0xa0},
|
||||
{0xf1, 0x07}, //output enable
|
||||
{0xf4, 0x00},
|
||||
//{0xf7, 0x00},
|
||||
//{0xfa, 0x00},
|
||||
{0xfc, 0x16}, //clock enable
|
||||
|
||||
{0xfe , 0x00},
|
||||
|
||||
{0x08, 0x02}, //col start
|
||||
{0x09, 0x01}, //window height
|
||||
{0x0a, 0x48},
|
||||
{0x0b, 0x00}, //window width
|
||||
{0x0c, 0xf4},
|
||||
{0x10, 0x48}, //sh_width
|
||||
{0x11, 0x1d}, //tx_width
|
||||
{0x14, 0x14}, //dark CFA
|
||||
{0x15, 0x0a}, //sdark
|
||||
{0x16, 0x04}, //AD pipe number
|
||||
{0x18, 0xc2}, //rowsg_gap
|
||||
{0x1a, 0x17}, //clk_delay_en
|
||||
{0x1b, 0x1a}, //20121107 comv_r solve FPN-W/18 //70/adclk mode
|
||||
{0x1c, 0x49}, //txhigh_en
|
||||
{0x1d, 0xb0}, //vref
|
||||
{0x1e, 0x52}, //20131231/53//20130306/52 //20121107 solve OBI/51 //ADC_r
|
||||
//{0x1f, 0x3f},
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// ISP //////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x20,0x5e},
|
||||
{0x21,0x38}, //autogray
|
||||
{0x22,0x92}, //20121107 auto_DD_en/82 //02
|
||||
{0x24,0xa2}, //output_format
|
||||
{0x26,0x03},
|
||||
{0x27,0x90}, //clock gating
|
||||
{0x28,0x8c},
|
||||
{0x38,0x80}, //crop
|
||||
{0x3b,0x01},
|
||||
{0x3c,0x40},
|
||||
{0x3d,0x00},
|
||||
{0x3e,0xf0},
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// BLK //////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x2a, 0x65}, //2f/BLK row select
|
||||
{0x2c, 0x40}, //global offset
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// GAIN /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x3f, 0x12}, //20/global gain
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// DNDD /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x50, 0x45},
|
||||
{0x52, 0x4f}, //6c/DN b
|
||||
{0x53, 0x81}, //a5/DN C
|
||||
{0x58, 0x6f}, //20121107 dark_th 64
|
||||
{0xc3, 0x96}, //00
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// ASDE /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0xac, 0xb5},
|
||||
{0x5c, 0x80}, //60/OT_th
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///////////////////// INTPEE ////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x63, 0x03}, //04/edge effect
|
||||
{0x65, 0x23}, //43/42/edge max/min
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///////////////////// GAMMA /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// CC ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x66, 0x13},
|
||||
{0x67, 0x26},
|
||||
{0x68, 0x07},
|
||||
{0x69, 0xf5},
|
||||
{0x6a, 0xea},
|
||||
{0x6b, 0x21},
|
||||
{0x6c, 0x21},
|
||||
{0x6d, 0xe4},
|
||||
{0x6e, 0xfb},
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// YCP //////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x81, 0x48}, //38//cb
|
||||
{0x82, 0x48}, //38//cr
|
||||
{0x83, 0x4b}, //40/luma contrast
|
||||
{0x84, 0x80}, //90/contrast center
|
||||
{0x85, 0x00}, //06/luma offset
|
||||
{0x86, 0xfb}, //skin cb
|
||||
{0x87, 0x1d}, //skin cr
|
||||
{0x88, 0x18}, //skin radius
|
||||
{0x8d, 0x78}, //38/edge dec sa
|
||||
{0x8e, 0x25}, //autogray
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// AEC //////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0xa4, 0x01},
|
||||
{0x9e, 0x01}, // increase fps
|
||||
{0x9f, 0x90}, // 0x1c
|
||||
{0xa0, 0x10},
|
||||
{0x90, 0x4a}, //0a //48
|
||||
{0x92, 0x40}, //40/target Y
|
||||
{0xa2, 0x40}, //max_post_gain
|
||||
{0xa3, 0x80}, //max_pre_gain
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// AWB //////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0xb0, 0xf8}, //f5/RGB high low
|
||||
{0xb1, 0x24}, //18/Y to C
|
||||
{0xb3, 0x20}, //0d/C max
|
||||
{0xb4, 0x2d}, //22/C inter
|
||||
{0xb5, 0x1b}, //22/C inter
|
||||
{0xb6, 0x2e}, //C inter2
|
||||
{0xb7, 0x18}, //40/C inter3
|
||||
{0xb8, 0x13}, //20/number limit
|
||||
{0xb9, 0x33},
|
||||
{0xba, 0x21},
|
||||
{0xbb, 0x61}, //42/speed & margin
|
||||
{0xbf, 0x68}, //78/b limit
|
||||
{0x4c, 0x08},
|
||||
{0x4d, 0x06},
|
||||
{0x4e, 0x7b},
|
||||
{0x4f, 0xa0},
|
||||
|
||||
{0xfe, 0x02},
|
||||
|
||||
{0x01, 0x03},
|
||||
{0x02, 0x02}, //LSB & Falling edge sample
|
||||
//{0x03, 0x20}, //1-wire
|
||||
{0x04, 0x20}, //[4] master_outformat
|
||||
{0x05, 0x00},
|
||||
{0x09, 0x00}, //Reverse the high<->low byte.
|
||||
{0x0a, 0x00}, //Data ID, 0x00-YUV422, 0x01-RGB565
|
||||
{0x13, 0xf0},
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///////////////////// 2-wire ////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x03, 0x25}, //20
|
||||
{0xfd, 0x04},
|
||||
{0xf1, 0x07}, //00
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///////////////////// 1-wire ////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
//{0x03, 0x20}, //20
|
||||
//{0xfd, 0x00}, //00
|
||||
//{0xf1, 0x05},
|
||||
|
||||
{0xfe, 0x00},
|
||||
};
|
||||
|
||||
camI2cCfg_t gc6123_1sdrRegInfo[] =
|
||||
{
|
||||
{0xfe, 0xa0},
|
||||
{0xfe, 0xa0},
|
||||
{0xfe, 0xa0},
|
||||
{0xf1, 0x07}, //output enable
|
||||
{0xf4, 0x00},
|
||||
//{0xf7, 0x00},
|
||||
//{0xfa, 0x00},
|
||||
{0xfc, 0x16}, //clock enable
|
||||
|
||||
{0xfe , 0x00},
|
||||
|
||||
{0x08, 0x02}, //col start
|
||||
{0x09, 0x01}, //window height
|
||||
{0x0a, 0x48},
|
||||
{0x0b, 0x00}, //window width
|
||||
{0x0c, 0xf4},
|
||||
{0x10, 0x48}, //sh_width
|
||||
{0x11, 0x1d}, //tx_width
|
||||
{0x14, 0x14}, //dark CFA
|
||||
{0x15, 0x0a}, //sdark
|
||||
{0x16, 0x04}, //AD pipe number
|
||||
{0x18, 0xc2}, //rowsg_gap
|
||||
{0x1a, 0x17}, //clk_delay_en
|
||||
{0x1b, 0x1a}, //20121107 comv_r solve FPN-W/18 //70/adclk mode
|
||||
{0x1c, 0x49}, //txhigh_en
|
||||
{0x1d, 0xb0}, //vref
|
||||
{0x1e, 0x52}, //20131231/53//20130306/52 //20121107 solve OBI/51 //ADC_r
|
||||
//{0x1f, 0x3f},
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// ISP //////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x20,0x5e},
|
||||
{0x21,0x38}, //autogray
|
||||
{0x22,0x92}, //20121107 auto_DD_en/82 //02
|
||||
{0x24,0xa2}, //output_format
|
||||
{0x26,0x03},
|
||||
{0x27,0x90}, //clock gating
|
||||
{0x28,0x8c},
|
||||
{0x38,0x80}, //crop
|
||||
{0x3b,0x01},
|
||||
{0x3c,0x40},
|
||||
{0x3d,0x00},
|
||||
{0x3e,0xf0},
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// BLK //////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x2a, 0x65}, //2f/BLK row select
|
||||
{0x2c, 0x40}, //global offset
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// GAIN /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x3f, 0x12}, //20/global gain
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// DNDD /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x50, 0x45},
|
||||
{0x52, 0x4f}, //6c/DN b
|
||||
{0x53, 0x81}, //a5/DN C
|
||||
{0x58, 0x6f}, //20121107 dark_th 64
|
||||
{0xc3, 0x96}, //00
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// ASDE /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0xac, 0xb5},
|
||||
{0x5c, 0x80}, //60/OT_th
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///////////////////// INTPEE ////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x63, 0x03}, //04/edge effect
|
||||
{0x65, 0x23}, //43/42/edge max/min
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///////////////////// GAMMA /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// CC ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x66, 0x13},
|
||||
{0x67, 0x26},
|
||||
{0x68, 0x07},
|
||||
{0x69, 0xf5},
|
||||
{0x6a, 0xea},
|
||||
{0x6b, 0x21},
|
||||
{0x6c, 0x21},
|
||||
{0x6d, 0xe4},
|
||||
{0x6e, 0xfb},
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// YCP //////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x81, 0x48}, //38//cb
|
||||
{0x82, 0x48}, //38//cr
|
||||
{0x83, 0x4b}, //40/luma contrast
|
||||
{0x84, 0x80}, //90/contrast center
|
||||
{0x85, 0x00}, //06/luma offset
|
||||
{0x86, 0xfb}, //skin cb
|
||||
{0x87, 0x1d}, //skin cr
|
||||
{0x88, 0x18}, //skin radius
|
||||
{0x8d, 0x78}, //38/edge dec sa
|
||||
{0x8e, 0x25}, //autogray
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// AEC //////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0xa4, 0x01},
|
||||
{0x9e, 0x01}, // 0x02
|
||||
{0x9f, 0x90}, // 0x1c
|
||||
{0xa0, 0x10},
|
||||
{0x90, 0x4a}, //0a //48
|
||||
{0x92, 0x40}, //40/target Y
|
||||
{0xa2, 0x40}, //max_post_gain
|
||||
{0xa3, 0x80}, //max_pre_gain
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
////////////////////// AWB //////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0xb0, 0xf8}, //f5/RGB high low
|
||||
{0xb1, 0x24}, //18/Y to C
|
||||
{0xb3, 0x20}, //0d/C max
|
||||
{0xb4, 0x2d}, //22/C inter
|
||||
{0xb5, 0x1b}, //22/C inter
|
||||
{0xb6, 0x2e}, //C inter2
|
||||
{0xb7, 0x18}, //40/C inter3
|
||||
{0xb8, 0x13}, //20/number limit
|
||||
{0xb9, 0x33},
|
||||
{0xba, 0x21},
|
||||
{0xbb, 0x61}, //42/speed & margin
|
||||
{0xbf, 0x68}, //78/b limit
|
||||
{0x4c, 0x08},
|
||||
{0x4d, 0x06},
|
||||
{0x4e, 0x7b},
|
||||
{0x4f, 0xa0},
|
||||
|
||||
{0xfe, 0x02},
|
||||
|
||||
{0x01, 0x03},
|
||||
{0x02, 0x02}, //LSB & Falling edge sample
|
||||
//{0x03, 0x20}, //1-wire
|
||||
{0x04, 0x20}, //[4] master_outformat
|
||||
{0x05, 0x00},
|
||||
{0x09, 0x00}, //Reverse the high<->low byte.
|
||||
{0x0a, 0x00}, //Data ID, 0x00-YUV422, 0x01-RGB565
|
||||
{0x13, 0xf0},
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///////////////////// 2-wire ////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
// {0x03, 0x25}, //20
|
||||
// {0xfd, 0x04},
|
||||
// {0xf1, 0x07}, //00
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///////////////////// 1-wire ////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
{0x03, 0x20}, //20
|
||||
{0xfd, 0x00}, //00
|
||||
{0xf1, 0x05},
|
||||
|
||||
{0xfe, 0x00},
|
||||
|
||||
};
|
||||
|
||||
uint16_t gc6123GetRegCnt(char* regName)
|
||||
{
|
||||
if (strcmp(regName, "gc6123_2sdr") == 0)
|
||||
{
|
||||
return (sizeof(gc6123_2sdrRegInfo) / sizeof(gc6123_2sdrRegInfo[0]));
|
||||
}
|
||||
else if (strcmp(regName, "gc6123_1sdr") == 0)
|
||||
{
|
||||
return (sizeof(gc6123_1sdrRegInfo) / sizeof(gc6123_1sdrRegInfo[0]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
#include "cameraDrv.h"
|
||||
|
||||
camI2cCfg_t gc6153_1sdrRegInfo[] =
|
||||
{
|
||||
// SYS
|
||||
{0xfe, 0xa0},
|
||||
{0xfe, 0xa0},
|
||||
{0xfe, 0xa0},
|
||||
{0xfa, 0x11},
|
||||
{0xfc, 0x00},
|
||||
{0xf6, 0x00},
|
||||
{0xfc, 0x12},
|
||||
|
||||
// ANALOG & CISCTL
|
||||
{0xfe, 0x00},
|
||||
{0x01, 0x40},
|
||||
{0x02, 0x12},
|
||||
{0x0d, 0x40},
|
||||
{0x14, 0x7c}, // 0x7e
|
||||
{0x16, 0x05}, // 0x05
|
||||
{0x17, 0x18}, // 0x18
|
||||
{0x1c, 0x31},
|
||||
{0x1d, 0xbb},
|
||||
{0x1f, 0x3f},
|
||||
{0x73, 0x20},
|
||||
{0x74, 0x71},
|
||||
{0x77, 0x22},
|
||||
{0x7a, 0x08},
|
||||
{0x11, 0x18},
|
||||
{0x13, 0x48},
|
||||
{0x12, 0xc8},
|
||||
{0x70, 0xc8},
|
||||
{0x7b, 0x18},
|
||||
{0x7d, 0x30},
|
||||
{0x7e, 0x02},
|
||||
|
||||
{0xfe, 0x10},
|
||||
{0xfe, 0x00},
|
||||
{0xfe, 0x00},
|
||||
{0xfe, 0x00},
|
||||
{0xfe, 0x00},
|
||||
{0xfe, 0x00},
|
||||
{0xfe, 0x10},
|
||||
{0xfe, 0x00},
|
||||
|
||||
{0x49, 0x61},
|
||||
{0x4a, 0x40},
|
||||
{0x4b, 0x58},
|
||||
|
||||
/*ISP*/
|
||||
{0xfe, 0x00},
|
||||
{0x39, 0x02},
|
||||
{0x3a, 0x80},
|
||||
{0x20, 0x7e},
|
||||
{0x26, 0xa7},
|
||||
|
||||
/*BLK*/
|
||||
{0x33, 0x10},
|
||||
{0x37, 0x06},
|
||||
{0x2a, 0x21},
|
||||
|
||||
/*GAIN*/
|
||||
{0x3f, 0x16},
|
||||
|
||||
/*DNDD*/
|
||||
{0x52, 0xa6},
|
||||
{0x53, 0x81},
|
||||
{0x54, 0x43},
|
||||
{0x56, 0x78},
|
||||
{0x57, 0xaa},
|
||||
{0x58, 0xff},
|
||||
|
||||
/*ASDE*/
|
||||
{0x5b, 0x60},
|
||||
{0x5c, 0x50},
|
||||
{0xab, 0x2a},
|
||||
{0xac, 0xb5},
|
||||
|
||||
/*INTPEE*/
|
||||
{0x5e, 0x06},
|
||||
{0x5f, 0x06},
|
||||
{0x60, 0x44},
|
||||
{0x61, 0xff},
|
||||
{0x62, 0x69},
|
||||
{0x63, 0x13},
|
||||
|
||||
/*CC*/
|
||||
{0x65, 0x13},
|
||||
{0x66, 0x26},
|
||||
{0x67, 0x07},
|
||||
{0x68, 0xf5},
|
||||
{0x69, 0xea},
|
||||
{0x6a, 0x21},
|
||||
{0x6b, 0x21},
|
||||
{0x6c, 0xe4},
|
||||
{0x6d, 0xfb},
|
||||
|
||||
/*YCP*/
|
||||
{0x81, 0x3b}, // 0
|
||||
{0x82, 0x3b}, // 0 : uyvy <20>ڰ<EFBFBD>
|
||||
{0x83, 0x4b},
|
||||
{0x84, 0x90},
|
||||
{0x86, 0xf0},
|
||||
{0x87, 0x1d},
|
||||
{0x88, 0x16},
|
||||
{0x8d, 0x74},
|
||||
{0x8e, 0x25},
|
||||
|
||||
/*AEC*/
|
||||
{0x90, 0x36},
|
||||
{0x92, 0x43},
|
||||
{0x9d, 0x32},
|
||||
{0x9e, 0x81},
|
||||
{0x9f, 0xf4},
|
||||
{0xa0, 0xa0},
|
||||
{0xa1, 0x04},
|
||||
{0xa3, 0x2d},
|
||||
{0xa4, 0x01},
|
||||
|
||||
/*AWB*/
|
||||
{0xb0, 0xc2},
|
||||
{0xb1, 0x1e},
|
||||
{0xb2, 0x10},
|
||||
{0xb3, 0x20},
|
||||
{0xb4, 0x2d},
|
||||
{0xb5, 0x1b},
|
||||
{0xb6, 0x2e},
|
||||
{0xb8, 0x13},
|
||||
{0xba, 0x60},
|
||||
{0xbb, 0x62},
|
||||
{0xbd, 0x78},
|
||||
{0xbe, 0x55},
|
||||
{0xbf, 0xa0},
|
||||
{0xc4, 0xe7},
|
||||
{0xc5, 0x15},
|
||||
{0xc6, 0x16},
|
||||
{0xc7, 0xeb},
|
||||
{0xc8, 0xe4},
|
||||
{0xc9, 0x16},
|
||||
{0xca, 0x16},
|
||||
{0xcb, 0xe9},
|
||||
{0x22, 0xf8},
|
||||
|
||||
/*SPI*/
|
||||
{0xfe, 0x02},
|
||||
{0x01, 0x01},
|
||||
{0x02, 0x02},
|
||||
{0x03, 0x20},
|
||||
{0x04, 0x20},
|
||||
{0x0a, 0x00},
|
||||
{0x13, 0x10},
|
||||
{0x24, 0x00},
|
||||
{0x28, 0x03},
|
||||
{0xfe, 0x00},
|
||||
|
||||
/*OUTPUT*/
|
||||
{0xf2, 0x03},
|
||||
{0xfe, 0x00},
|
||||
};
|
||||
|
||||
uint16_t gc6153GetRegCnt(char* regName)
|
||||
{
|
||||
if (strcmp(regName, "gc6153_1sdr") == 0)
|
||||
{
|
||||
return (sizeof(gc6153_1sdrRegInfo) / sizeof(gc6153_1sdrRegInfo[0]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
#include "i2cGpio.h"
|
||||
|
||||
// We only act as I2C master
|
||||
|
||||
typedef enum
|
||||
{
|
||||
INPUT,
|
||||
OUTPUT,
|
||||
}pinDirection_e;
|
||||
|
||||
static void setSdaDirection(pinDirection_e direction)
|
||||
{
|
||||
GpioPinConfig_t config;
|
||||
|
||||
if (direction == INPUT)
|
||||
{
|
||||
config.pinDirection = GPIO_DIRECTION_INPUT;
|
||||
config.misc.interruptConfig = GPIO_INTERRUPT_DISABLED;
|
||||
GPIO_pinConfig(SDA_GPIO_INSTANCE, SDA_GPIO_PIN, &config);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.pinDirection = GPIO_DIRECTION_OUTPUT;
|
||||
//config.initOutput = 0;
|
||||
GPIO_pinConfig(SDA_GPIO_INSTANCE, SDA_GPIO_PIN, &config);
|
||||
}
|
||||
}
|
||||
|
||||
void i2cStart()
|
||||
{
|
||||
I2C_SDA_1;
|
||||
I2C_SCL_1;
|
||||
delay_us(20);
|
||||
I2C_SDA_0;
|
||||
delay_us(19);
|
||||
I2C_SCL_0;
|
||||
}
|
||||
|
||||
void i2cStop()
|
||||
{
|
||||
setSdaDirection(OUTPUT);
|
||||
|
||||
I2C_SDA_0;
|
||||
I2C_SCL_1;
|
||||
delay_us(18);
|
||||
|
||||
I2C_SDA_1;
|
||||
delay_us(18);
|
||||
}
|
||||
|
||||
static uint32_t i2cSdaRead()
|
||||
{
|
||||
return (((((GPIO_TypeDef *) (MP_GPIO_BASE_ADDR + 0x1000*SDA_GPIO_INSTANCE))->DATA) >> SDA_GPIO_PIN) & 0x01);
|
||||
}
|
||||
|
||||
void i2cWritebyte(uint8_t byte)
|
||||
{
|
||||
setSdaDirection(OUTPUT);
|
||||
|
||||
for (uint8_t i=0; i<8; i++)
|
||||
{
|
||||
I2C_SCL_0;
|
||||
delay_us(18);
|
||||
|
||||
// Send data every bit
|
||||
if (byte&0x80)
|
||||
{
|
||||
I2C_SDA_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
I2C_SDA_0;
|
||||
}
|
||||
|
||||
byte <<= 1;
|
||||
|
||||
I2C_SCL_1;
|
||||
delay_us(18);
|
||||
}
|
||||
|
||||
I2C_SCL_0;
|
||||
delay_us(18);
|
||||
I2C_SDA_1;
|
||||
delay_us(18);
|
||||
}
|
||||
|
||||
void i2cAck()
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
setSdaDirection(INPUT);
|
||||
I2C_SCL_1;
|
||||
delay_us(18);
|
||||
|
||||
while ((i2cSdaRead()==1) && (i<255))
|
||||
i++;
|
||||
|
||||
I2C_SCL_0;
|
||||
delay_us(18);
|
||||
|
||||
setSdaDirection(OUTPUT);
|
||||
}
|
||||
|
||||
uint8_t i2cReadByte()
|
||||
{
|
||||
uint8_t i, receveData = 0;
|
||||
|
||||
setSdaDirection(INPUT);
|
||||
delay_us(18);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
I2C_SCL_1;
|
||||
delay_us(18);
|
||||
receveData |= (i2cSdaRead() << (7-i));
|
||||
I2C_SCL_0;
|
||||
delay_us(18);
|
||||
}
|
||||
|
||||
setSdaDirection(OUTPUT);
|
||||
|
||||
return receveData;
|
||||
}
|
||||
|
||||
|
||||
void i2cGpioInit()
|
||||
{
|
||||
PadConfig_t config;
|
||||
|
||||
PAD_getDefaultConfig(&config);
|
||||
|
||||
// scl pin
|
||||
config.mux = SCL_PAD_ALT_FUNC;
|
||||
PAD_setPinConfig(SCL_GPIO_ADDR, &config);
|
||||
|
||||
GpioPinConfig_t gpioCfg;
|
||||
gpioCfg.pinDirection = GPIO_DIRECTION_OUTPUT;
|
||||
gpioCfg.misc.initOutput= 1;
|
||||
GPIO_pinConfig(SCL_GPIO_INSTANCE, SCL_GPIO_PIN, &gpioCfg);
|
||||
|
||||
// sda pin
|
||||
config.mux = SDA_PAD_ALT_FUNC;
|
||||
PAD_setPinConfig(SDA_GPIO_ADDR, &config);
|
||||
|
||||
gpioCfg.pinDirection = GPIO_DIRECTION_OUTPUT;
|
||||
gpioCfg.misc.initOutput= 1;
|
||||
GPIO_pinConfig(SDA_GPIO_INSTANCE, SDA_GPIO_PIN, &gpioCfg);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,349 @@
|
||||
#include "cameraDrv.h"
|
||||
|
||||
camI2cCfg_t sp0821_2sdrRegInfo[] =
|
||||
{
|
||||
{0x30,0x01},
|
||||
{0x32,0x00},
|
||||
{0x03,0x00},
|
||||
{0x04,0x96},
|
||||
{0x24,0x13},
|
||||
{0x9b,0x32},
|
||||
{0xd7,0x00},
|
||||
{0xc5,0xc7},
|
||||
{0xc6,0xe2},
|
||||
{0xe7,0x03},
|
||||
{0x32,0x00},
|
||||
{0x32,0x01},
|
||||
{0x32,0x00},
|
||||
{0xbf,0x0f},
|
||||
{0xba,0x5a},
|
||||
{0xbb,0x69},
|
||||
{0xe7,0x00},
|
||||
{0x32,0x07},
|
||||
{0x31,0x03},
|
||||
{0x19,0x04},
|
||||
{0x2c,0x0f},
|
||||
{0x2e,0x3c},
|
||||
{0x30,0x01},
|
||||
{0x28,0x2e},
|
||||
{0x29,0x1f},
|
||||
{0x0f,0x30},
|
||||
{0x14,0xb0},
|
||||
{0x38,0x50},
|
||||
{0x39,0x52},
|
||||
{0x3a,0x60},
|
||||
{0x3b,0x10},
|
||||
{0x3c,0xe0},
|
||||
{0x85,0x01},
|
||||
{0xe0,0x02},
|
||||
{0xe5,0x60},
|
||||
{0xf5,0x02},
|
||||
{0xf1,0x03},
|
||||
{0xf3,0x40},
|
||||
{0x41,0x00},
|
||||
{0x05,0x00},
|
||||
{0x06,0x00},
|
||||
{0x07,0x00},
|
||||
{0x08,0x00},
|
||||
{0x09,0x00},
|
||||
{0x0a,0x34},
|
||||
{0x0D,0x01},
|
||||
{0xc8,0x10},
|
||||
{0x29,0x1e},
|
||||
{0xa2,0x26},
|
||||
{0xa3,0x02},
|
||||
{0xa4,0x32},
|
||||
{0xa5,0x00},
|
||||
{0xa8,0x32},
|
||||
{0xa9,0x00},
|
||||
{0xaa,0x01},
|
||||
{0xab,0x00},
|
||||
{0x4c,0x80},
|
||||
{0x4d,0x80},
|
||||
{0xa6,0xf0},
|
||||
{0xa7,0x20},
|
||||
{0xac,0xf0},
|
||||
{0xad,0x20},
|
||||
{0x8a,0x3e},
|
||||
{0x8b,0x30},
|
||||
{0x8c,0x2a},
|
||||
{0x8d,0x26},
|
||||
{0x8e,0x26},
|
||||
{0x8f,0x24},
|
||||
{0x90,0x24},
|
||||
{0x91,0x22},
|
||||
{0x92,0x22},
|
||||
{0x93,0x22},
|
||||
{0x94,0x20},
|
||||
{0x95,0x20},
|
||||
{0x96,0x20},
|
||||
{0x17,0x88},
|
||||
{0x18,0x80},
|
||||
{0x4e,0x78},
|
||||
{0x4f,0x78},
|
||||
{0x58,0x8a},
|
||||
{0x59,0xa8},
|
||||
{0x5a,0x80},
|
||||
{0xca,0x00},
|
||||
{0x86,0x08},
|
||||
{0x87,0x0f},
|
||||
{0x88,0x30},
|
||||
{0x89,0x45},
|
||||
{0x9e,0x94},
|
||||
{0x9f,0x88},
|
||||
{0x97,0x84},
|
||||
{0x98,0x88},
|
||||
{0x99,0x74},
|
||||
{0x9a,0x84},
|
||||
{0xa0,0x7c},
|
||||
{0xa1,0x78},
|
||||
{0x9d,0x09},
|
||||
{0xB1,0x04},
|
||||
{0xb3,0x00},
|
||||
{0x47,0x40},
|
||||
{0xb8,0x04},
|
||||
{0xb9,0x28},
|
||||
{0x3f,0x18},
|
||||
{0xc1,0xff},
|
||||
{0xc2,0x40},
|
||||
{0xc3,0xff},
|
||||
{0xc4,0x40},
|
||||
{0xc5,0xc7},
|
||||
{0xc6,0xe2},
|
||||
{0xc7,0xef},
|
||||
{0xc8,0x10},
|
||||
{0x50,0x2a},
|
||||
{0x51,0x2a},
|
||||
{0x52,0x2f},
|
||||
{0x53,0xcf},
|
||||
{0x54,0xd0},
|
||||
{0x5c,0x1e},
|
||||
{0x5d,0x21},
|
||||
{0x5e,0x1a},
|
||||
{0x5f,0xe9},
|
||||
{0x60,0x98},
|
||||
{0xcb,0x3f},
|
||||
{0xcc,0x3f},
|
||||
{0xcd,0x3f},
|
||||
{0xce,0x85},
|
||||
{0xcf,0xff},
|
||||
{0x79,0x5a},
|
||||
{0x7a,0xDC},
|
||||
{0x7b,0x0A},
|
||||
{0x7c,0xFD},
|
||||
{0x7d,0x46},
|
||||
{0x7e,0xFD},
|
||||
{0x7f,0xFD},
|
||||
{0x80,0xEF},
|
||||
{0x81,0x54},
|
||||
{0x1b,0x0a},
|
||||
{0x1c,0x0f},
|
||||
{0x1d,0x15},
|
||||
{0x1e,0x15},
|
||||
{0x1f,0x15},
|
||||
{0x20,0x1f},
|
||||
{0x21,0x2a},
|
||||
{0x22,0x2a},
|
||||
{0x56,0x49},
|
||||
{0x1a,0x14},
|
||||
{0x34,0x1f},
|
||||
{0x82,0x10},
|
||||
{0x83,0x00},
|
||||
{0x84,0xff},
|
||||
{0xd7,0x50},
|
||||
{0xd8,0x1a},
|
||||
{0xd9,0x20},
|
||||
{0xc9,0x1f},
|
||||
{0xbf,0x33},
|
||||
{0xba,0x37},
|
||||
{0xbb,0x38},
|
||||
|
||||
{0x19,0x04},
|
||||
{0x34,0x1f},
|
||||
{0x30,0x01},
|
||||
{0x2e,0x2c},//0x29
|
||||
{0x2c,0x0f},
|
||||
|
||||
};
|
||||
|
||||
camI2cCfg_t sp0821_1sdrRegInfo[] =
|
||||
{
|
||||
{0x30,0x01},
|
||||
{0x32,0x00},
|
||||
{0x03,0x00},
|
||||
{0x04,0x96},
|
||||
{0x24,0x13},
|
||||
{0x9b,0x32},
|
||||
{0xd7,0x00},
|
||||
{0xc5,0xc7},
|
||||
{0xc6,0xe2},
|
||||
{0xe7,0x03},
|
||||
{0x32,0x00},
|
||||
{0x32,0x01},
|
||||
{0x32,0x00},
|
||||
{0xbf,0x0f},
|
||||
{0xba,0x5a},
|
||||
{0xbb,0x69},
|
||||
{0xe7,0x00},
|
||||
{0x32,0x07},
|
||||
{0x31,0x03},
|
||||
{0x19,0x04},
|
||||
{0x2c,0x0f},
|
||||
{0x2e,0x3c},
|
||||
{0x30,0x01},
|
||||
{0x28,0x2e},
|
||||
{0x29,0x1f},
|
||||
{0x0f,0x30},
|
||||
{0x14,0xb0},
|
||||
{0x38,0x50},
|
||||
{0x39,0x52},
|
||||
{0x3a,0x60},
|
||||
{0x3b,0x10},
|
||||
{0x3c,0xe0},
|
||||
{0x85,0x01},
|
||||
{0xe0,0x02},
|
||||
{0xe5,0x60},
|
||||
{0xf5,0x02},
|
||||
{0xf1,0x03},
|
||||
{0xf3,0x40},
|
||||
{0x41,0x00},
|
||||
{0x05,0x00},
|
||||
{0x06,0x00},
|
||||
{0x07,0x00},
|
||||
{0x08,0x00},
|
||||
{0x09,0x00},
|
||||
{0x0a,0x34},
|
||||
{0x0D,0x01},
|
||||
{0xc8,0x10},
|
||||
{0x29,0x1e},
|
||||
{0xa2,0x26},
|
||||
{0xa3,0x02},
|
||||
{0xa4,0x32},
|
||||
{0xa5,0x00},
|
||||
{0xa8,0x32},
|
||||
{0xa9,0x00},
|
||||
{0xaa,0x01},
|
||||
{0xab,0x00},
|
||||
{0x4c,0x80},
|
||||
{0x4d,0x80},
|
||||
{0xa6,0xf0},
|
||||
{0xa7,0x20},
|
||||
{0xac,0xf0},
|
||||
{0xad,0x20},
|
||||
{0x8a,0x3e},
|
||||
{0x8b,0x30},
|
||||
{0x8c,0x2a},
|
||||
{0x8d,0x26},
|
||||
{0x8e,0x26},
|
||||
{0x8f,0x24},
|
||||
{0x90,0x24},
|
||||
{0x91,0x22},
|
||||
{0x92,0x22},
|
||||
{0x93,0x22},
|
||||
{0x94,0x20},
|
||||
{0x95,0x20},
|
||||
{0x96,0x20},
|
||||
{0x17,0x88},
|
||||
{0x18,0x80},
|
||||
{0x4e,0x78},
|
||||
{0x4f,0x78},
|
||||
{0x58,0x8a},
|
||||
{0x59,0xa8},
|
||||
{0x5a,0x80},
|
||||
{0xca,0x00},
|
||||
{0x86,0x08},
|
||||
{0x87,0x0f},
|
||||
{0x88,0x30},
|
||||
{0x89,0x45},
|
||||
{0x9e,0x94},
|
||||
{0x9f,0x88},
|
||||
{0x97,0x84},
|
||||
{0x98,0x88},
|
||||
{0x99,0x74},
|
||||
{0x9a,0x84},
|
||||
{0xa0,0x7c},
|
||||
{0xa1,0x78},
|
||||
{0x9d,0x09},
|
||||
{0xB1,0x04},
|
||||
{0xb3,0x00},
|
||||
{0x47,0x40},
|
||||
{0xb8,0x04},
|
||||
{0xb9,0x28},
|
||||
{0x3f,0x18},
|
||||
{0xc1,0xff},
|
||||
{0xc2,0x40},
|
||||
{0xc3,0xff},
|
||||
{0xc4,0x40},
|
||||
{0xc5,0xc7},
|
||||
{0xc6,0xe2},
|
||||
{0xc7,0xef},
|
||||
{0xc8,0x10},
|
||||
{0x50,0x2a},
|
||||
{0x51,0x2a},
|
||||
{0x52,0x2f},
|
||||
{0x53,0xcf},
|
||||
{0x54,0xd0},
|
||||
{0x5c,0x1e},
|
||||
{0x5d,0x21},
|
||||
{0x5e,0x1a},
|
||||
{0x5f,0xe9},
|
||||
{0x60,0x98},
|
||||
{0xcb,0x3f},
|
||||
{0xcc,0x3f},
|
||||
{0xcd,0x3f},
|
||||
{0xce,0x85},
|
||||
{0xcf,0xff},
|
||||
{0x79,0x5a},
|
||||
{0x7a,0xDC},
|
||||
{0x7b,0x0A},
|
||||
{0x7c,0xFD},
|
||||
{0x7d,0x46},
|
||||
{0x7e,0xFD},
|
||||
{0x7f,0xFD},
|
||||
{0x80,0xEF},
|
||||
{0x81,0x54},
|
||||
{0x1b,0x0a},
|
||||
{0x1c,0x0f},
|
||||
{0x1d,0x15},
|
||||
{0x1e,0x15},
|
||||
{0x1f,0x15},
|
||||
{0x20,0x1f},
|
||||
{0x21,0x2a},
|
||||
{0x22,0x2a},
|
||||
{0x56,0x49},
|
||||
{0x1a,0x14},
|
||||
{0x34,0x1f},
|
||||
{0x82,0x10},
|
||||
{0x83,0x00},
|
||||
{0x84,0xff},
|
||||
{0xd7,0x50},
|
||||
{0xd8,0x1a},
|
||||
{0xd9,0x20},
|
||||
{0xc9,0x1f},
|
||||
{0xbf,0x33},
|
||||
{0xba,0x37},
|
||||
{0xbb,0x38},
|
||||
|
||||
{0x19,0x04},
|
||||
{0x34,0x1f},
|
||||
{0x30,0x01},
|
||||
{0x2e,0x2c},//0x29
|
||||
{0x2c,0x0f},
|
||||
|
||||
};
|
||||
|
||||
uint16_t sp0821GetRegCnt(char* regName)
|
||||
{
|
||||
if (strcmp(regName, "sp0821_2sdr") == 0)
|
||||
{
|
||||
return (sizeof(sp0821_2sdrRegInfo) / sizeof(sp0821_2sdrRegInfo[0]));
|
||||
}
|
||||
else if (strcmp(regName, "sp0821_1sdr") == 0)
|
||||
{
|
||||
return (sizeof(sp0821_1sdrRegInfo) / sizeof(sp0821_1sdrRegInfo[0]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,740 @@
|
||||
#include "cameraDrv.h"
|
||||
|
||||
camI2cCfg_t sp0A39_2sdrRegInfo[] =
|
||||
{
|
||||
{0xfd,0x00},
|
||||
{0x1d,0x25},
|
||||
{0x31,0x04},
|
||||
{0x32,0x01},
|
||||
{0x30,0x01},
|
||||
{0xfd,0x01},
|
||||
{0x5d,0x01},
|
||||
{0x34,0xe3},
|
||||
{0x35,0x10},
|
||||
{0xfd,0x00},
|
||||
{0xf0,0xff},
|
||||
{0xf1,0xff},
|
||||
{0xf2,0xff},
|
||||
{0xf3,0xff},
|
||||
{0xfc,0x50},
|
||||
{0xfd,0x00},
|
||||
{0x03,0x00},
|
||||
{0x04,0xf0},
|
||||
{0x24,0x10},
|
||||
{0xef,0x40},
|
||||
{0x06,0x00},
|
||||
{0x09,0x00},
|
||||
{0x0a,0x46},
|
||||
{0x10,0x07},
|
||||
{0x11,0x04},
|
||||
{0x16,0x01},
|
||||
{0x19,0x22},
|
||||
{0x1e,0x58},
|
||||
{0x29,0x48},
|
||||
{0x13,0x37},
|
||||
{0x14,0x01},
|
||||
{0x25,0x01},
|
||||
{0x2a,0x06},
|
||||
{0x27,0x01},
|
||||
{0x54,0x00},
|
||||
{0x55,0x10},
|
||||
{0x58,0x38},
|
||||
{0x5d,0x12},
|
||||
{0x63,0x00},
|
||||
{0x64,0x00},
|
||||
{0x66,0x28},
|
||||
{0x68,0x2a},
|
||||
{0x72,0x3a},
|
||||
{0x73,0x0a},
|
||||
{0x75,0x48},
|
||||
{0x76,0x0a},
|
||||
{0x1f,0x77},
|
||||
{0x20,0x07},
|
||||
{0xfb,0x16},
|
||||
{0xfd,0x01},
|
||||
{0xf2,0x69},
|
||||
{0xf7,0x28},
|
||||
{0x02,0x10},
|
||||
{0x03,0x01},
|
||||
{0x06,0x28},
|
||||
{0x08,0x01},
|
||||
{0xfd,0x02},
|
||||
{0xb8,0x50},
|
||||
{0xb9,0xff},
|
||||
{0xba,0x40},
|
||||
{0xbb,0x45},
|
||||
{0xbc,0xc0},
|
||||
{0xbd,0x50},
|
||||
{0xbe,0x80},
|
||||
{0xbf,0x02},
|
||||
{0xd0,0x80},
|
||||
{0xd1,0x02},
|
||||
{0xfd,0x01},
|
||||
{0xc0,0x1f},
|
||||
{0xc1,0x18},
|
||||
{0xc2,0x15},
|
||||
{0xc3,0x13},
|
||||
{0xc4,0x13},
|
||||
{0xc5,0x12},
|
||||
{0xc6,0x12},
|
||||
{0xc7,0x11},
|
||||
{0xc8,0x11},
|
||||
{0xc9,0x11},
|
||||
{0xca,0x10},
|
||||
{0xf3,0x10},
|
||||
{0xf4,0x10},
|
||||
{0xfd,0x01},
|
||||
{0x04,0xff},
|
||||
{0x05,0x10},
|
||||
{0x0a,0x30},
|
||||
{0x0b,0x10},
|
||||
{0xfd,0x01},
|
||||
{0xcb,0x38},
|
||||
{0xcc,0x35},
|
||||
{0xcd,0x03},
|
||||
{0xce,0x05},
|
||||
{0xfd,0x00},
|
||||
{0xfb,0x16},
|
||||
{0x35,0xaa},
|
||||
{0xfd,0x01},
|
||||
{0x1e,0x00},
|
||||
{0x20,0x00},
|
||||
{0x84,0x25},
|
||||
{0x85,0x25},
|
||||
{0x86,0x1f},
|
||||
{0x87,0x23},
|
||||
{0x88,0x1c},
|
||||
{0x89,0x20},
|
||||
{0x8a,0x1a},
|
||||
{0x8b,0x15},
|
||||
{0x8c,0x15},
|
||||
{0x8d,0x1a},
|
||||
{0x8e,0x0a},
|
||||
{0x8f,0x13},
|
||||
{0x90,0x13},
|
||||
{0x91,0x00},
|
||||
{0x92,0x0a},
|
||||
{0x93,0x08},
|
||||
{0x94,0x12},
|
||||
{0x95,0x00},
|
||||
{0x96,0x0a},
|
||||
{0x97,0x08},
|
||||
{0x98,0x15},
|
||||
{0x99,0x00},
|
||||
{0x9a,0x0a},
|
||||
{0x9b,0x05},
|
||||
{0xe8,0x20},
|
||||
{0xe9,0x0f},
|
||||
{0xea,0x00},
|
||||
{0xfd,0x01},
|
||||
{0xa4,0x00},
|
||||
{0x0e,0x80},
|
||||
{0x18,0x80},
|
||||
{0x0f,0x20},
|
||||
{0x10,0x90},
|
||||
{0x11,0x80},
|
||||
{0x12,0x80},
|
||||
{0x13,0xa0},
|
||||
{0x14,0x80},
|
||||
{0x15,0x90},
|
||||
{0x16,0x85},
|
||||
{0x17,0x85},
|
||||
{0x6e,0x00},
|
||||
{0x6f,0x03},
|
||||
{0x70,0x07},
|
||||
{0x71,0x0d},
|
||||
{0x72,0x17},
|
||||
{0x73,0x29},
|
||||
{0x74,0x3d},
|
||||
{0x75,0x4f},
|
||||
{0x76,0x5f},
|
||||
{0x77,0x79},
|
||||
{0x78,0x8c},
|
||||
{0x79,0x9d},
|
||||
{0x7a,0xa9},
|
||||
{0x7b,0xb3},
|
||||
{0x7c,0xbe},
|
||||
{0x7d,0xc7},
|
||||
{0x7e,0xd0},
|
||||
{0x7f,0xd6},
|
||||
{0x80,0xde},
|
||||
{0x81,0xe4},
|
||||
{0x82,0xe9},
|
||||
{0x83,0xee},
|
||||
{0xfd,0x02},
|
||||
{0x09,0x06},
|
||||
{0x0d,0x1a},
|
||||
{0x1c,0x09},
|
||||
{0x1d,0x03},
|
||||
{0x1e,0x10},
|
||||
{0x1f,0x06},
|
||||
{0xfd,0x01},
|
||||
{0x32,0x00},
|
||||
{0xfd,0x02},
|
||||
{0x26,0xcb},
|
||||
{0x27,0xc2},
|
||||
{0x10,0x00},
|
||||
{0x11,0x00},
|
||||
{0x18,0x17},
|
||||
{0x19,0x36},
|
||||
{0x2a,0x01},
|
||||
{0x2b,0x10},
|
||||
{0x28,0xf8},
|
||||
{0x29,0x08},
|
||||
{0x66,0x5F},
|
||||
{0x67,0x7f},
|
||||
{0x68,0xE0},
|
||||
{0x69,0x10},
|
||||
{0x69,0x10},
|
||||
{0x6a,0xa6},
|
||||
{0x7c,0x4A},
|
||||
{0x7d,0x80},
|
||||
{0x7e,0x00},
|
||||
{0x7f,0x30},
|
||||
{0x80,0xaa},
|
||||
{0x70,0x32},
|
||||
{0x71,0x60},
|
||||
{0x72,0x30},
|
||||
{0x73,0x5a},
|
||||
{0x74,0xaa},
|
||||
{0x6b,0xff},
|
||||
{0x6c,0x50},
|
||||
{0x6d,0x40},
|
||||
{0x6e,0x60},
|
||||
{0x6f,0x6a},
|
||||
{0x61,0xff},
|
||||
{0x62,0x27},
|
||||
{0x63,0x51},
|
||||
{0x64,0x7f},
|
||||
{0x65,0x6a},
|
||||
{0x75,0x80},
|
||||
{0x76,0x09},
|
||||
{0x77,0x02},
|
||||
{0x0e,0x12},
|
||||
{0x3b,0x09},
|
||||
{0x48,0xea},
|
||||
{0x49,0xfc},
|
||||
{0x4a,0x05},
|
||||
{0x02,0x00},
|
||||
{0x03,0x88},
|
||||
{0xf5,0xfe},
|
||||
{0x22,0xfe},
|
||||
{0x20,0xfe},
|
||||
{0xf7,0xfe},
|
||||
{0xfd,0x02},
|
||||
{0xde,0x0f},
|
||||
{0xcf,0x0a},
|
||||
{0xd7,0x0a},
|
||||
{0xd8,0x12},
|
||||
{0xd9,0x14},
|
||||
{0xda,0x1a},
|
||||
{0xdc,0x07},
|
||||
{0xe8,0x60},
|
||||
{0xe9,0x40},
|
||||
{0xea,0x40},
|
||||
{0xeb,0x30},
|
||||
{0xec,0x60},
|
||||
{0xed,0x50},
|
||||
{0xee,0x40},
|
||||
{0xef,0x30},
|
||||
{0xd3,0x30},
|
||||
{0xd4,0xc0},
|
||||
{0xd5,0x50},
|
||||
{0xd6,0x0b},
|
||||
{0xf0,0x7f},
|
||||
{0xfd,0x01},
|
||||
{0xb1,0xf0},
|
||||
{0xfd,0x02},
|
||||
{0xdc,0x07},
|
||||
{0x05,0x08},
|
||||
{0xfd,0x01},
|
||||
{0x26,0x33},
|
||||
{0x27,0x99},
|
||||
{0x62,0xf0},
|
||||
{0x63,0x80},
|
||||
{0x64,0x80},
|
||||
{0x65,0x20},
|
||||
{0xfd,0x02},
|
||||
{0xdd,0xff},
|
||||
{0xfd,0x01},
|
||||
{0xa8,0x00},
|
||||
{0xa9,0x09},
|
||||
{0xaa,0x09},
|
||||
{0xab,0x0c},
|
||||
{0xd3,0x00},
|
||||
{0xd4,0x09},
|
||||
{0xd5,0x09},
|
||||
{0xd6,0x0c},
|
||||
{0xcf,0xff},
|
||||
{0xd0,0xf0},
|
||||
{0xd1,0x80},
|
||||
{0xd2,0x80},
|
||||
{0xdf,0xff},
|
||||
{0xe0,0xf0},
|
||||
{0xe1,0xd0},
|
||||
{0xe2,0x80},
|
||||
{0xe3,0xff},
|
||||
{0xe4,0xf0},
|
||||
{0xe5,0xd0},
|
||||
{0xe6,0x80},
|
||||
{0xfd,0x02},
|
||||
{0x15,0xe0},
|
||||
{0x16,0x95},
|
||||
{0xa0,0x9b},
|
||||
{0xa1,0xe4},
|
||||
{0xa2,0x01},
|
||||
{0xa3,0xf2},
|
||||
{0xa4,0x8f},
|
||||
{0xa5,0xff},
|
||||
{0xa6,0x01},
|
||||
{0xa7,0xdb},
|
||||
{0xa8,0xa4},
|
||||
{0xac,0x80},
|
||||
{0xad,0x21},
|
||||
{0xae,0xdf},
|
||||
{0xaf,0xf2},
|
||||
{0xb0,0xa0},
|
||||
{0xb1,0xee},
|
||||
{0xb2,0xea},
|
||||
{0xb3,0xd9},
|
||||
{0xb4,0xbd},
|
||||
{0xfd,0x01},
|
||||
{0xb3,0xb0},
|
||||
{0xb4,0x90},
|
||||
{0xb5,0x70},
|
||||
{0xb6,0x55},
|
||||
{0xb7,0xb0},
|
||||
{0xb8,0x90},
|
||||
{0xb9,0x70},
|
||||
{0xba,0x55},
|
||||
{0xfd,0x01},
|
||||
{0xbf,0xff},
|
||||
{0x00,0x00},
|
||||
{0xfd,0x01},
|
||||
{0xa4,0x00},
|
||||
{0xa5,0x1f},
|
||||
{0xa6,0x50},
|
||||
{0xa7,0x65},
|
||||
{0xfd,0x02},
|
||||
{0x30,0x38},
|
||||
{0x31,0x40},
|
||||
{0x32,0x40},
|
||||
{0x33,0xd0},
|
||||
{0x34,0x10},
|
||||
{0x35,0x60},
|
||||
{0x36,0x28},
|
||||
{0x37,0x07},
|
||||
{0x38,0x08},
|
||||
{0xe6,0x8F},
|
||||
{0xfd,0x01},
|
||||
{0x1b,0x15},
|
||||
{0x1c,0x1A},
|
||||
{0x1d,0x0c},
|
||||
{0xfd,0x01},
|
||||
{0x32,0x15},
|
||||
{0x33,0xef},
|
||||
{0x36,0x10},
|
||||
{0xf6,0xb0},
|
||||
{0xf5,0x10},
|
||||
{0xd7,0x3a},
|
||||
{0xd8,0x10},
|
||||
{0xd9,0x20},
|
||||
{0xda,0x10},
|
||||
{0xdb,0x7a},
|
||||
{0xdc,0x3a},
|
||||
{0xdd,0x30},
|
||||
{0xde,0x30},
|
||||
{0xe7,0x3a},
|
||||
{0x9c,0xaa},
|
||||
{0x9d,0xaa},
|
||||
{0x9e,0x55},
|
||||
{0x9f,0x55},
|
||||
{0xfd,0x00},
|
||||
{0x1c,0x00},
|
||||
{0xfd,0x00},
|
||||
|
||||
{0xfd,0x00},
|
||||
{0x30,0x0b},
|
||||
{0x1c,0xdc},
|
||||
{0x2c,0x1d}, // LSB
|
||||
{0x2e,0xe1},
|
||||
|
||||
|
||||
};
|
||||
|
||||
camI2cCfg_t sp0A39_1sdrRegInfo[] =
|
||||
{
|
||||
{0xfd,0x00},
|
||||
{0x1d,0x25},
|
||||
{0x31,0x04},
|
||||
{0x32,0x01},
|
||||
{0x30,0x01},
|
||||
{0xfd,0x01},
|
||||
{0x5d,0x01},
|
||||
{0x34,0xe3},
|
||||
{0x35,0x10},
|
||||
{0xfd,0x00},
|
||||
{0xf0,0xff},
|
||||
{0xf1,0xff},
|
||||
{0xf2,0xff},
|
||||
{0xf3,0xff},
|
||||
{0xfc,0x50},
|
||||
{0xfd,0x00},
|
||||
{0x03,0x03},
|
||||
{0x04,0x6c},
|
||||
{0x24,0x10},
|
||||
{0xef,0x40},
|
||||
{0x06,0x00},
|
||||
{0x09,0x00},
|
||||
{0x0a,0x80},
|
||||
{0x10,0x07},
|
||||
{0x11,0x04},
|
||||
{0x16,0x01},
|
||||
{0x19,0x22},
|
||||
{0x1e,0x58},
|
||||
{0x29,0x48},
|
||||
{0x13,0x37},
|
||||
{0x14,0x01},
|
||||
{0x25,0x01},
|
||||
{0x2a,0x06},
|
||||
{0x27,0x01},
|
||||
{0x54,0x00},
|
||||
{0x55,0x10},
|
||||
{0x58,0x38},
|
||||
{0x5d,0x12},
|
||||
{0x63,0x00},
|
||||
{0x64,0x00},
|
||||
{0x66,0x28},
|
||||
{0x68,0x2a},
|
||||
{0x72,0x3a},
|
||||
{0x73,0x0a},
|
||||
{0x75,0x48},
|
||||
{0x76,0x0a},
|
||||
{0x1f,0x77},
|
||||
{0x20,0x07},
|
||||
{0xfb,0x16},
|
||||
{0xfd,0x01},
|
||||
{0xf2,0x69},
|
||||
{0xf7,0x97},
|
||||
{0x02,0x08},
|
||||
{0x03,0x01},
|
||||
{0x06,0x8a},
|
||||
{0x08,0x01},
|
||||
{0xfd,0x02},
|
||||
{0xb8,0x50},
|
||||
{0xb9,0xff},
|
||||
{0xba,0x40},
|
||||
{0xbb,0x45},
|
||||
{0xbc,0xc0},
|
||||
{0xbd,0x50},
|
||||
{0xbe,0xb8},
|
||||
{0xbf,0x04},
|
||||
{0xd0,0xb8},
|
||||
{0xd1,0x04},
|
||||
{0xfd,0x01},
|
||||
{0xc0,0x1f},
|
||||
{0xc1,0x18},
|
||||
{0xc2,0x15},
|
||||
{0xc3,0x13},
|
||||
{0xc4,0x13},
|
||||
{0xc5,0x12},
|
||||
{0xc6,0x12},
|
||||
{0xc7,0x11},
|
||||
{0xc8,0x11},
|
||||
{0xc9,0x11},
|
||||
{0xca,0x10},
|
||||
{0xf3,0x10},
|
||||
{0xf4,0x10},
|
||||
{0xfd,0x01},
|
||||
{0x04,0xff},
|
||||
{0x05,0x10},
|
||||
{0x0a,0x30},
|
||||
{0x0b,0x10},
|
||||
{0xfd,0x01},
|
||||
{0xcb,0x38},
|
||||
{0xcc,0x35},
|
||||
{0xcd,0x03},
|
||||
{0xce,0x05},
|
||||
{0xfd,0x00},
|
||||
{0xfb,0x16},
|
||||
{0x35,0xaa},
|
||||
{0xfd,0x01},
|
||||
{0x1e,0x00},
|
||||
{0x20,0x00},
|
||||
{0x84,0x25},
|
||||
{0x85,0x25},
|
||||
{0x86,0x1f},
|
||||
{0x87,0x23},
|
||||
{0x88,0x1c},
|
||||
{0x89,0x20},
|
||||
{0x8a,0x1a},
|
||||
{0x8b,0x15},
|
||||
{0x8c,0x15},
|
||||
{0x8d,0x1a},
|
||||
{0x8e,0x0a},
|
||||
{0x8f,0x13},
|
||||
{0x90,0x13},
|
||||
{0x91,0x00},
|
||||
{0x92,0x0a},
|
||||
{0x93,0x08},
|
||||
{0x94,0x12},
|
||||
{0x95,0x00},
|
||||
{0x96,0x0a},
|
||||
{0x97,0x08},
|
||||
{0x98,0x15},
|
||||
{0x99,0x00},
|
||||
{0x9a,0x0a},
|
||||
{0x9b,0x05},
|
||||
{0xe8,0x20},
|
||||
{0xe9,0x0f},
|
||||
{0xea,0x00},
|
||||
{0xfd,0x01},
|
||||
{0xa4,0x00},
|
||||
{0x0e,0x80},
|
||||
{0x18,0x80},
|
||||
{0x0f,0x20},
|
||||
{0x10,0x90},
|
||||
{0x11,0x80},
|
||||
{0x12,0x80},
|
||||
{0x13,0xa0},
|
||||
{0x14,0x80},
|
||||
{0x15,0x90},
|
||||
{0x16,0x85},
|
||||
{0x17,0x85},
|
||||
{0x6e,0x00},
|
||||
{0x6f,0x03},
|
||||
{0x70,0x07},
|
||||
{0x71,0x0d},
|
||||
{0x72,0x17},
|
||||
{0x73,0x29},
|
||||
{0x74,0x3d},
|
||||
{0x75,0x4f},
|
||||
{0x76,0x5f},
|
||||
{0x77,0x79},
|
||||
{0x78,0x8c},
|
||||
{0x79,0x9d},
|
||||
{0x7a,0xa9},
|
||||
{0x7b,0xb3},
|
||||
{0x7c,0xbe},
|
||||
{0x7d,0xc7},
|
||||
{0x7e,0xd0},
|
||||
{0x7f,0xd6},
|
||||
{0x80,0xde},
|
||||
{0x81,0xe4},
|
||||
{0x82,0xe9},
|
||||
{0x83,0xee},
|
||||
{0xfd,0x02},
|
||||
{0x09,0x06},
|
||||
{0x0d,0x1a},
|
||||
{0x1c,0x09},
|
||||
{0x1d,0x03},
|
||||
{0x1e,0x10},
|
||||
{0x1f,0x06},
|
||||
{0xfd,0x01},
|
||||
{0x32,0x00},
|
||||
{0xfd,0x02},
|
||||
{0x26,0xcb},
|
||||
{0x27,0xc2},
|
||||
{0x10,0x00},
|
||||
{0x11,0x00},
|
||||
{0x18,0x17},
|
||||
{0x19,0x36},
|
||||
{0x2a,0x01},
|
||||
{0x2b,0x10},
|
||||
{0x28,0xf8},
|
||||
{0x29,0x08},
|
||||
{0x66,0x5F},
|
||||
{0x67,0x7f},
|
||||
{0x68,0xE0},
|
||||
{0x69,0x10},
|
||||
{0x69,0x10},
|
||||
{0x6a,0xa6},
|
||||
{0x7c,0x4A},
|
||||
{0x7d,0x80},
|
||||
{0x7e,0x00},
|
||||
{0x7f,0x30},
|
||||
{0x80,0xaa},
|
||||
{0x70,0x32},
|
||||
{0x71,0x60},
|
||||
{0x72,0x30},
|
||||
{0x73,0x5a},
|
||||
{0x74,0xaa},
|
||||
{0x6b,0xff},
|
||||
{0x6c,0x50},
|
||||
{0x6d,0x40},
|
||||
{0x6e,0x60},
|
||||
{0x6f,0x6a},
|
||||
{0x61,0xff},
|
||||
{0x62,0x27},
|
||||
{0x63,0x51},
|
||||
{0x64,0x7f},
|
||||
{0x65,0x6a},
|
||||
{0x75,0x80},
|
||||
{0x76,0x09},
|
||||
{0x77,0x02},
|
||||
{0x0e,0x12},
|
||||
{0x3b,0x09},
|
||||
{0x48,0xea},
|
||||
{0x49,0xfc},
|
||||
{0x4a,0x05},
|
||||
{0x02,0x00},
|
||||
{0x03,0x88},
|
||||
{0xf5,0xfe},
|
||||
{0x22,0xfe},
|
||||
{0x20,0xfe},
|
||||
{0xf7,0xfe},
|
||||
{0xfd,0x02},
|
||||
{0xde,0x0f},
|
||||
{0xcf,0x0a},
|
||||
{0xd7,0x0a},
|
||||
{0xd8,0x12},
|
||||
{0xd9,0x14},
|
||||
{0xda,0x1a},
|
||||
{0xdc,0x07},
|
||||
{0xe8,0x60},
|
||||
{0xe9,0x40},
|
||||
{0xea,0x40},
|
||||
{0xeb,0x30},
|
||||
{0xec,0x60},
|
||||
{0xed,0x50},
|
||||
{0xee,0x40},
|
||||
{0xef,0x30},
|
||||
{0xd3,0x30},
|
||||
{0xd4,0xc0},
|
||||
{0xd5,0x50},
|
||||
{0xd6,0x0b},
|
||||
{0xf0,0x7f},
|
||||
{0xfd,0x01},
|
||||
{0xb1,0xf0},
|
||||
{0xfd,0x02},
|
||||
{0xdc,0x07},
|
||||
{0x05,0x08},
|
||||
{0xfd,0x01},
|
||||
{0x26,0x33},
|
||||
{0x27,0x99},
|
||||
{0x62,0xf0},
|
||||
{0x63,0x80},
|
||||
{0x64,0x80},
|
||||
{0x65,0x20},
|
||||
{0xfd,0x02},
|
||||
{0xdd,0xff},
|
||||
{0xfd,0x01},
|
||||
{0xa8,0x00},
|
||||
{0xa9,0x09},
|
||||
{0xaa,0x09},
|
||||
{0xab,0x0c},
|
||||
{0xd3,0x00},
|
||||
{0xd4,0x09},
|
||||
{0xd5,0x09},
|
||||
{0xd6,0x0c},
|
||||
{0xcf,0xff},
|
||||
{0xd0,0xf0},
|
||||
{0xd1,0x80},
|
||||
{0xd2,0x80},
|
||||
{0xdf,0xff},
|
||||
{0xe0,0xf0},
|
||||
{0xe1,0xd0},
|
||||
{0xe2,0x80},
|
||||
{0xe3,0xff},
|
||||
{0xe4,0xf0},
|
||||
{0xe5,0xd0},
|
||||
{0xe6,0x80},
|
||||
{0xfd,0x02},
|
||||
{0x15,0xe0},
|
||||
{0x16,0x95},
|
||||
{0xa0,0x9b},
|
||||
{0xa1,0xe4},
|
||||
{0xa2,0x01},
|
||||
{0xa3,0xf2},
|
||||
{0xa4,0x8f},
|
||||
{0xa5,0xff},
|
||||
{0xa6,0x01},
|
||||
{0xa7,0xdb},
|
||||
{0xa8,0xa4},
|
||||
{0xac,0x80},
|
||||
{0xad,0x21},
|
||||
{0xae,0xdf},
|
||||
{0xaf,0xf2},
|
||||
{0xb0,0xa0},
|
||||
{0xb1,0xee},
|
||||
{0xb2,0xea},
|
||||
{0xb3,0xd9},
|
||||
{0xb4,0xbd},
|
||||
{0xfd,0x01},
|
||||
{0xb3,0xb0},
|
||||
{0xb4,0x90},
|
||||
{0xb5,0x70},
|
||||
{0xb6,0x55},
|
||||
{0xb7,0xb0},
|
||||
{0xb8,0x90},
|
||||
{0xb9,0x70},
|
||||
{0xba,0x55},
|
||||
{0xfd,0x01},
|
||||
{0xbf,0xff},
|
||||
{0x00,0x00},
|
||||
{0xfd,0x01},
|
||||
{0xa4,0x00},
|
||||
{0xa5,0x1f},
|
||||
{0xa6,0x50},
|
||||
{0xa7,0x65},
|
||||
{0xfd,0x02},
|
||||
{0x30,0x38},
|
||||
{0x31,0x40},
|
||||
{0x32,0x40},
|
||||
{0x33,0xd0},
|
||||
{0x34,0x10},
|
||||
{0x35,0x60},
|
||||
{0x36,0x28},
|
||||
{0x37,0x07},
|
||||
{0x38,0x08},
|
||||
{0xe6,0x8F},
|
||||
{0xfd,0x01},
|
||||
{0x1b,0x15},
|
||||
{0x1c,0x1A},
|
||||
{0x1d,0x0c},
|
||||
{0xfd,0x01},
|
||||
{0x32,0x15},
|
||||
{0x33,0xef},
|
||||
{0x36,0x10},
|
||||
{0xf6,0xb0},
|
||||
{0xf5,0x10},
|
||||
{0xd7,0x3a},
|
||||
{0xd8,0x10},
|
||||
{0xd9,0x20},
|
||||
{0xda,0x10},
|
||||
{0xdb,0x7a},
|
||||
{0xdc,0x3a},
|
||||
{0xdd,0x30},
|
||||
{0xde,0x30},
|
||||
{0xe7,0x3a},
|
||||
{0x9c,0xaa},
|
||||
{0x9d,0xaa},
|
||||
{0x9e,0x55},
|
||||
{0x9f,0x55},
|
||||
{0xfd,0x00},
|
||||
{0x1c,0x00},
|
||||
{0xfd,0x00},
|
||||
|
||||
{0xfd,0x00},
|
||||
{0x30,0x0c},
|
||||
{0x1c,0xde},
|
||||
{0x2c,0x1d}, //LSB
|
||||
//{0x2c,0x15}, //MSB
|
||||
{0x2e,0xf0},
|
||||
|
||||
};
|
||||
|
||||
uint16_t sp0a39GetRegCnt(char* regName)
|
||||
{
|
||||
if (strcmp(regName, "sp0a39_2sdr") == 0)
|
||||
{
|
||||
return (sizeof(sp0A39_2sdrRegInfo) / sizeof(sp0A39_2sdrRegInfo[0]));
|
||||
}
|
||||
else if (strcmp(regName, "sp0a39_1sdr") == 0)
|
||||
{
|
||||
return (sizeof(sp0A39_1sdrRegInfo) / sizeof(sp0A39_1sdrRegInfo[0]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,315 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2020-, Copyrigths of AirM2M Ltd.
|
||||
* File name: eepRom.c
|
||||
* Description: EC618 eepRom ds2431 driver source file
|
||||
* History: Rev1.0 2020-12-17
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
#include "eepRom.h"
|
||||
#include "oneWire.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
|
||||
extern void delay_us(uint32_t us);
|
||||
|
||||
static uint16_t crc16Maxim(uint8_t *data, uint16_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t crc = 0;
|
||||
while (len--)
|
||||
{
|
||||
crc ^= *data++;
|
||||
for (i=0; i<8; ++i)
|
||||
{
|
||||
if (crc&1)
|
||||
{
|
||||
crc = (crc>>1) ^ 0xA001;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc = crc>>1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
|
||||
int32_t writeScratchpad(uint8_t addr, uint8_t data[8])
|
||||
{
|
||||
uint8_t crcSrcData[11];
|
||||
uint16_t crcCalResult;
|
||||
uint8_t crcReadData[2];
|
||||
|
||||
if ((data == NULL) || (addr > 0x8F))
|
||||
{
|
||||
return EEPROMDRV_SCRATCHPADWRITE_ERR;
|
||||
}
|
||||
|
||||
if (owResetPd() != 0)
|
||||
{
|
||||
return EEPROMDRV_RESET_ERR;
|
||||
}
|
||||
|
||||
delay_us(140); // delay 200us
|
||||
|
||||
owWriteByte(ROM_SKIP_CMD);
|
||||
owWriteByte(SCRATCHPAD_WRITE_CMD);
|
||||
owWriteByte(addr);
|
||||
owWriteByte(0x00);
|
||||
|
||||
crcSrcData[0] = SCRATCHPAD_WRITE_CMD; // before are right
|
||||
crcSrcData[1] = addr;
|
||||
crcSrcData[2] = 0x00;
|
||||
for (int i=0; i<8; i++)
|
||||
{
|
||||
owWriteByte(data[i]);
|
||||
crcSrcData[i+3] = data[i];
|
||||
}
|
||||
|
||||
crcCalResult = crc16Maxim(crcSrcData, 11); // before are right
|
||||
|
||||
owReadByte(crcReadData);
|
||||
owReadByte(crcReadData+1);
|
||||
|
||||
if (((crcReadData[1]<<8) | crcReadData[0]) != crcCalResult)
|
||||
{
|
||||
return EEPROMDRV_SCRATCHPADWRITE_ERR;
|
||||
}
|
||||
|
||||
return EEPROMDRV_OK;
|
||||
}
|
||||
|
||||
void readScratchpad(uint8_t dataBack[13])
|
||||
{
|
||||
if (owResetPd() != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
delay_us(140); // delay 200us
|
||||
|
||||
owWriteByte(ROM_SKIP_CMD);
|
||||
owWriteByte(SCRATCHPAD_READ_CMD);
|
||||
|
||||
// first 3 bytes are: TA1, TA2, ES; Then 8 bytes data; Last are 2 bytes crc
|
||||
for (int i=0; i<13; i++)
|
||||
{
|
||||
owReadByte(dataBack+i);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t copyScratchpad2Mem(uint16_t addr)
|
||||
{
|
||||
uint8_t readData;
|
||||
|
||||
if (owResetPd() != 0)
|
||||
{
|
||||
return EEPROMDRV_RESET_ERR;
|
||||
}
|
||||
|
||||
delay_us(140); // delay 200us
|
||||
|
||||
owWriteByte(ROM_SKIP_CMD);
|
||||
owWriteByte(SCRATCHPAD_COPY_CMD);
|
||||
owWriteByte(addr);
|
||||
owWriteByte(0x00);
|
||||
owWriteByte(0x07);
|
||||
|
||||
delay_us(140); // delay 200us
|
||||
|
||||
owReadByte(&readData);
|
||||
if (readData != 0xAA)
|
||||
{
|
||||
return EEPROMDRV_SCRATCHPADCOPY_ERR;
|
||||
}
|
||||
|
||||
return EEPROMDRV_OK;
|
||||
}
|
||||
|
||||
uint8_t dataBack[13]={0};
|
||||
int32_t dataCmp(uint8_t targetAddr, uint8_t* buffer, uint8_t len)
|
||||
{
|
||||
// compare the data read from scratchpad
|
||||
if (dataBack[0] != targetAddr)
|
||||
{
|
||||
return EEPROMDRV_SCRATCHPADWRITE_ERR;
|
||||
}
|
||||
|
||||
if (dataBack[1] != 0)
|
||||
{
|
||||
return EEPROMDRV_SCRATCHPADWRITE_ERR;
|
||||
}
|
||||
|
||||
if (dataBack[2] != 0x7)
|
||||
{
|
||||
return EEPROMDRV_SCRATCHPADWRITE_ERR;
|
||||
}
|
||||
|
||||
for (int j=0; j<len; j++)
|
||||
{
|
||||
if (dataBack[j+3] != buffer[j])
|
||||
{
|
||||
return EEPROMDRV_SCRATCHPADWRITE_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
return EEPROMDRV_OK;
|
||||
}
|
||||
|
||||
int32_t eePromReadRom(uint8_t* romCode)
|
||||
{
|
||||
if (owResetPd() !=0)
|
||||
{
|
||||
return EEPROMDRV_RESET_ERR;
|
||||
}
|
||||
|
||||
delay_us(140); // delay 200us
|
||||
|
||||
#if 0
|
||||
uint8_t data = ROM_READ_CMD;
|
||||
int i;
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
owWriteBit(data&0x01);
|
||||
data >>=1;
|
||||
}
|
||||
|
||||
uint8_t dataRead;
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
owReadBit(&dataRead);
|
||||
dataRead <<=1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
int32_t result = owWriteByte(ROM_READ_CMD);
|
||||
if (result < 0)
|
||||
{
|
||||
return EEPROMDRV_ROMREAD_ERR;
|
||||
}
|
||||
|
||||
for (int32_t i=0; i<8; i++)
|
||||
{
|
||||
owReadByte(romCode+i);
|
||||
}
|
||||
#endif
|
||||
|
||||
return EEPROMDRV_OK;
|
||||
}
|
||||
|
||||
int32_t eePromReadMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer)
|
||||
{
|
||||
delay_us(3000); // wait unitl former write operations finish
|
||||
|
||||
if (owResetPd() != 0)
|
||||
{
|
||||
return EEPROMDRV_RESET_ERR;
|
||||
}
|
||||
|
||||
delay_us(140); // delay 200us
|
||||
|
||||
if (owWriteByte(ROM_SKIP_CMD) < 0)
|
||||
{
|
||||
return EEPROMDRV_ROMREAD_ERR;
|
||||
}
|
||||
|
||||
if (owWriteByte(MEM_READ_CMD) < 0)
|
||||
{
|
||||
return EEPROMDRV_ROMREAD_ERR;
|
||||
}
|
||||
|
||||
// write addr low byte
|
||||
if (owWriteByte(targetAddr) < 0)
|
||||
{
|
||||
return EEPROMDRV_ROMREAD_ERR;
|
||||
}
|
||||
|
||||
// write addr high byte
|
||||
if (owWriteByte(0) < 0)
|
||||
{
|
||||
return EEPROMDRV_ROMREAD_ERR;
|
||||
}
|
||||
|
||||
for (int i=0; i<len; i++)
|
||||
{
|
||||
owReadByte(buffer+i);
|
||||
}
|
||||
|
||||
return owResetPd();
|
||||
}
|
||||
|
||||
int32_t writeSctStats;
|
||||
int32_t eePromWriteMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer)
|
||||
{
|
||||
uint8_t tmp[8];
|
||||
int i, index=0;
|
||||
|
||||
if (owResetPd() != 0)
|
||||
{
|
||||
return EEPROMDRV_RESET_ERR;
|
||||
}
|
||||
|
||||
if (targetAddr > 0x88)
|
||||
{
|
||||
return EEPROMDRV_SCRATCHPADWRITE_ERR;
|
||||
}
|
||||
|
||||
while (len > 8)
|
||||
{
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
tmp[i] = buffer[i+index];
|
||||
}
|
||||
|
||||
len -= 8;
|
||||
writeSctStats = writeScratchpad(targetAddr+index, tmp);
|
||||
delay_us(3000);
|
||||
readScratchpad(dataBack);
|
||||
if (dataCmp(targetAddr+index, buffer+index, 8) != 0)
|
||||
{
|
||||
return EEPROMDRV_SCRATCHPADWRITE_ERR;
|
||||
}
|
||||
|
||||
copyScratchpad2Mem(targetAddr+index);
|
||||
delay_us(3000);
|
||||
memset(dataBack, 0, 13);
|
||||
|
||||
index += 8;
|
||||
}
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
tmp[i] = buffer[i+index];
|
||||
}
|
||||
|
||||
memset(tmp+i, 1, 8-len);
|
||||
delay_us(3000); // wait until eeprom store data finish
|
||||
writeSctStats = writeScratchpad(targetAddr+index, tmp);
|
||||
delay_us(3000);
|
||||
readScratchpad(dataBack);
|
||||
if (dataCmp(targetAddr+index, buffer+index, len) != 0)
|
||||
{
|
||||
return EEPROMDRV_SCRATCHPADWRITE_ERR;
|
||||
}
|
||||
|
||||
copyScratchpad2Mem(targetAddr+index);
|
||||
delay_us(30000); // wait until eeprom store data finish
|
||||
|
||||
if (owResetPd() != 0)
|
||||
{
|
||||
return EEPROMDRV_RESET_ERR;
|
||||
}
|
||||
|
||||
return EEPROMDRV_OK;
|
||||
}
|
||||
|
||||
void eepRomInit(OwModeSel_e mode)
|
||||
{
|
||||
owInit();
|
||||
owSetMode(mode);
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
#include "imageProcess.h"
|
||||
|
||||
/* This file is used for camera preview. Since LCD will have different resolution, and decoder library need
|
||||
a fixed resolution, so the picture from camera needs to be processed to fit different LCD resolution. */
|
||||
|
||||
|
||||
/**
|
||||
\brief Scale the picture. Now this api can only zoom out the picture.
|
||||
\param[in] ratio Zoom out ratio.
|
||||
\param[in] inPtr Data source.
|
||||
\param[in] width Source data width.
|
||||
\param[in] height Source data height.
|
||||
\param[out] outPtr Output data address.
|
||||
\return
|
||||
*/
|
||||
void scalePic(uint8_t ratio, uint8_t* inPtr, uint16_t width, uint16_t height, uint8_t *outPtr)
|
||||
{
|
||||
uint8_t *p = outPtr;
|
||||
uint16_t h, w;
|
||||
|
||||
for (h = 0; h < height; h += ratio)
|
||||
{
|
||||
for (w = 0; w < width; w += ratio)
|
||||
{
|
||||
*p++ = inPtr[w + h*width];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Clockwise rotate 90 degree.
|
||||
\param[in/out] mem Data source.
|
||||
\param[in] width Source picture width.
|
||||
\param[in] height Source picture height.
|
||||
\return
|
||||
*/
|
||||
void imageRotate(uint8_t* mem, uint32_t width, uint32_t height)
|
||||
{
|
||||
uint8_t* tmpData = (uint8_t *)malloc(width * height);
|
||||
memcpy(tmpData, mem, width*height);
|
||||
|
||||
for (int i= 0; i < width; i++)
|
||||
{
|
||||
for (int j = 0; j < height; j++)
|
||||
{
|
||||
mem[i*height + j] = tmpData[(height-1-j) * width + i];
|
||||
}
|
||||
}
|
||||
|
||||
free(tmpData);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Organize the bytes as horizontal or vertical.
|
||||
\param[in] inPut Src data.
|
||||
\param[in] pageLen The pageNum you want for these data, this param is set by you.
|
||||
\param[in] width The width you want for these data, this param is set by you.
|
||||
\param[out] outPut Output buffer.
|
||||
\param[in] horizotal These data you want to array them as horizontal or vertical.
|
||||
\return
|
||||
*/
|
||||
void storeByteIntoArray(uint8_t *inPut, uint8_t pageLen, uint16_t width, uint8_t *outPut, bool horizotal)
|
||||
{
|
||||
uint32_t i, j;
|
||||
uint32_t index = 0;
|
||||
|
||||
if (horizotal)
|
||||
{
|
||||
for (i = 0; i < pageLen*width; i++)
|
||||
{
|
||||
outPut[index++] = inPut[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
for (j = 0; j < pageLen; j++)
|
||||
{
|
||||
outPut[i + j*width] = inPut[i*pageLen + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Merge 8bytes into one byte, used in 1-bit LCD.
|
||||
\param[in] p Src data.
|
||||
\param[out] outPut Output buffer.
|
||||
\param[in] width Source data width.
|
||||
\param[out] height Source data height.
|
||||
\param[in] horizotal Fetch the data by row or by column.
|
||||
\param[in] inByteRevert Within the byte, positive or reverse the bit sequence.
|
||||
\return index How many bytes has been returned, for debug use
|
||||
*/
|
||||
uint16_t merge8Bytes2OneByte(uint8_t* p, uint8_t *outPut, uint16_t width, uint16_t height, bool horizotal, bool inByteRevert)
|
||||
{
|
||||
int i;
|
||||
uint8_t data=0, data0=0, data1=0, data2=0, data3=0, data4=0, data5=0, data6=0, data7=0;
|
||||
uint16_t index = 0;
|
||||
|
||||
if (horizotal)
|
||||
{
|
||||
for (i = 0 ; i < width*height; i+=8)
|
||||
{
|
||||
data0 = p[i];
|
||||
data1 = p[i+1];
|
||||
data2 = p[i+2];
|
||||
data3 = p[i+3];
|
||||
data4 = p[i+4];
|
||||
data5 = p[i+5];
|
||||
data6 = p[i+6];
|
||||
data7 = p[i+7];
|
||||
|
||||
if (inByteRevert)
|
||||
{
|
||||
data = data0 | (data1<<1) | (data2<<2) | (data3<<3) | (data4<<4) | (data5<<5) | (data6<<6) | (data7<<7);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = data7 | (data6<<1) | (data5<<2) | (data4<<3) | (data3<<4) | (data2<<5) | (data1<<6) | (data0<<7);
|
||||
}
|
||||
|
||||
outPut[index++] = data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t page = 0; page < height/8; page++)
|
||||
{
|
||||
i = page*width*8;
|
||||
|
||||
for (; i < page*width*8 + width; i++)
|
||||
{
|
||||
data0 = p[i];
|
||||
data1 = p[i+1*width];
|
||||
data2 = p[i+2*width];
|
||||
data3 = p[i+3*width];
|
||||
data4 = p[i+4*width];
|
||||
data5 = p[i+5*width];
|
||||
data6 = p[i+6*width];
|
||||
data7 = p[i+7*width];
|
||||
|
||||
if (inByteRevert)
|
||||
{
|
||||
data = data0 | (data1<<1) | (data2<<2) | (data3<<3) | (data4<<4) | (data5<<5) | (data6<<6) | (data7<<7);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = data7 | (data6<<1) | (data5<<2) | (data4<<3) | (data3<<4) | (data2<<5) | (data1<<6) | (data0<<7);
|
||||
}
|
||||
|
||||
outPut[index++] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Binary the source picture.
|
||||
\param[in] inPut Src data.
|
||||
\param[in] width Source picture width.
|
||||
\param[in] height Source picture height.
|
||||
\param[out] outPut Output buffer.
|
||||
\return
|
||||
*/
|
||||
void calBinary(uint8_t* inPut, uint16_t width, uint16_t height, uint8_t* outPut)
|
||||
{
|
||||
uint32_t sum = 0, avg = 0, i;
|
||||
|
||||
for (i = 0; i < width*height; i++)
|
||||
{
|
||||
sum += *(inPut + i);
|
||||
}
|
||||
|
||||
avg = sum / (width*height);
|
||||
|
||||
for (uint32_t j = 0; j < width*height; j++)
|
||||
{
|
||||
if (*(inPut + j) < avg)
|
||||
{
|
||||
*(outPut + j) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(outPut + j) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse the high 4bits and low 4bits.
|
||||
\param[in/out] p source/output memory.
|
||||
\param[in] num source data num.
|
||||
\return
|
||||
*/
|
||||
void reverseByte(uint8_t* p, int num)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
for (int i = 0; i< num; i++)
|
||||
{
|
||||
data = *(p+i);
|
||||
data = ((data&0x0f)<<4) | ((data&0xf0)>>4);
|
||||
*(p+i) = data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Clear low 7bits.
|
||||
\param[in/out] p Src/output mem.
|
||||
\param[in] num source data num.
|
||||
\return
|
||||
*/
|
||||
void clearLow7bits(uint8_t* p, int num)
|
||||
{
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
*(p+i) = *(p+i) & 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Convert yuv422 to rgb565, used in color screen.
|
||||
\param[in] inbuf source memory.
|
||||
\param[out] outbuf output memory.
|
||||
\param[in] width source picture width.
|
||||
\param[in] height source picture height.
|
||||
\return
|
||||
*/
|
||||
#define RANGE_LIMIT(x) (x > 255 ? 255 : (x < 0 ? 0 : x))
|
||||
void yuv422ToRgb565(const void* inbuf, void* outbuf, int width, int height)
|
||||
{
|
||||
int rows, cols;
|
||||
int y, u, v, r, g, b;
|
||||
unsigned char *yuv_buf;
|
||||
unsigned short *rgb_buf;
|
||||
int y_pos,u_pos,v_pos;
|
||||
|
||||
yuv_buf = (unsigned char *)inbuf;
|
||||
rgb_buf = (unsigned short *)outbuf;
|
||||
|
||||
y_pos = 0;
|
||||
u_pos = 1;
|
||||
v_pos = 3;
|
||||
|
||||
for (rows = 0; rows < height; rows++)
|
||||
{
|
||||
for (cols = 0; cols < width; cols++)
|
||||
{
|
||||
y = yuv_buf[y_pos];
|
||||
u = yuv_buf[u_pos] - 128;
|
||||
v = yuv_buf[v_pos] - 128;
|
||||
|
||||
// R = Y + 1.402*(V-128)
|
||||
// G = Y - 0.34414*(U-128)
|
||||
// B = Y + 1.772*(U-128)
|
||||
r = RANGE_LIMIT(y + v + ((v * 103) >> 8));
|
||||
g = RANGE_LIMIT(y - ((u * 88) >> 8) - ((v * 183) >> 8));
|
||||
b = RANGE_LIMIT(y + u + ((u * 198) >> 8));
|
||||
|
||||
*rgb_buf++ = (((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
|
||||
|
||||
y_pos += 2;
|
||||
|
||||
if (cols & 0x01)
|
||||
{
|
||||
u_pos += 4;
|
||||
v_pos += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
#include "lcdDrv.h"
|
||||
|
||||
|
||||
extern void delay_us(uint32_t us);
|
||||
int8_t lcdDmaTxCh; // dma tx channel
|
||||
DmaDescriptor_t __ALIGNED(16) lcdDmaTxDesc[HEIGHT];
|
||||
//uint8_t dmaTxData[WIDTH*2];
|
||||
|
||||
static DmaTransferConfig_t lcdDmaTxCfg =
|
||||
{
|
||||
NULL,
|
||||
(void *)&(SPI->DR),
|
||||
DMA_FLOW_CONTROL_TARGET,
|
||||
DMA_ADDRESS_INCREMENT_SOURCE,
|
||||
DMA_DATA_WIDTH_ONE_BYTE,
|
||||
DMA_BURST_8_BYTES,
|
||||
WIDTH * 2
|
||||
};
|
||||
|
||||
|
||||
|
||||
void mDelay(uint32_t mDelay)
|
||||
{
|
||||
delay_us(mDelay * 1000);
|
||||
}
|
||||
|
||||
void lcdWriteData(uint8_t data)
|
||||
{
|
||||
SPI_CS_LOW;
|
||||
LCD_DS_HIGH;
|
||||
SPI_SEND_DATA(data);
|
||||
//SPI_WAIT_TX_DONE;
|
||||
SPI_IS_BUSY;
|
||||
SPI_CS_HIGH;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void lcdWriteCmd(uint8_t cmd)
|
||||
{
|
||||
SPI_CS_LOW;
|
||||
LCD_DS_LOW;
|
||||
SPI_SEND_DATA(cmd);
|
||||
SPI_WAIT_TX_DONE;
|
||||
SPI_CS_HIGH;
|
||||
}
|
||||
|
||||
uint8_t lcdReadData()
|
||||
{
|
||||
SPI_WAIT_TX_DONE;
|
||||
SPI_SEND_DATA(0xff); // Dummy data
|
||||
SPI_WAIT_TX_DONE;
|
||||
uint8_t data = SPI_READ_DATA;
|
||||
SPI_IS_BUSY;
|
||||
return data;
|
||||
}
|
||||
|
||||
void lcdDispWindows()
|
||||
{
|
||||
lcdWriteCmd(0x2A);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0xEF);
|
||||
|
||||
lcdWriteCmd(0x2B);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0x01);
|
||||
lcdWriteData(0x3f);
|
||||
lcdWriteCmd(0x2C);
|
||||
}
|
||||
|
||||
void lcdWriteSetup(uint8_t * dataBuf, uint16_t dataCnt)
|
||||
{
|
||||
lcdDispWindows();
|
||||
|
||||
// Configure tx DMA and start it
|
||||
lcdDmaTxCfg.sourceAddress = (void *)dataBuf;
|
||||
//lcdDmaTxCfg.totalLength = dataCnt; // every descriptor transfer this trunk of data
|
||||
|
||||
SPI_CS_LOW;
|
||||
LCD_DS_HIGH;
|
||||
DMA_buildDescriptorChain(lcdDmaTxDesc, &lcdDmaTxCfg, dataCnt / LCD_TRANSFER_SIZE_ONCE, false);
|
||||
SPI_ENABLE_TX_DMA;
|
||||
}
|
||||
|
||||
void lcdWriteCtrl(bool startOrStop)
|
||||
{
|
||||
if (startOrStop)
|
||||
{
|
||||
DMA_loadChannelDescriptorAndRun(DMA_INSTANCE_MP, lcdDmaTxCh, lcdDmaTxDesc);
|
||||
}
|
||||
else
|
||||
{
|
||||
extern void DMA_stopChannelNoWait(DmaInstance_e instance, uint32_t channel);
|
||||
DMA_stopChannelNoWait(DMA_INSTANCE_MP, lcdDmaTxCh);
|
||||
SPI_CS_HIGH;
|
||||
}
|
||||
}
|
||||
|
||||
void lcdDispColor(uint16_t color)
|
||||
{
|
||||
//lcdFillColorBuf(color);
|
||||
|
||||
for (int i = 0; i < HEIGHT; i++)
|
||||
{
|
||||
lcdWriteCtrl(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void lcdReadId()
|
||||
{
|
||||
uint8_t id1, id2, id3;
|
||||
|
||||
LCD_RST_HIGH;
|
||||
mDelay(150); // Delay 200ms
|
||||
LCD_RST_LOW;
|
||||
mDelay(300); // Delay 400ms
|
||||
LCD_RST_HIGH;
|
||||
mDelay(400); // Delay 500ms
|
||||
|
||||
lcdWriteData(0x04);
|
||||
(void)lcdReadData(); // Dummy
|
||||
id1 = lcdReadData();
|
||||
id2 = lcdReadData();
|
||||
id3 = lcdReadData();
|
||||
printf("LCD ID: %02x, %02x, %02x \r\n", id1, id2, id3);
|
||||
}
|
||||
|
||||
static void lcdGpioInit()
|
||||
{
|
||||
PadConfig_t config;
|
||||
|
||||
PAD_getDefaultConfig(&config);
|
||||
|
||||
// Cs pin
|
||||
config.mux = SPI_CS_PAD_ALT_FUNC;
|
||||
PAD_setPinConfig(SPI_CS_PAD_ADDR, &config);
|
||||
|
||||
GpioPinConfig_t gpioCfg;
|
||||
gpioCfg.pinDirection = GPIO_DIRECTION_OUTPUT;
|
||||
GPIO_pinConfig(SPI_CS_GPIO_INSTANCE, SPI_CS_GPIO_PIN, &gpioCfg);
|
||||
|
||||
// Rst pin
|
||||
config.mux = LCD_RST_PAD_ALT_FUNC;
|
||||
PAD_setPinConfig(LCD_RST_PAD_ADDR, &config);
|
||||
|
||||
gpioCfg.pinDirection = GPIO_DIRECTION_OUTPUT;
|
||||
//gpioCfg.misc.initOutput = 1;
|
||||
GPIO_pinConfig(LCD_RST_GPIO_INSTANCE, LCD_RST_GPIO_PIN, &gpioCfg);
|
||||
|
||||
// Ds pin
|
||||
config.mux = LCD_DS_PAD_ALT_FUNC;
|
||||
PAD_setPinConfig(LCD_DS_PAD_ADDR, &config);
|
||||
|
||||
gpioCfg.pinDirection = GPIO_DIRECTION_OUTPUT;
|
||||
GPIO_pinConfig(LCD_DS_GPIO_INSTANCE, LCD_DS_GPIO_PIN, &gpioCfg);
|
||||
|
||||
#if (ST7571_ENABLE)
|
||||
#if 0 // if used in environment with os, use this api to adjust voltage
|
||||
slpManAONIOVoltSet(IOVOLT_2_95V); // 54
|
||||
APmuWakeupPadSettings_t cfg;
|
||||
cfg.pullUpEn = 1;
|
||||
slpManSetWakeupPadCfg(WAKEUP_PAD_4, false, &cfg); //gpio21 50
|
||||
slpManAONIOPowerOn();//70
|
||||
#else // used in environment without os
|
||||
*(uint32_t*)0x4d020018 = 0x1; // Normal gpio: 2.8V
|
||||
*(uint32_t*)0x4d020054 = 0x1b; // AON IO: 3.35V, 2.8V
|
||||
*(uint32_t*)0x4d020150 = 0x7; // Enable AON gpio as wakeup pin
|
||||
*(uint32_t*)0x4d020170 = 0x1; // Enable AON IO
|
||||
#endif
|
||||
|
||||
// Lcd en pin
|
||||
config.mux = LCD_EN_PAD_ALT_FUNC;
|
||||
PAD_setPinConfig(LCD_EN_PAD_ADDR, &config);
|
||||
|
||||
gpioCfg.pinDirection = GPIO_DIRECTION_OUTPUT;
|
||||
gpioCfg.misc.initOutput = 1;
|
||||
GPIO_pinConfig(LCD_EN_GPIO_INSTANCE, LCD_EN_GPIO_PIN, &gpioCfg);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void lcdSpiInit()
|
||||
{
|
||||
PadConfig_t config;
|
||||
|
||||
PAD_getDefaultConfig(&config);
|
||||
|
||||
config.mux = SPI_CLK_PAD_ALT_FUNC;
|
||||
PAD_setPinConfig(SPI_CLK_PAD_ADDR, &config);
|
||||
|
||||
config.mux = SPI_MOSI_PAD_ALT_FUNC;
|
||||
PAD_setPinConfig(SPI_MOSI_PAD_ADDR, &config);
|
||||
|
||||
config.mux = SPI_MISO_PAD_ALT_FUNC;
|
||||
PAD_setPinConfig(SPI_MISO_PAD_ADDR, &config);
|
||||
|
||||
// Enable spi clock
|
||||
GPR_clockEnable(SPI_APB_CLOCK);
|
||||
GPR_clockEnable(SPI_FUNC_CLOCK);
|
||||
|
||||
// Disable spi first
|
||||
SPI->CR1 = 0;
|
||||
|
||||
// Pol = 0; PHA = 0; Data width = 8
|
||||
SPI->CR0 = 0x7;
|
||||
|
||||
// lcd spi clock choose 26M by default to speed up the fps.
|
||||
CLOCK_clockEnable(CLK_HF51M); // open 51M
|
||||
CLOCK_setClockSrc(FCLK_SPI0, FCLK_SPI0_SEL_51M); // choose 51M
|
||||
SPI->CPSR = 2 & SPI_CPSR_CPSDVSR_Msk; // 2 division, to 26M
|
||||
SPI->CR0 = (SPI->CR0 & ~SPI_CR0_SCR_Msk) | 0;
|
||||
|
||||
// Enable spi
|
||||
SPI->CR1 = SPI_CR1_SSE_Msk;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void lcdWriteData16(uint16_t data)
|
||||
{
|
||||
lcdWriteData(data >> 8);
|
||||
lcdWriteData(data);
|
||||
}
|
||||
|
||||
void lcdDispPic(uint8_t * pic)
|
||||
{
|
||||
#if (ST7789V2_ENABLE)
|
||||
int i, j;
|
||||
|
||||
lcdDispWindows();
|
||||
for (i = 0; i < HEIGHT; i++)
|
||||
{
|
||||
for (j = 0; j < WIDTH; j++)
|
||||
{
|
||||
lcdWriteData16(pic[j*2 + HEIGHT*i*2]);
|
||||
}
|
||||
}
|
||||
#elif (ST7571_ENABLE)
|
||||
displayPic_60x80(pic);
|
||||
#endif
|
||||
}
|
||||
|
||||
void lcdClearScreen()
|
||||
{
|
||||
#if (ST7571_ENABLE)
|
||||
st7571CleanScreen();
|
||||
#endif
|
||||
}
|
||||
|
||||
void lcdInit(pTxCb txCb)
|
||||
{
|
||||
lcdSpiInit();
|
||||
lcdGpioInit();
|
||||
|
||||
lcdReadId();
|
||||
#if (ST7789V2_ENABLE)
|
||||
st7789v2_init();
|
||||
#endif
|
||||
|
||||
#if (ST7571_ENABLE)
|
||||
st7571_init();
|
||||
lcdClearScreen();
|
||||
#else
|
||||
|
||||
// Tx config
|
||||
DMA_init(DMA_INSTANCE_MP);
|
||||
lcdDmaTxCh = DMA_openChannel(DMA_INSTANCE_MP);
|
||||
|
||||
DMA_setChannelRequestSource(DMA_INSTANCE_MP, lcdDmaTxCh, (DmaRequestSource_e)SPI_DMA_TX_REQID);
|
||||
DMA_rigisterChannelCallback(DMA_INSTANCE_MP, lcdDmaTxCh, txCb);
|
||||
//DMA_transferSetup(DMA_INSTANCE_MP, lcdDmaTxCh, &lcdDmaTxCfg);
|
||||
//DMA_transferSetup(DMA_INSTANCE_MP, lcdDmaTxCh, &lcdDmaConfig);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
#include "lcdDrv.h"
|
||||
|
||||
uint8_t clearScreen[128] = {0};
|
||||
|
||||
#define USE_DMA
|
||||
|
||||
#ifdef USE_DMA
|
||||
static DmaTransferConfig_t st7571DmaTxCfg =
|
||||
{
|
||||
NULL,
|
||||
(void *)&(SPI->DR),
|
||||
DMA_FLOW_CONTROL_TARGET,
|
||||
DMA_ADDRESS_INCREMENT_SOURCE,
|
||||
DMA_DATA_WIDTH_ONE_BYTE,
|
||||
DMA_BURST_8_BYTES,
|
||||
0
|
||||
};
|
||||
static DmaDescriptor_t __ALIGNED(16) st7571DmaTxDesc[1];
|
||||
int8_t st7571DmaTxCh;
|
||||
bool isDMADone = false;
|
||||
uint8_t st7571DmaSrc[128] = {0};
|
||||
uint8_t *pLcdData = NULL;
|
||||
|
||||
static void st7571DmaEventCb(uint32_t event)
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
case DMA_EVENT_END:
|
||||
isDMADone = true;
|
||||
SPI_CS_HIGH;
|
||||
//DMA_stopChannel(DMA_INSTANCE_MP, st7571DmaTxCh, false);
|
||||
|
||||
break;
|
||||
case DMA_EVENT_ERROR:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void st7571DmaInit()
|
||||
{
|
||||
// Tx config
|
||||
DMA_init(DMA_INSTANCE_MP);
|
||||
st7571DmaTxCh = DMA_openChannel(DMA_INSTANCE_MP);
|
||||
|
||||
DMA_setChannelRequestSource(DMA_INSTANCE_MP, st7571DmaTxCh, (DmaRequestSource_e)SPI_DMA_TX_REQID);
|
||||
DMA_rigisterChannelCallback(DMA_INSTANCE_MP, st7571DmaTxCh, st7571DmaEventCb);
|
||||
SPI_ENABLE_TX_DMA;
|
||||
}
|
||||
|
||||
void st7571WriteCtrl(uint32_t totalLen)
|
||||
{
|
||||
// Configure tx DMA and start it
|
||||
st7571DmaTxCfg.sourceAddress = (void *)pLcdData;
|
||||
st7571DmaTxCfg.totalLength = totalLen; // every descriptor transfer this trunk of data
|
||||
|
||||
SPI_CS_LOW;
|
||||
LCD_DS_HIGH;
|
||||
DMA_buildDescriptorChain(st7571DmaTxDesc, &st7571DmaTxCfg, 1, true);
|
||||
//SPI_ENABLE_TX_DMA;
|
||||
|
||||
DMA_loadChannelDescriptorAndRun(DMA_INSTANCE_MP, st7571DmaTxCh, st7571DmaTxDesc);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void st7571_init()
|
||||
{
|
||||
//--------------------------------ST7571 reset sequence------------------------------------//
|
||||
LCD_RST_HIGH;
|
||||
mDelay(50); //Delay 100ms
|
||||
LCD_RST_LOW;
|
||||
mDelay(150); //Delay 200ms
|
||||
LCD_RST_HIGH;
|
||||
mDelay(250); //Delay 500ms
|
||||
|
||||
lcdWriteCmd(0xAE);
|
||||
lcdWriteCmd(0xE2);
|
||||
lcdWriteCmd(0x38);
|
||||
|
||||
lcdWriteCmd(0xE1);
|
||||
lcdWriteCmd(0xAB);
|
||||
|
||||
lcdWriteCmd(0x54);
|
||||
lcdWriteCmd(0x48);
|
||||
lcdWriteCmd(0x80);
|
||||
|
||||
|
||||
lcdWriteCmd(0xB8);
|
||||
|
||||
lcdWriteCmd(0xA2);
|
||||
lcdWriteCmd(0xA0);
|
||||
lcdWriteCmd(0xc8);
|
||||
|
||||
lcdWriteCmd(0x25);
|
||||
lcdWriteCmd(0x81);
|
||||
//lcdWriteCmd(v0); ////////////////////////////////////////////
|
||||
lcdWriteCmd(0x23);
|
||||
|
||||
|
||||
lcdWriteCmd(0x40);//START LINE
|
||||
lcdWriteCmd(0x00);
|
||||
|
||||
lcdWriteCmd(0x44);//START LINE
|
||||
lcdWriteCmd(0x00);
|
||||
|
||||
lcdWriteCmd(0x2c); mDelay(10);
|
||||
lcdWriteCmd(0x2e); mDelay(10);
|
||||
lcdWriteCmd(0x2F); mDelay(10);
|
||||
|
||||
|
||||
|
||||
lcdWriteCmd(0xAF);//DISPLAY ON
|
||||
|
||||
|
||||
lcdWriteCmd(0x7B);
|
||||
lcdWriteCmd(0x11); // 0x11=black/white mode; 0x10=gray mode;
|
||||
lcdWriteCmd(0x00);
|
||||
|
||||
mDelay(10);
|
||||
//disp_off();
|
||||
mDelay(50);
|
||||
|
||||
#ifdef USE_DMA
|
||||
st7571DmaInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void lcdAddress(uint8_t page, uint8_t column)
|
||||
{
|
||||
lcdWriteCmd(0xB0 + page);
|
||||
lcdWriteCmd(((column >> 4) & 0x0f) + 0x10); // column addr MSB
|
||||
lcdWriteCmd(column & 0x0f); // column addr LSB
|
||||
}
|
||||
|
||||
void st7571CleanScreen(void)
|
||||
{
|
||||
uint8_t j;
|
||||
#ifdef USE_DMA
|
||||
pLcdData = clearScreen;
|
||||
#else
|
||||
uint8_t i;
|
||||
#endif
|
||||
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
lcdAddress(j, 0);
|
||||
#ifndef USE_DMA
|
||||
for(i = 0; i < 128; i++)
|
||||
{
|
||||
lcdWriteData(0x00);
|
||||
}
|
||||
#else
|
||||
st7571WriteCtrl(128);
|
||||
|
||||
do
|
||||
{
|
||||
delay_us(1);
|
||||
}while (isDMADone == false);
|
||||
isDMADone = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void displayPic_60x80(uint8_t *p)
|
||||
{
|
||||
#ifndef USE_DMA
|
||||
uint32_t k;
|
||||
#endif
|
||||
uint32_t n;
|
||||
st7571CleanScreen();
|
||||
|
||||
for(n = 0; n < 10; n++) // 16 page
|
||||
{
|
||||
lcdAddress(n, 0);
|
||||
|
||||
#ifndef USE_DMA
|
||||
for(k = 0; k < 60; k++)// every page 64byte, total 1k
|
||||
{
|
||||
lcdWriteData(p[k + 60 * n]);
|
||||
}
|
||||
#else
|
||||
pLcdData = p + 60 * n;
|
||||
st7571WriteCtrl(60);
|
||||
|
||||
do
|
||||
{
|
||||
delay_us(1);
|
||||
}while (isDMADone == false);
|
||||
isDMADone = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void testResolution()
|
||||
{
|
||||
st7571CleanScreen();
|
||||
|
||||
uint32_t k, n;
|
||||
|
||||
for (n = 0; n < 16; n++)
|
||||
{
|
||||
lcdAddress(n, 0); // set page and initial column
|
||||
for(k = 0; k < 64/4; k++)// every page 64byte, total 1k
|
||||
{
|
||||
lcdWriteData(0xff); // write one byte 1
|
||||
lcdWriteData(0xff); // write one byte 1 again
|
||||
|
||||
lcdWriteData(0); // write one byte 0
|
||||
lcdWriteData(0); // write one byte 0 again
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "lcdDrv.h"
|
||||
|
||||
void st7789v2_init()
|
||||
{
|
||||
//--------------------------------ST7789V reset sequence------------------------------------//
|
||||
LCD_RST_HIGH;
|
||||
mDelay(50); //Delay 100ms
|
||||
LCD_RST_LOW;
|
||||
mDelay(150); //Delay 200ms
|
||||
LCD_RST_HIGH;
|
||||
mDelay(250); //Delay 500ms
|
||||
|
||||
//-------------------------------Color Mode---------------------------------------------//
|
||||
lcdWriteCmd(0x11);
|
||||
mDelay (120); //Delay 120ms
|
||||
|
||||
//--------------------------------Display Setting------------------------------------------//
|
||||
lcdWriteCmd(0x36);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteCmd(0x3a);
|
||||
lcdWriteData(0x05);
|
||||
|
||||
//--------------------------------ST7789V Frame rate setting----------------------------------//
|
||||
lcdWriteCmd(0xb2);
|
||||
lcdWriteData(0x0c);
|
||||
lcdWriteData(0x0c);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0x33);
|
||||
lcdWriteData(0x33);
|
||||
lcdWriteCmd(0xb7);
|
||||
lcdWriteData(0x35);
|
||||
|
||||
//--------------------------------ST7789V Power setting--------------------------------------//
|
||||
lcdWriteCmd(0xbb);
|
||||
lcdWriteData(0x20);
|
||||
lcdWriteCmd(0xc0);
|
||||
lcdWriteData(0x2c);
|
||||
lcdWriteCmd(0xc2);
|
||||
lcdWriteData(0x01);
|
||||
lcdWriteCmd(0xc3);
|
||||
lcdWriteData(0x0b);
|
||||
lcdWriteCmd(0xc4);
|
||||
lcdWriteData(0x20);
|
||||
lcdWriteCmd(0xc6);
|
||||
lcdWriteData(0x0f);
|
||||
lcdWriteCmd(0xd0);
|
||||
lcdWriteData(0xa4);
|
||||
lcdWriteData(0xa1);
|
||||
|
||||
//--------------------------------ST7789V gamma setting---------------------------------------//
|
||||
lcdWriteCmd(0xe0);
|
||||
lcdWriteData(0xd0);
|
||||
lcdWriteData(0x03);
|
||||
lcdWriteData(0x09);
|
||||
lcdWriteData(0x0e);
|
||||
lcdWriteData(0x11);
|
||||
lcdWriteData(0x3d);
|
||||
lcdWriteData(0x47);
|
||||
lcdWriteData(0x55);
|
||||
lcdWriteData(0x53);
|
||||
lcdWriteData(0x1a);
|
||||
lcdWriteData(0x16);
|
||||
lcdWriteData(0x14);
|
||||
lcdWriteData(0x1f);
|
||||
lcdWriteData(0x22);
|
||||
lcdWriteCmd(0xe1);
|
||||
lcdWriteData(0xd0);
|
||||
lcdWriteData(0x02);
|
||||
lcdWriteData(0x08);
|
||||
lcdWriteData(0x0d);
|
||||
lcdWriteData(0x12);
|
||||
lcdWriteData(0x2c);
|
||||
lcdWriteData(0x43);
|
||||
lcdWriteData(0x55);
|
||||
lcdWriteData(0x53);
|
||||
lcdWriteData(0x1e);
|
||||
lcdWriteData(0x1b);
|
||||
lcdWriteData(0x19);
|
||||
lcdWriteData(0x20);
|
||||
lcdWriteData(0x22);
|
||||
lcdWriteCmd(0x29);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2018 Copyrigths of AirM2M Ltd.
|
||||
* File name: ntc.c
|
||||
* Description:
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "ntc.h"
|
||||
|
||||
#define NCP15XH103F03RC
|
||||
|
||||
#if defined(NCP15XH103F03RC)
|
||||
static const int32_t gNTCLut[65] = {
|
||||
253347, // T:253.35 Rntc:0.0k ADC code:0 Input voltage:0uV
|
||||
187444, // T:187.44 Rntc:0.159k ADC code:64 Input voltage:18750uV
|
||||
149195, // T:149.2 Rntc:0.323k ADC code:128 Input voltage:37500uV
|
||||
128368, // T:128.37 Rntc:0.492k ADC code:192 Input voltage:56250uV
|
||||
115301, // T:115.3 Rntc:0.667k ADC code:256 Input voltage:75000uV
|
||||
105493, // T:105.49 Rntc:0.847k ADC code:320 Input voltage:93750uV
|
||||
97670, // T:97.67 Rntc:1.034k ADC code:384 Input voltage:112500uV
|
||||
91187, // T:91.19 Rntc:1.228k ADC code:448 Input voltage:131250uV
|
||||
85596, // T:85.6 Rntc:1.429k ADC code:512 Input voltage:150000uV
|
||||
80693, // T:80.69 Rntc:1.636k ADC code:576 Input voltage:168750uV
|
||||
76336, // T:76.34 Rntc:1.852k ADC code:640 Input voltage:187500uV
|
||||
72403, // T:72.4 Rntc:2.075k ADC code:704 Input voltage:206250uV
|
||||
68803, // T:68.8 Rntc:2.308k ADC code:768 Input voltage:225000uV
|
||||
65478, // T:65.48 Rntc:2.549k ADC code:832 Input voltage:243750uV
|
||||
62389, // T:62.39 Rntc:2.8k ADC code:896 Input voltage:262500uV
|
||||
59508, // T:59.51 Rntc:3.061k ADC code:960 Input voltage:281250uV
|
||||
56829, // T:56.83 Rntc:3.333k ADC code:1024 Input voltage:300000uV
|
||||
54289, // T:54.29 Rntc:3.617k ADC code:1088 Input voltage:318750uV
|
||||
51869, // T:51.87 Rntc:3.913k ADC code:1152 Input voltage:337500uV
|
||||
49556, // T:49.56 Rntc:4.222k ADC code:1216 Input voltage:356250uV
|
||||
47337, // T:47.34 Rntc:4.545k ADC code:1280 Input voltage:375000uV
|
||||
45200, // T:45.2 Rntc:4.884k ADC code:1344 Input voltage:393750uV
|
||||
43135, // T:43.14 Rntc:5.238k ADC code:1408 Input voltage:412500uV
|
||||
41134, // T:41.13 Rntc:5.61k ADC code:1472 Input voltage:431250uV
|
||||
39186, // T:39.19 Rntc:6.0k ADC code:1536 Input voltage:450000uV
|
||||
37287, // T:37.29 Rntc:6.41k ADC code:1600 Input voltage:468750uV
|
||||
35433, // T:35.43 Rntc:6.842k ADC code:1664 Input voltage:487500uV
|
||||
33620, // T:33.62 Rntc:7.297k ADC code:1728 Input voltage:506250uV
|
||||
31842, // T:31.84 Rntc:7.778k ADC code:1792 Input voltage:525000uV
|
||||
30095, // T:30.1 Rntc:8.286k ADC code:1856 Input voltage:543750uV
|
||||
28377, // T:28.38 Rntc:8.824k ADC code:1920 Input voltage:562500uV
|
||||
26680, // T:26.68 Rntc:9.394k ADC code:1984 Input voltage:581250uV
|
||||
25000, // T:25.0 Rntc:10.0k ADC code:2048 Input voltage:600000uV
|
||||
23332, // T:23.33 Rntc:10.645k ADC code:2112 Input voltage:618750uV
|
||||
21675, // T:21.68 Rntc:11.333k ADC code:2176 Input voltage:637500uV
|
||||
20024, // T:20.02 Rntc:12.069k ADC code:2240 Input voltage:656250uV
|
||||
18382, // T:18.38 Rntc:12.857k ADC code:2304 Input voltage:675000uV
|
||||
16741, // T:16.74 Rntc:13.704k ADC code:2368 Input voltage:693750uV
|
||||
15100, // T:15.1 Rntc:14.615k ADC code:2432 Input voltage:712500uV
|
||||
13455, // T:13.46 Rntc:15.6k ADC code:2496 Input voltage:731250uV
|
||||
11801, // T:11.8 Rntc:16.667k ADC code:2560 Input voltage:750000uV
|
||||
10137, // T:10.14 Rntc:17.826k ADC code:2624 Input voltage:768750uV
|
||||
8454, // T:8.45 Rntc:19.091k ADC code:2688 Input voltage:787500uV
|
||||
6750, // T:6.75 Rntc:20.476k ADC code:2752 Input voltage:806250uV
|
||||
5022, // T:5.02 Rntc:22.0k ADC code:2816 Input voltage:825000uV
|
||||
3265, // T:3.27 Rntc:23.684k ADC code:2880 Input voltage:843750uV
|
||||
1472, // T:1.47 Rntc:25.556k ADC code:2944 Input voltage:862500uV
|
||||
-361, // T:-0.36 Rntc:27.647k ADC code:3008 Input voltage:881250uV
|
||||
-2238, // T:-2.24 Rntc:30.0k ADC code:3072 Input voltage:900000uV
|
||||
-4171, // T:-4.17 Rntc:32.667k ADC code:3136 Input voltage:918750uV
|
||||
-6170, // T:-6.17 Rntc:35.714k ADC code:3200 Input voltage:937500uV
|
||||
-8248, // T:-8.25 Rntc:39.231k ADC code:3264 Input voltage:956250uV
|
||||
-10419, // T:-10.42 Rntc:43.333k ADC code:3328 Input voltage:975000uV
|
||||
-12711, // T:-12.71 Rntc:48.182k ADC code:3392 Input voltage:993750uV
|
||||
-15137, // T:-15.14 Rntc:54.0k ADC code:3456 Input voltage:1012500uV
|
||||
-17727, // T:-17.73 Rntc:61.111k ADC code:3520 Input voltage:1031250uV
|
||||
-20519, // T:-20.52 Rntc:70.0k ADC code:3584 Input voltage:1050000uV
|
||||
-23562, // T:-23.56 Rntc:81.429k ADC code:3648 Input voltage:1068750uV
|
||||
-26937, // T:-26.94 Rntc:96.667k ADC code:3712 Input voltage:1087500uV
|
||||
-30762, // T:-30.76 Rntc:118.0k ADC code:3776 Input voltage:1106250uV
|
||||
-35224, // T:-35.22 Rntc:150.0k ADC code:3840 Input voltage:1125000uV
|
||||
-40677, // T:-40.68 Rntc:203.333k ADC code:3904 Input voltage:1143750uV
|
||||
-47755, // T:-47.76 Rntc:310.0k ADC code:3968 Input voltage:1162500uV
|
||||
-57225, // T:-57.23 Rntc:630.0k ADC code:4032 Input voltage:1181250uV
|
||||
-69859, // T:-69.86 Rntc:10000.0k ADC code:4096 Input voltage:1200000uV
|
||||
};
|
||||
#elif defined(NCP15WF104F03RC)
|
||||
static const int32_t gNTCLut[65] = {
|
||||
175093, // T:175.09 Rntc:0.0k ADC code:0 Input voltage:0uV
|
||||
140197, // T:140.2 Rntc:1.587k ADC code:64 Input voltage:18750uV
|
||||
116573, // T:116.57 Rntc:3.226k ADC code:128 Input voltage:37500uV
|
||||
102838, // T:102.84 Rntc:4.918k ADC code:192 Input voltage:56250uV
|
||||
93457, // T:93.46 Rntc:6.667k ADC code:256 Input voltage:75000uV
|
||||
86333, // T:86.33 Rntc:8.475k ADC code:320 Input voltage:93750uV
|
||||
80598, // T:80.6 Rntc:10.345k ADC code:384 Input voltage:112500uV
|
||||
75787, // T:75.79 Rntc:12.281k ADC code:448 Input voltage:131250uV
|
||||
71646, // T:71.65 Rntc:14.286k ADC code:512 Input voltage:150000uV
|
||||
67994, // T:67.99 Rntc:16.364k ADC code:576 Input voltage:168750uV
|
||||
64720, // T:64.72 Rntc:18.519k ADC code:640 Input voltage:187500uV
|
||||
61757, // T:61.76 Rntc:20.755k ADC code:704 Input voltage:206250uV
|
||||
59039, // T:59.04 Rntc:23.077k ADC code:768 Input voltage:225000uV
|
||||
56524, // T:56.52 Rntc:25.49k ADC code:832 Input voltage:243750uV
|
||||
54178, // T:54.18 Rntc:28.0k ADC code:896 Input voltage:262500uV
|
||||
51977, // T:51.98 Rntc:30.612k ADC code:960 Input voltage:281250uV
|
||||
49898, // T:49.9 Rntc:33.333k ADC code:1024 Input voltage:300000uV
|
||||
47928, // T:47.93 Rntc:36.17k ADC code:1088 Input voltage:318750uV
|
||||
46050, // T:46.05 Rntc:39.13k ADC code:1152 Input voltage:337500uV
|
||||
44250, // T:44.25 Rntc:42.222k ADC code:1216 Input voltage:356250uV
|
||||
42521, // T:42.52 Rntc:45.455k ADC code:1280 Input voltage:375000uV
|
||||
40853, // T:40.85 Rntc:48.837k ADC code:1344 Input voltage:393750uV
|
||||
39240, // T:39.24 Rntc:52.381k ADC code:1408 Input voltage:412500uV
|
||||
37676, // T:37.68 Rntc:56.098k ADC code:1472 Input voltage:431250uV
|
||||
36155, // T:36.16 Rntc:60.0k ADC code:1536 Input voltage:450000uV
|
||||
34671, // T:34.67 Rntc:64.103k ADC code:1600 Input voltage:468750uV
|
||||
33220, // T:33.22 Rntc:68.421k ADC code:1664 Input voltage:487500uV
|
||||
31797, // T:31.8 Rntc:72.973k ADC code:1728 Input voltage:506250uV
|
||||
30400, // T:30.4 Rntc:77.778k ADC code:1792 Input voltage:525000uV
|
||||
29025, // T:29.03 Rntc:82.857k ADC code:1856 Input voltage:543750uV
|
||||
27669, // T:27.67 Rntc:88.235k ADC code:1920 Input voltage:562500uV
|
||||
26328, // T:26.33 Rntc:93.939k ADC code:1984 Input voltage:581250uV
|
||||
24999, // T:25.0 Rntc:100.0k ADC code:2048 Input voltage:600000uV
|
||||
23681, // T:23.68 Rntc:106.452k ADC code:2112 Input voltage:618750uV
|
||||
22370, // T:22.37 Rntc:113.333k ADC code:2176 Input voltage:637500uV
|
||||
21064, // T:21.06 Rntc:120.69k ADC code:2240 Input voltage:656250uV
|
||||
19760, // T:19.76 Rntc:128.571k ADC code:2304 Input voltage:675000uV
|
||||
18455, // T:18.46 Rntc:137.037k ADC code:2368 Input voltage:693750uV
|
||||
17148, // T:17.15 Rntc:146.154k ADC code:2432 Input voltage:712500uV
|
||||
15835, // T:15.84 Rntc:156.0k ADC code:2496 Input voltage:731250uV
|
||||
14513, // T:14.51 Rntc:166.667k ADC code:2560 Input voltage:750000uV
|
||||
13179, // T:13.18 Rntc:178.261k ADC code:2624 Input voltage:768750uV
|
||||
11830, // T:11.83 Rntc:190.909k ADC code:2688 Input voltage:787500uV
|
||||
10463, // T:10.46 Rntc:204.762k ADC code:2752 Input voltage:806250uV
|
||||
9074, // T:9.07 Rntc:220.0k ADC code:2816 Input voltage:825000uV
|
||||
7658, // T:7.66 Rntc:236.842k ADC code:2880 Input voltage:843750uV
|
||||
6211, // T:6.21 Rntc:255.556k ADC code:2944 Input voltage:862500uV
|
||||
4728, // T:4.73 Rntc:276.471k ADC code:3008 Input voltage:881250uV
|
||||
3202, // T:3.2 Rntc:300.0k ADC code:3072 Input voltage:900000uV
|
||||
1626, // T:1.63 Rntc:326.667k ADC code:3136 Input voltage:918750uV
|
||||
-6, // T:-0.01 Rntc:357.143k ADC code:3200 Input voltage:937500uV
|
||||
-1710, // T:-1.71 Rntc:392.308k ADC code:3264 Input voltage:956250uV
|
||||
-3495, // T:-3.5 Rntc:433.333k ADC code:3328 Input voltage:975000uV
|
||||
-5376, // T:-5.38 Rntc:481.818k ADC code:3392 Input voltage:993750uV
|
||||
-7371, // T:-7.37 Rntc:540.0k ADC code:3456 Input voltage:1012500uV
|
||||
-9506, // T:-9.51 Rntc:611.111k ADC code:3520 Input voltage:1031250uV
|
||||
-11819, // T:-11.82 Rntc:700.0k ADC code:3584 Input voltage:1050000uV
|
||||
-14354, // T:-14.35 Rntc:814.286k ADC code:3648 Input voltage:1068750uV
|
||||
-17179, // T:-17.18 Rntc:966.667k ADC code:3712 Input voltage:1087500uV
|
||||
-20397, // T:-20.4 Rntc:1180.0k ADC code:3776 Input voltage:1106250uV
|
||||
-24176, // T:-24.18 Rntc:1500.0k ADC code:3840 Input voltage:1125000uV
|
||||
-28836, // T:-28.84 Rntc:2033.333k ADC code:3904 Input voltage:1143750uV
|
||||
-35053, // T:-35.05 Rntc:3100.0k ADC code:3968 Input voltage:1162500uV
|
||||
-44840, // T:-44.84 Rntc:6300.0k ADC code:4032 Input voltage:1181250uV
|
||||
-63302, // T:-63.3 Rntc:100000.0k ADC code:4096 Input voltage:1200000uV
|
||||
};
|
||||
|
||||
#else
|
||||
#error "NTC type is not defined"
|
||||
#endif
|
||||
|
||||
|
||||
int32_t ntcGetTemperature(int32_t adcInputVoltage)
|
||||
{
|
||||
if(adcInputVoltage <= 1200000)
|
||||
{
|
||||
int32_t step = 1200000 >> 6;
|
||||
int32_t i = adcInputVoltage / step;
|
||||
return gNTCLut[i] + ((int32_t)((gNTCLut[i + 1] - gNTCLut[i]) * (adcInputVoltage - (i * step))) / step);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -256000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,851 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
|
||||
* File name: plat_config.c
|
||||
* Description: platform configuration source file
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "plat_config.h"
|
||||
#include "exception_process.h"
|
||||
#ifdef FEATURE_BOOTLOADER_PROJECT_ENABLE
|
||||
#include "debug_trace.h"
|
||||
#include "common.h"
|
||||
#else
|
||||
#include DEBUG_LOG_HEADER_FILE
|
||||
#include "osasys.h"
|
||||
|
||||
#define PLAT_CONFIG_FS_ENABLE
|
||||
#endif
|
||||
|
||||
/** \brief config file version
|
||||
* \note when the order of struct \ref plat_config_fs_t and \ref plat_config_raw_flash_t field has changed,
|
||||
* for example, from 1,2,3 to 1,3,2, update version to refresh flash,
|
||||
* in other cases(add more fields or remove some fields from struct \ref plat_config_fs_t), it's not a must to update
|
||||
*/
|
||||
|
||||
// external API declarations
|
||||
extern uint8_t BSP_QSPI_Erase_Safe(uint32_t SectorAddress, uint32_t Size);
|
||||
extern uint8_t BSP_QSPI_Write_Safe(uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
|
||||
extern uint8_t BSP_QSPI_Erase_Sector(uint32_t BlockAddress);
|
||||
extern uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
|
||||
extern uint8_t getOSState(void);
|
||||
|
||||
|
||||
/**
|
||||
\fn uint8_t BSP_CalcCrcValue(const uint8_t *buf, uint16_t bufSize)
|
||||
\brief Calculate the "CRC" value of data buffer
|
||||
\param[in] buf buffer pointer
|
||||
\param[in] bufSize buffer size
|
||||
\returns crcValue
|
||||
*/
|
||||
static uint8_t BSP_CalcCrcValue(const uint8_t *buf, uint16_t bufSize)
|
||||
{
|
||||
uint32_t i = bufSize;
|
||||
uint32_t a = 1, b = 0;
|
||||
|
||||
EC_ASSERT(buf != NULL && bufSize > 0, buf, bufSize, 0);
|
||||
|
||||
for (i = bufSize; i > 0; )
|
||||
{
|
||||
a += (uint32_t)(buf[--i]);
|
||||
b += a;
|
||||
}
|
||||
|
||||
return (uint8_t)(((a>>24)&0xFF)^((a>>16)&0xFF)^((a>>8)&0xFF)^((a)&0xFF)^
|
||||
((b>>24)&0xFF)^((b>>16)&0xFF)^((b>>8)&0xFF)^((b)&0xFF)^
|
||||
(bufSize&0xFF));
|
||||
}
|
||||
|
||||
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
static uint8_t g_fsPlatConfigInitFlag = 0;
|
||||
static plat_config_fs_t g_fsPlatConfig;
|
||||
|
||||
/**
|
||||
\fn void BSP_SetDefaultFsPlatConfig(void)
|
||||
\brief set default value of "g_fsPlatConfig"
|
||||
\return void
|
||||
*/
|
||||
static void BSP_SetDefaultFsPlatConfig(void)
|
||||
{
|
||||
g_fsPlatConfigInitFlag = 1;
|
||||
|
||||
memset(&g_fsPlatConfig, 0x0, sizeof(g_fsPlatConfig));
|
||||
g_fsPlatConfig.atPortBaudRate = 115200;
|
||||
}
|
||||
|
||||
void BSP_LoadPlatConfigFromFs(void)
|
||||
{
|
||||
OSAFILE fp = PNULL;
|
||||
UINT32 readCount = 0;
|
||||
UINT8 crcCheck = 0;
|
||||
config_file_header_t fileHeader;
|
||||
|
||||
/*
|
||||
* open NVM file
|
||||
*/
|
||||
fp = OsaFopen("plat_config", "rb"); //read only
|
||||
if (fp == PNULL)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_LoadPlatConfig_1, P_ERROR,
|
||||
"Can't open 'plat_config' file, use the defult value");
|
||||
|
||||
BSP_SetDefaultFsPlatConfig();
|
||||
BSP_SavePlatConfigToFs();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* read file header
|
||||
*/
|
||||
readCount = OsaFread(&fileHeader, sizeof(config_file_header_t), 1, fp);
|
||||
if (readCount != 1)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_LoadPlatConfig_2, P_ERROR,
|
||||
"Can't read 'plat_config' file header, use the defult value");
|
||||
|
||||
OsaFclose(fp);
|
||||
|
||||
BSP_SetDefaultFsPlatConfig();
|
||||
BSP_SavePlatConfigToFs();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* read file body, check validation and handle compatiblity issue
|
||||
*/
|
||||
if(fileHeader.version != FS_PLAT_CONFIG_FILE_CURRENT_VERSION)
|
||||
{
|
||||
if(fileHeader.version == 0)
|
||||
{
|
||||
}
|
||||
// handle future version below
|
||||
else if(0)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_LoadPlatConfig_5, P_ERROR,
|
||||
"'plat_config' version:%d not right, use the defult value", fileHeader.version);
|
||||
|
||||
OsaFclose(fp);
|
||||
|
||||
BSP_SetDefaultFsPlatConfig();
|
||||
BSP_SavePlatConfigToFs();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fileHeader.fileBodySize != sizeof(g_fsPlatConfig))
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_LoadPlatConfig_3, P_ERROR,
|
||||
"'plat_config' version:%d file body size not right: (%u/%u), use the defult value",
|
||||
fileHeader.version, fileHeader.fileBodySize, sizeof(plat_config_fs_t));
|
||||
|
||||
OsaFclose(fp);
|
||||
|
||||
BSP_SetDefaultFsPlatConfig();
|
||||
BSP_SavePlatConfigToFs();
|
||||
}
|
||||
else
|
||||
{
|
||||
readCount = OsaFread(&g_fsPlatConfig, sizeof(g_fsPlatConfig), 1, fp);
|
||||
crcCheck = BSP_CalcCrcValue((uint8_t *)&g_fsPlatConfig, sizeof(g_fsPlatConfig));
|
||||
|
||||
OsaFclose(fp);
|
||||
|
||||
if (readCount != 1 || crcCheck != fileHeader.checkSum)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_LoadPlatConfig_4, P_ERROR,
|
||||
"Can't read 'plat_config' version:%d file body, or body not right, (%u/%u), use the defult value",
|
||||
fileHeader.version, crcCheck, fileHeader.checkSum);
|
||||
|
||||
BSP_SetDefaultFsPlatConfig();
|
||||
BSP_SavePlatConfigToFs();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_fsPlatConfigInitFlag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void BSP_SetFsPorDefaultValue(void)
|
||||
{
|
||||
bool fsCfgChanged = false;
|
||||
if(g_fsPlatConfig.ecSclkCfg != 0)
|
||||
{
|
||||
g_fsPlatConfig.ecSclkCfg = 0;
|
||||
fsCfgChanged = true;
|
||||
}
|
||||
if(fsCfgChanged)
|
||||
{
|
||||
BSP_SavePlatConfigToFs();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BSP_SavePlatConfigToFs(void)
|
||||
{
|
||||
OSAFILE fp = PNULL;
|
||||
UINT32 writeCount = 0;
|
||||
config_file_header_t fileHeader;
|
||||
|
||||
/*
|
||||
* open the config file
|
||||
*/
|
||||
fp = OsaFopen("plat_config", "wb"); //write & create
|
||||
if (fp == PNULL)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SavePlatConfig_1, P_ERROR,
|
||||
"Can't open/create 'plat_config' file, save plat_config failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* write the header
|
||||
*/
|
||||
fileHeader.fileBodySize = sizeof(g_fsPlatConfig);
|
||||
fileHeader.version = FS_PLAT_CONFIG_FILE_CURRENT_VERSION;
|
||||
fileHeader.checkSum = BSP_CalcCrcValue((uint8_t *)&g_fsPlatConfig, sizeof(g_fsPlatConfig));
|
||||
|
||||
writeCount = OsaFwrite(&fileHeader, sizeof(config_file_header_t), 1, fp);
|
||||
if (writeCount != 1)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SavePlatConfig_2, P_ERROR,
|
||||
"Write 'plat_config' file header failed");
|
||||
|
||||
OsaFclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* write the file body
|
||||
*/
|
||||
writeCount = OsaFwrite(&g_fsPlatConfig, sizeof(g_fsPlatConfig), 1, fp);
|
||||
if (writeCount != 1)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SavePlatConfig_3, P_ERROR,
|
||||
"Write 'plat_config' file body failed");
|
||||
}
|
||||
|
||||
OsaFclose(fp);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
plat_config_fs_t* BSP_GetFsPlatConfig(void)
|
||||
{
|
||||
return &g_fsPlatConfig;
|
||||
}
|
||||
|
||||
uint32_t BSP_GetFSAssertCount(void)
|
||||
{
|
||||
plat_info_layout_t platInfo;
|
||||
|
||||
// read
|
||||
memcpy((uint8_t*)&platInfo, (void*)FLASH_MEM_PLAT_INFO_ADDR, sizeof(plat_info_layout_t));
|
||||
|
||||
return platInfo.fsAssertCount;
|
||||
}
|
||||
|
||||
void BSP_SetFSAssertCount(uint32_t value)
|
||||
{
|
||||
plat_info_layout_t platInfo;
|
||||
|
||||
// read
|
||||
memcpy((uint8_t*)&platInfo, (void*)FLASH_MEM_PLAT_INFO_ADDR, sizeof(plat_info_layout_t));
|
||||
|
||||
// modify
|
||||
platInfo.fsAssertCount = value;
|
||||
|
||||
// erase
|
||||
if(BSP_QSPI_Erase_Safe(FLASH_MEM_PLAT_INFO_NONXIP_ADDR, FLASH_MEM_PLAT_INFO_SIZE) != 0)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SetFSAssertCount_0, P_ERROR, "Erase flash error!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
// write back
|
||||
if(BSP_QSPI_Write_Safe((uint8_t*)&platInfo, FLASH_MEM_PLAT_INFO_NONXIP_ADDR, sizeof(plat_info_layout_t)) != 0)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SetFSAssertCount_1, P_ERROR, "Update fsAssertCount value error!!!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
plat_config_raw_flash_t g_rawFlashPlatConfig;
|
||||
|
||||
/**
|
||||
\fn void BSP_SetDefaultRawFlashPlatConfig(void)
|
||||
\brief set default value of "g_rawFlashPlatConfig"
|
||||
\return void
|
||||
*/
|
||||
static void BSP_SetDefaultRawFlashPlatConfig(void)
|
||||
{
|
||||
#ifdef __USER_CODE__
|
||||
g_rawFlashPlatConfig.faultAction = EXCEP_OPTION_DUMP_FLASH_RESET;//silent anable
|
||||
g_rawFlashPlatConfig.startWDT = 1;//start wdt
|
||||
g_rawFlashPlatConfig.uartDumpPort = 0xff; // default at port
|
||||
#else
|
||||
#ifdef SDK_REL_BUILD
|
||||
g_rawFlashPlatConfig.faultAction = 4;//silent anable
|
||||
g_rawFlashPlatConfig.startWDT = 1;//start wdt
|
||||
#else
|
||||
g_rawFlashPlatConfig.faultAction = 0;
|
||||
g_rawFlashPlatConfig.startWDT = 0;
|
||||
#endif
|
||||
|
||||
g_rawFlashPlatConfig.uartDumpPort = 1; // default at port
|
||||
#endif
|
||||
g_rawFlashPlatConfig.logControl = 0x2;
|
||||
|
||||
g_rawFlashPlatConfig.uartBaudRate = 3000000;
|
||||
|
||||
g_rawFlashPlatConfig.logLevel = P_DEBUG;
|
||||
|
||||
g_rawFlashPlatConfig.logPortSel = PLAT_CFG_ULG_PORT_MIX;//default MIX mode
|
||||
|
||||
g_rawFlashPlatConfig.usbCtrl = 0;//all en
|
||||
|
||||
g_rawFlashPlatConfig.usbSlpMask = 0; // no mask
|
||||
|
||||
g_rawFlashPlatConfig.usbSlpThd = 0;
|
||||
|
||||
g_rawFlashPlatConfig.pwrKeyMode = 0;
|
||||
|
||||
g_rawFlashPlatConfig.usbVBUSModeEn = 0;
|
||||
|
||||
g_rawFlashPlatConfig.usbVBUSWkupPad = 1;
|
||||
|
||||
g_rawFlashPlatConfig.usbNet = 0;
|
||||
|
||||
g_rawFlashPlatConfig.usbVcomEnBitMap = 0;
|
||||
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
g_rawFlashPlatConfig.atPortBaudRate = g_fsPlatConfigInitFlag ? g_fsPlatConfig.atPortBaudRate : 115200;
|
||||
#else
|
||||
g_rawFlashPlatConfig.atPortBaudRate = 115200;
|
||||
#endif
|
||||
g_rawFlashPlatConfig.fotaUrcPortSel = (PLAT_CFG_FOTA_URC_PORT_USB << 4) | 0;
|
||||
|
||||
g_rawFlashPlatConfig.pmuInCdrx = 1;
|
||||
|
||||
g_rawFlashPlatConfig.slpLimitEn = 0;
|
||||
|
||||
g_rawFlashPlatConfig.slpLimitTime = 0;
|
||||
|
||||
memset(g_rawFlashPlatConfig.resv, 0x0,PLAT_CFG_RAW_FLASH_RSVD_SIZE);
|
||||
}
|
||||
|
||||
void BSP_SavePlatConfigToRawFlash(void)
|
||||
{
|
||||
plat_info_layout_t platInfo;
|
||||
|
||||
// read
|
||||
memcpy((uint8_t*)&platInfo, (void*)FLASH_MEM_PLAT_INFO_ADDR, sizeof(plat_info_layout_t));
|
||||
|
||||
// modify start //
|
||||
// header part
|
||||
platInfo.header.fileBodySize = sizeof(plat_config_raw_flash_t);
|
||||
platInfo.header.version = RAW_FLASH_PLAT_CONFIG_FILE_CURRENT_VERSION;
|
||||
platInfo.header.checkSum = BSP_CalcCrcValue((uint8_t *)&g_rawFlashPlatConfig, sizeof(g_rawFlashPlatConfig));
|
||||
|
||||
// body part
|
||||
platInfo.config = g_rawFlashPlatConfig;
|
||||
// modify end //
|
||||
|
||||
// write back
|
||||
|
||||
#ifndef FEATURE_BOOTLOADER_PROJECT_ENABLE
|
||||
if(1 == getOSState())
|
||||
{
|
||||
if(BSP_QSPI_Erase_Safe(FLASH_MEM_PLAT_INFO_NONXIP_ADDR, FLASH_MEM_PLAT_INFO_SIZE) != 0)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SavePlatConfigToRawFlash_1, P_ERROR, "Erase flash error!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
if(BSP_QSPI_Write_Safe((uint8_t*)&platInfo, FLASH_MEM_PLAT_INFO_NONXIP_ADDR, sizeof(plat_info_layout_t)) != 0)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SavePlatConfigToRawFlash_2, P_ERROR, "Save plat config to raw flash error!!!");
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(BSP_QSPI_Erase_Sector(FLASH_MEM_PLAT_INFO_NONXIP_ADDR) != 0)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SavePlatConfigToRawFlash_3, P_ERROR, "Erase flash error!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
if(BSP_QSPI_Write((uint8_t*)&platInfo, FLASH_MEM_PLAT_INFO_NONXIP_ADDR, sizeof(plat_info_layout_t)) != 0)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SavePlatConfigToRawFlash_4, P_ERROR, "Save plat config to raw flash error!!!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void BSP_WriteToRawFlash(uint8_t* pBuffer, uint32_t bufferSize)
|
||||
{
|
||||
if(pBuffer == NULL || bufferSize == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef FEATURE_BOOTLOADER_PROJECT_ENABLE
|
||||
if(1 == getOSState())
|
||||
{
|
||||
if(BSP_QSPI_Erase_Safe(FLASH_MEM_PLAT_INFO_NONXIP_ADDR, FLASH_MEM_PLAT_INFO_SIZE) != 0)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_WriteToRawFlash_1, P_ERROR, "Erase flash error!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
if(BSP_QSPI_Write_Safe(pBuffer, FLASH_MEM_PLAT_INFO_NONXIP_ADDR, bufferSize) != 0)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_WriteToRawFlash_2, P_ERROR, "Save plat config to raw flash error!!!");
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(BSP_QSPI_Erase_Sector(FLASH_MEM_PLAT_INFO_NONXIP_ADDR) != 0)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_WriteToRawFlash_3, P_ERROR, "Erase flash error!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
if(BSP_QSPI_Write(pBuffer, FLASH_MEM_PLAT_INFO_NONXIP_ADDR, bufferSize) != 0)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_WriteToRawFlash_4, P_ERROR, "Save plat config to raw flash error!!!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BSP_LoadPlatConfigFromRawFlash(void)
|
||||
{
|
||||
plat_info_layout_t platInfo;
|
||||
config_file_header_t header;
|
||||
uint32_t fsAssertCount;
|
||||
|
||||
/*
|
||||
* read file header
|
||||
*/
|
||||
memcpy((uint8_t*)&header, (void*)FLASH_MEM_PLAT_INFO_ADDR, sizeof(header));
|
||||
|
||||
if(header.version != RAW_FLASH_PLAT_CONFIG_FILE_CURRENT_VERSION)
|
||||
{
|
||||
if(header.version == 0)
|
||||
{
|
||||
plat_config_raw_flash_v0_t v0Config;
|
||||
|
||||
BSP_SetDefaultRawFlashPlatConfig();
|
||||
|
||||
// migrate from old version
|
||||
if(header.fileBodySize == sizeof(plat_config_raw_flash_v0_t))
|
||||
{
|
||||
memcpy((uint8_t*)&v0Config, (void*)(FLASH_MEM_PLAT_INFO_ADDR + sizeof(config_file_header_t)), sizeof(v0Config));
|
||||
memcpy((uint8_t*)&fsAssertCount, (void*)(FLASH_MEM_PLAT_INFO_ADDR + sizeof(config_file_header_t) + sizeof(v0Config)), sizeof(fsAssertCount));
|
||||
|
||||
g_rawFlashPlatConfig.faultAction = v0Config.faultAction;
|
||||
g_rawFlashPlatConfig.uartDumpPort = v0Config.uartDumpPort;
|
||||
g_rawFlashPlatConfig.startWDT = v0Config.startWDT;
|
||||
g_rawFlashPlatConfig.logControl = v0Config.logControl;
|
||||
g_rawFlashPlatConfig.uartBaudRate = v0Config.uartBaudRate;
|
||||
g_rawFlashPlatConfig.logLevel = v0Config.logLevel;
|
||||
g_rawFlashPlatConfig.logPortSel = v0Config.logPortSel;
|
||||
g_rawFlashPlatConfig.usbCtrl = v0Config.usbCtrl;
|
||||
g_rawFlashPlatConfig.usbSwTrace = v0Config.usbSwTrace;
|
||||
g_rawFlashPlatConfig.usbSlpMask = v0Config.usbSlpMask;
|
||||
g_rawFlashPlatConfig.usbSlpThd = v0Config.usbSlpThd;
|
||||
g_rawFlashPlatConfig.pwrKeyMode = v0Config.pwrKeyMode;
|
||||
|
||||
platInfo.header.fileBodySize = sizeof(plat_config_raw_flash_t);
|
||||
platInfo.header.version = RAW_FLASH_PLAT_CONFIG_FILE_CURRENT_VERSION;
|
||||
platInfo.header.checkSum = BSP_CalcCrcValue((uint8_t *)&g_rawFlashPlatConfig, sizeof(g_rawFlashPlatConfig));
|
||||
|
||||
platInfo.config = g_rawFlashPlatConfig;
|
||||
|
||||
platInfo.fsAssertCount = fsAssertCount;
|
||||
|
||||
}
|
||||
// version matches but size is wrong, use default value
|
||||
else
|
||||
{
|
||||
platInfo.header.fileBodySize = sizeof(plat_config_raw_flash_t);
|
||||
platInfo.header.version = RAW_FLASH_PLAT_CONFIG_FILE_CURRENT_VERSION;
|
||||
platInfo.header.checkSum = BSP_CalcCrcValue((uint8_t *)&g_rawFlashPlatConfig, sizeof(g_rawFlashPlatConfig));
|
||||
|
||||
platInfo.config = g_rawFlashPlatConfig;
|
||||
platInfo.fsAssertCount = 0;
|
||||
}
|
||||
|
||||
BSP_WriteToRawFlash((uint8_t*)&platInfo, sizeof(platInfo));
|
||||
|
||||
}
|
||||
else if(0)
|
||||
{
|
||||
// handle future version
|
||||
}
|
||||
else
|
||||
{
|
||||
// version is invalid
|
||||
|
||||
BSP_SetDefaultRawFlashPlatConfig();
|
||||
|
||||
platInfo.header.fileBodySize = sizeof(plat_config_raw_flash_t);
|
||||
platInfo.header.version = RAW_FLASH_PLAT_CONFIG_FILE_CURRENT_VERSION;
|
||||
platInfo.header.checkSum = BSP_CalcCrcValue((uint8_t *)&g_rawFlashPlatConfig, sizeof(g_rawFlashPlatConfig));
|
||||
|
||||
platInfo.config = g_rawFlashPlatConfig;
|
||||
platInfo.fsAssertCount = 0;
|
||||
|
||||
BSP_WriteToRawFlash((uint8_t*)&platInfo, sizeof(platInfo));
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// file body check
|
||||
memcpy((uint8_t*)&g_rawFlashPlatConfig, (void*)(FLASH_MEM_PLAT_INFO_ADDR + sizeof(config_file_header_t)), sizeof(g_rawFlashPlatConfig));
|
||||
|
||||
if((header.fileBodySize != sizeof(plat_config_raw_flash_t)) ||
|
||||
(header.checkSum != BSP_CalcCrcValue((uint8_t *)&g_rawFlashPlatConfig, sizeof(g_rawFlashPlatConfig))))
|
||||
{
|
||||
|
||||
BSP_SetDefaultRawFlashPlatConfig();
|
||||
|
||||
platInfo.header.fileBodySize = sizeof(plat_config_raw_flash_t);
|
||||
platInfo.header.version = RAW_FLASH_PLAT_CONFIG_FILE_CURRENT_VERSION;
|
||||
platInfo.header.checkSum = BSP_CalcCrcValue((uint8_t *)&g_rawFlashPlatConfig, sizeof(g_rawFlashPlatConfig));
|
||||
|
||||
platInfo.config = g_rawFlashPlatConfig;
|
||||
platInfo.fsAssertCount = 0;
|
||||
|
||||
BSP_WriteToRawFlash((uint8_t*)&platInfo, sizeof(platInfo));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
if(g_fsPlatConfigInitFlag && g_fsPlatConfig.atPortBaudRate != g_rawFlashPlatConfig.atPortBaudRate)
|
||||
{
|
||||
g_rawFlashPlatConfig.atPortBaudRate = g_fsPlatConfig.atPortBaudRate;
|
||||
|
||||
memcpy((uint8_t*)&fsAssertCount, (void*)(FLASH_MEM_PLAT_INFO_ADDR + sizeof(config_file_header_t) + sizeof(g_rawFlashPlatConfig)), sizeof(fsAssertCount));
|
||||
platInfo.header.fileBodySize = sizeof(plat_config_raw_flash_t);
|
||||
platInfo.header.version = RAW_FLASH_PLAT_CONFIG_FILE_CURRENT_VERSION;
|
||||
platInfo.header.checkSum = BSP_CalcCrcValue((uint8_t *)&g_rawFlashPlatConfig, sizeof(g_rawFlashPlatConfig));
|
||||
|
||||
platInfo.config = g_rawFlashPlatConfig;
|
||||
platInfo.fsAssertCount = fsAssertCount;
|
||||
|
||||
BSP_WriteToRawFlash((uint8_t*)&platInfo, sizeof(platInfo));
|
||||
}
|
||||
#else
|
||||
/* do nothing! */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
plat_config_raw_flash_t* BSP_GetRawFlashPlatConfig(void)
|
||||
{
|
||||
return &g_rawFlashPlatConfig;
|
||||
}
|
||||
|
||||
uint32_t BSP_GetPlatConfigItemValue(plat_config_id_t id)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case PLAT_CONFIG_ITEM_FAULT_ACTION:
|
||||
return g_rawFlashPlatConfig.faultAction;
|
||||
|
||||
case PLAT_CONFIG_ITEM_UART_DUMP_PORT:
|
||||
return g_rawFlashPlatConfig.uartDumpPort;
|
||||
|
||||
case PLAT_CONFIG_ITEM_START_WDT:
|
||||
return g_rawFlashPlatConfig.startWDT;
|
||||
|
||||
case PLAT_CONFIG_ITEM_LOG_CONTROL:
|
||||
return g_rawFlashPlatConfig.logControl;
|
||||
|
||||
case PLAT_CONFIG_ITEM_LOG_BAUDRATE:
|
||||
return g_rawFlashPlatConfig.uartBaudRate;
|
||||
|
||||
case PLAT_CONFIG_ITEM_LOG_LEVEL:
|
||||
return g_rawFlashPlatConfig.logLevel;
|
||||
|
||||
case PLAT_CONFIG_ITEM_ENABLE_PM:
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
return g_fsPlatConfig.enablePM;
|
||||
#else
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_GET_PLAT_CFG_0, P_ERROR, "Get enablePM unsupported yet!");
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case PLAT_CONFIG_ITEM_SLEEP_MODE:
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
return g_fsPlatConfig.sleepMode;
|
||||
#else
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_GET_PLAT_CFG_1, P_ERROR, "Get sleepMode unsupported yet!");
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case PLAT_CONFIG_ITEM_WAIT_SLEEP:
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
return g_fsPlatConfig.slpWaitTime;
|
||||
#else
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_GET_PLAT_CFG_2, P_ERROR, "Get slpWaitTime unsupported yet!");
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case PLAT_CONFIG_ITEM_AT_PORT_BAUDRATE:
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
#if 0
|
||||
EC_ASSERT(g_fsPlatConfig.atPortBaudRate == g_rawFlashPlatConfig.atPortBaudRate,
|
||||
g_fsPlatConfig.atPortBaudRate, g_rawFlashPlatConfig.atPortBaudRate, 0);
|
||||
#else
|
||||
if(g_fsPlatConfig.atPortBaudRate != g_rawFlashPlatConfig.atPortBaudRate)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_GET_PLAT_CFG_3, P_WARNING, "non-identical baud between fs(%d) & raw(%d)!",
|
||||
g_fsPlatConfig.atPortBaudRate, g_rawFlashPlatConfig.atPortBaudRate);
|
||||
}
|
||||
#endif
|
||||
return g_fsPlatConfig.atPortBaudRate;
|
||||
#else
|
||||
return g_rawFlashPlatConfig.atPortBaudRate;
|
||||
#endif
|
||||
|
||||
case PLAT_CONFIG_ITEM_AT_PORT_FRAME_FORMAT:
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
return g_fsPlatConfig.atPortFrameFormat.wholeValue;
|
||||
#else
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_GET_PLAT_CFG_4, P_ERROR, "Get atPortFrameFormat unsupported yet!");
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case PLAT_CONFIG_ITEM_ECSCLK_CFG:
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
return g_fsPlatConfig.ecSclkCfg;
|
||||
#else
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_GET_PLAT_CFG_5, P_ERROR, "Get ecSclkCfg unsupported yet!");
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case PLAT_CONFIG_ITEM_LOG_PORT_SEL:
|
||||
return g_rawFlashPlatConfig.logPortSel;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_CTRL:
|
||||
return g_rawFlashPlatConfig.usbCtrl;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_SW_TRACE_FLAG:
|
||||
return g_rawFlashPlatConfig.usbSwTrace;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_SLEEP_MASK:
|
||||
return g_rawFlashPlatConfig.usbSlpMask;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_SLEEP_THD:
|
||||
return g_rawFlashPlatConfig.usbSlpThd;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_VBUS_MODE_EN:
|
||||
return g_rawFlashPlatConfig.usbVBUSModeEn;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_VBUS_WKUP_PAD:
|
||||
return g_rawFlashPlatConfig.usbVBUSWkupPad;
|
||||
|
||||
case PLAT_CONFIG_ITEM_PWRKEY_MODE:
|
||||
return g_rawFlashPlatConfig.pwrKeyMode;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_NET:
|
||||
return g_rawFlashPlatConfig.usbNet;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_VCOM_EN_BMP:
|
||||
return g_rawFlashPlatConfig.usbVcomEnBitMap;
|
||||
|
||||
case PLAT_CONFIG_ITEM_FOTA_URC_PORT_SEL:
|
||||
return g_rawFlashPlatConfig.fotaUrcPortSel;
|
||||
|
||||
case PLAT_CONFIG_ITEM_PMUINCDRX:
|
||||
return g_rawFlashPlatConfig.pmuInCdrx;
|
||||
|
||||
case PLAT_CONFIG_ITEM_SLP_LIMIT_EN:
|
||||
return g_rawFlashPlatConfig.slpLimitEn;
|
||||
|
||||
case PLAT_CONFIG_ITEM_SLP_LIMIT_TIME:
|
||||
return g_rawFlashPlatConfig.slpLimitTime;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void BSP_SetPlatConfigItemValue(plat_config_id_t id, uint32_t value)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case PLAT_CONFIG_ITEM_FAULT_ACTION:
|
||||
if(value <= (EXCEP_OPTION_MAX -1))
|
||||
g_rawFlashPlatConfig.faultAction = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_UART_DUMP_PORT:
|
||||
g_rawFlashPlatConfig.uartDumpPort = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_START_WDT:
|
||||
if(value <= 1)
|
||||
g_rawFlashPlatConfig.startWDT = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_LOG_CONTROL:
|
||||
if(value <= 2)
|
||||
g_rawFlashPlatConfig.logControl = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_LOG_BAUDRATE:
|
||||
g_rawFlashPlatConfig.uartBaudRate = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_LOG_LEVEL:
|
||||
if(value <= P_ERROR)
|
||||
g_rawFlashPlatConfig.logLevel = (DebugTraceLevelType_e)value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_ENABLE_PM:
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
g_fsPlatConfig.enablePM = value;
|
||||
#else
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SET_PLAT_CFG_0, P_ERROR, "Set enablePM unsupported yet!");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_SLEEP_MODE:
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
if(value <= 4) g_fsPlatConfig.sleepMode = value;
|
||||
#else
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SET_PLAT_CFG_1, P_ERROR, "Set sleepMode unsupported yet!");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_WAIT_SLEEP:
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
g_fsPlatConfig.slpWaitTime = value;
|
||||
#else
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SET_PLAT_CFG_2, P_ERROR, "Set slpWaitTime unsupported yet!");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_AT_PORT_BAUDRATE:
|
||||
g_rawFlashPlatConfig.atPortBaudRate = value;
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
g_fsPlatConfig.atPortBaudRate = value;
|
||||
#else
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SET_PLAT_CFG_3, P_ERROR, "Set atPortBaudRate unsupported yet!");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_AT_PORT_FRAME_FORMAT:
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
g_fsPlatConfig.atPortFrameFormat.wholeValue = value;
|
||||
#else
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SET_PLAT_CFG_4, P_ERROR, "Set atPortFrameFormat unsupported yet!");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_ECSCLK_CFG:
|
||||
#ifdef PLAT_CONFIG_FS_ENABLE
|
||||
g_fsPlatConfig.ecSclkCfg = value;
|
||||
#else
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_SET_PLAT_CFG_5, P_ERROR, "Set ecSclkCfg unsupported yet!");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_LOG_PORT_SEL:
|
||||
g_rawFlashPlatConfig.logPortSel = (PlatCfgUlgPort_e)value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_CTRL:
|
||||
g_rawFlashPlatConfig.usbCtrl = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_SW_TRACE_FLAG:
|
||||
g_rawFlashPlatConfig.usbSwTrace = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_SLEEP_MASK:
|
||||
g_rawFlashPlatConfig.usbSlpMask = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_SLEEP_THD:
|
||||
g_rawFlashPlatConfig.usbSlpThd = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_VBUS_MODE_EN:
|
||||
g_rawFlashPlatConfig.usbVBUSModeEn = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_VBUS_WKUP_PAD:
|
||||
g_rawFlashPlatConfig.usbVBUSWkupPad = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_PWRKEY_MODE:
|
||||
g_rawFlashPlatConfig.pwrKeyMode = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_NET:
|
||||
g_rawFlashPlatConfig.usbNet = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_USB_VCOM_EN_BMP:
|
||||
g_rawFlashPlatConfig.usbVcomEnBitMap = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_FOTA_URC_PORT_SEL:
|
||||
g_rawFlashPlatConfig.fotaUrcPortSel = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_PMUINCDRX:
|
||||
g_rawFlashPlatConfig.pmuInCdrx = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_SLP_LIMIT_EN:
|
||||
g_rawFlashPlatConfig.slpLimitEn = value;
|
||||
break;
|
||||
|
||||
case PLAT_CONFIG_ITEM_SLP_LIMIT_TIME:
|
||||
g_rawFlashPlatConfig.slpLimitTime = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
|
||||
* File name: adc.h
|
||||
* Description: EC618 adc driver header file
|
||||
* History:
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _ADC_EC618_H
|
||||
#define _ADC_EC618_H
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
|
||||
/**
|
||||
\addtogroup adc_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/** \brief List of ADC clock source divider */
|
||||
typedef enum
|
||||
{
|
||||
ADC_CLOCK_DIV_4 = 0U, /**< ADC clock is divided by 4 from input clock */
|
||||
ADC_CLOCK_DIV_8 = 1U, /**< ADC clock is divided by 8 from input clock */
|
||||
ADC_CLOCK_DIV_16 = 2U, /**< ADC clock is divided by 16 from input clock */
|
||||
} AdcClockDivider_e;
|
||||
|
||||
/** \brief List of ADC channels */
|
||||
typedef enum
|
||||
{
|
||||
ADC_CHANNEL_THERMAL = 0U, /**< ADC Thermal channel */
|
||||
ADC_CHANNEL_VBAT = 1U, /**< ADC VBAT channel */
|
||||
ADC_CHANNEL_AIO4 = 2U, /**< ADC AIO4 channel */
|
||||
ADC_CHANNEL_AIO3 = 3U, /**< ADC AIO3 channel */
|
||||
ADC_CHANNEL_AIO2 = 4U, /**< ADC AIO2 channel */
|
||||
ADC_CHANNEL_AIO1 = 5U, /**< ADC AIO1 channel */
|
||||
} AdcChannel_e;
|
||||
|
||||
/** \brief List of AIO resdiv select options */
|
||||
typedef enum
|
||||
{
|
||||
ADC_AIO_RESDIV_RATIO_1 = 0U, /**< ADC AIO RESDIV select as VIN */
|
||||
ADC_AIO_RESDIV_RATIO_14OVER16 = 1U, /**< ADC AIO RESDIV select as 14/16 VIN */
|
||||
ADC_AIO_RESDIV_RATIO_12OVER16 = 2U, /**< ADC AIO RESDIV select as 12/16 VIN */
|
||||
ADC_AIO_RESDIV_RATIO_10OVER16 = 3U, /**< ADC AIO RESDIV select as 10/16 VIN */
|
||||
ADC_AIO_RESDIV_RATIO_8OVER16 = 4U, /**< ADC AIO RESDIV select as 8/16 VIN */
|
||||
ADC_AIO_RESDIV_RATIO_7OVER16 = 5U, /**< ADC AIO RESDIV select as 7/16 VIN */
|
||||
ADC_AIO_RESDIV_RATIO_6OVER16 = 6U, /**< ADC AIO RESDIV select as 6/16 VIN */
|
||||
ADC_AIO_RESDIV_RATIO_5OVER16 = 7U, /**< ADC AIO RESDIV select as 5/16 VIN */
|
||||
ADC_AIO_RESDIV_RATIO_4OVER16 = 8U, /**< ADC AIO RESDIV select as 4/16 VIN */
|
||||
ADC_AIO_RESDIV_RATIO_3OVER16 = 9U, /**< ADC AIO RESDIV select as 3/16 VIN */
|
||||
ADC_AIO_RESDIV_RATIO_2OVER16 = 10U, /**< ADC AIO RESDIV select as 2/16 VIN */
|
||||
ADC_AIO_RESDIV_RATIO_1OVER16 = 11U, /**< ADC AIO RESDIV select as 1/16 VIN */
|
||||
ADC_AIO_RESDIV_BYPASS = 12U, /**< BYPASS the whole ADC AIO RESDIV network(direct input) */
|
||||
} AdcAioResDiv_e;
|
||||
|
||||
/** \brief List of VBAT resdiv select options */
|
||||
typedef enum
|
||||
{
|
||||
ADC_VBAT_RESDIV_RATIO_8OVER16 = 0U, /**< ADC AIO RESDIV select as 8/16 VBAT */
|
||||
ADC_VBAT_RESDIV_RATIO_7OVER16 = 1U, /**< ADC AIO RESDIV select as 7/16 VBAT */
|
||||
ADC_VBAT_RESDIV_RATIO_6OVER16 = 2U, /**< ADC AIO RESDIV select as 6/16 VBAT */
|
||||
ADC_VBAT_RESDIV_RATIO_5OVER16 = 3U, /**< ADC AIO RESDIV select as 5/16 VBAT */
|
||||
ADC_VBAT_RESDIV_RATIO_4OVER16 = 4U, /**< ADC AIO RESDIV select as 4/16 VBAT */
|
||||
ADC_VBAT_RESDIV_RATIO_3OVER16 = 5U, /**< ADC AIO RESDIV select as 3/16 VBAT */
|
||||
ADC_VBAT_RESDIV_RATIO_2OVER16 = 6U, /**< ADC AIO RESDIV select as 2/16 VBAT */
|
||||
ADC_VBAT_RESDIV_RATIO_1OVER16 = 7U, /**< ADC AIO RESDIV select as 1/16 VBAT */
|
||||
} AdcVbatResdiv_e;
|
||||
|
||||
/** \brief ADC channel configuration */
|
||||
typedef union
|
||||
{
|
||||
AdcAioResDiv_e aioResDiv; /**< resdiv setting, valid only for AIO channel */
|
||||
AdcVbatResdiv_e vbatResDiv; /**< resdiv setting, valid only for VBAT channel */
|
||||
} AdcChannelConfig_t;
|
||||
|
||||
/** \brief ADC configuration structure */
|
||||
typedef struct
|
||||
{
|
||||
AdcClockDivider_e clockDivider; /**< ADC work clock source divider setting */
|
||||
AdcChannelConfig_t channelConfig; /**< ADC channel configuration */
|
||||
} AdcConfig_t;
|
||||
|
||||
/** \brief List of ADC channel users, used to compose logical channel combining with ADC physical channel
|
||||
each channel can be occupied by these users at the same time, conversion request gets serviced one by one in FIFO ordering.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ADC_USER_PHY = 0U, /**< Internal user ID for PHY */
|
||||
ADC_USER_PLAT = 1U, /**< Internal user ID for PLAT */
|
||||
ADC_USER_APP = 2U, /**< user ID for APP */
|
||||
ADC_USER_MAX /**< Total number of users for one channel */
|
||||
} AdcUser_t;
|
||||
|
||||
|
||||
/**
|
||||
\brief Defines callback function prototype.
|
||||
Callback function will be called in ADC interrupt service routine after sample completes
|
||||
\param result ADC sample result
|
||||
*/
|
||||
typedef void (*adcCallback_t)(uint32_t result);
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \name ADC Configuration */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void ADC_getDefaultConfig(AdcConfig_t *config)
|
||||
\brief Gets the ADC default configuartion.
|
||||
This function sets the configuration structure to default values as below:
|
||||
\code
|
||||
config->clockDivider = ADC_CLOCK_DIV_4;
|
||||
config->channalConfig.aioResDiv = ADC_AIO_RESDIV_BYPASS; // Note: channelConfig field is union
|
||||
\endcode
|
||||
|
||||
\param[in] config Pointer to ADC configuration structure
|
||||
*/
|
||||
void ADC_getDefaultConfig(AdcConfig_t *config);
|
||||
|
||||
/**
|
||||
\fn int32_t ADC_channelInit(AdcChannel_e channel, const AdcConfig_t *config, adcCallback_t callback)
|
||||
\brief Initialize ADC specific channel
|
||||
\param[in] channel ADC physical channel to be configured
|
||||
\param[in] userID user ID of specific channel, customer user is assigned with ADC_USER_APP, used to compose logical channel combining with channel parameter
|
||||
\param[in] config Pointer to ADC configuration
|
||||
\param[in] callback Function to be called when ADC conversion completes
|
||||
\return 0 on success, -1 for parameter check error, -2 for AIO1 channel conflict(vref output has been enabled)
|
||||
*/
|
||||
int32_t ADC_channelInit(AdcChannel_e channel, AdcUser_t userID, const AdcConfig_t *config, adcCallback_t callback);
|
||||
|
||||
/**
|
||||
\fn void ADC_channelDeInit(AdcChannel_e channel)
|
||||
\brief Deinitialize ADC channel
|
||||
\param[in] channel physical channel to be de-initialized, configuration of specific logical channel is invalid after this API call.
|
||||
\param[in] userID user ID of specific channel, customer user is assigned with ADC_USER_APP, used to compose logical channel combining with channel parameter
|
||||
*/
|
||||
void ADC_channelDeInit(AdcChannel_e channel, AdcUser_t userID);
|
||||
|
||||
/**
|
||||
\fn void ADC_startConversion(uint32_t channels)
|
||||
\brief Starts ADC conversion. Conversion is performed imediately when ADC is free, otherwise, the start request is put into a request queue and will be serviced later.
|
||||
|
||||
\param[in] channel ADC physical channel to converse
|
||||
\param[in] userID user ID of specific channel, customer user is assigned with ADC_USER_APP, used to compose logical channel combining with channel parameter
|
||||
\return 0 on success, -1 if request queue is full, -2 if channel has not been initialized yet
|
||||
*/
|
||||
int32_t ADC_startConversion(AdcChannel_e channel, AdcUser_t userID);
|
||||
|
||||
/**
|
||||
\fn int32_t ADC_enableVrefOutput(void)
|
||||
\brief Enable vref output through AIO1
|
||||
\return 0 on success, -2 for AIO1 channel conflict(AIO1 input has been enabled)
|
||||
\note this feature and AIO1 input is mutual exclusive
|
||||
*/
|
||||
int32_t ADC_enableVrefOutput(void);
|
||||
|
||||
/**
|
||||
\fn void ADC_disableVrefOutput(void)
|
||||
\brief Disable vref output through AIO1
|
||||
*/
|
||||
void ADC_disableVrefOutput(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ADC_EC618_H */
|
||||
@@ -0,0 +1,117 @@
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
*(C) Copyright 2018 AirM2M International Ltd.
|
||||
|
||||
* All Rights Reserved
|
||||
|
||||
******************************************************************************
|
||||
* Filename: alarm.h
|
||||
*
|
||||
* Description: header of alarm.c, hw config for hal_alarm
|
||||
*
|
||||
* History: 2021.05.12 initiated by Zhao Weiqi
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef CHIP_ALARM_H
|
||||
#define CHIP_ALARM_H
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* INCLUDES *
|
||||
*----------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* MACROS *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* DATA TYPE DEFINITION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* GLOBAL FUNCTIONS DECLEARATION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief alarmVBatHwInit
|
||||
* @details configure and start vbat alarm
|
||||
*
|
||||
* @param voltThd100: set the threshold
|
||||
* @return null
|
||||
*/
|
||||
void alarmVBatHwInit(uint16_t voltThd100);
|
||||
/**
|
||||
* @brief alarmThmHwInit
|
||||
* @details configure and start themral alarm
|
||||
*
|
||||
* @param thmThd: set the threshold
|
||||
* @param range: set the hysteresis range
|
||||
* @return null
|
||||
*/
|
||||
void alarmThmHwInit(uint8_t thmThd, uint8_t range);
|
||||
/**
|
||||
* @brief alarmVBatHwDeinit
|
||||
* @details stop vbat alarm
|
||||
|
||||
* @return null
|
||||
*/
|
||||
void alarmVBatHwDeinit(void);
|
||||
/**
|
||||
* @brief alarmThmHwDeinit
|
||||
* @details stop thermal alarm
|
||||
|
||||
* @return null
|
||||
*/
|
||||
void alarmThmHwDeinit(void);
|
||||
/**
|
||||
* @brief alarmVBatGetIntIndicate
|
||||
* @details stop thermal alarm
|
||||
|
||||
* @return 1: high 0: low
|
||||
*/
|
||||
uint8_t alarmVBatGetIntIndicate(void);
|
||||
/**
|
||||
* @brief alarmThmGetIntIndicate
|
||||
* @details stop thermal alarm
|
||||
|
||||
* @return 1: high 0: low
|
||||
*/
|
||||
uint8_t alarmThmGetIntIndicate(void);
|
||||
/**
|
||||
* @brief alarmThmDisableInAdc
|
||||
* @details stop thermal alarm, call in auxadc when sample the thm channel
|
||||
|
||||
* @return 1: disable operation down 0: do nothing
|
||||
*/
|
||||
bool alarmThmDisableInAdc(void);
|
||||
/**
|
||||
* @brief alarmThmEnableInAdc
|
||||
* @details restart thermal alarm, call in auxadc when sample the thm channel
|
||||
|
||||
* @return 1: enable operation down 0: do nothing
|
||||
*/
|
||||
bool alarmThmEnableInAdc(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
#ifndef _APMU_PERIPHERAL_
|
||||
#define _APMU_PERIPHERAL_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void apmuPeriUsbEnterStartProc(bool forceCfgPwrDown);
|
||||
|
||||
void apmuPeriUsbEnterAbortProc(bool forceCfgPwrDown);
|
||||
|
||||
void apmuPeriUsbSusp2VbusTblGuardDlyChk(uint32_t cur_tick);
|
||||
|
||||
void apmuPeriUsbSusp2HibGuardDlyChk(uint32_t cur_tick);
|
||||
|
||||
void apmuPeriUsbSleep1LateRecoverFlow(bool sleepSuccess);
|
||||
|
||||
void apmuPeriUsbSleep1PreRecoverFlow(bool sleepSuccess);
|
||||
|
||||
bool apmuPeriLpuartPreSleepProcess(void);
|
||||
|
||||
bool apmuPeriLpuartIsRxActive(void);
|
||||
|
||||
void apmuPeriStartWFITimer(uint32_t ms);
|
||||
|
||||
void apmuPeriDeleteWFITimer(void);
|
||||
|
||||
void apmuPeriDeleteCPTimer(void);
|
||||
|
||||
void apmuPeriClearCPTimerInterrupt(void);
|
||||
|
||||
void apmuPeriStartCPTimer(uint32_t cpStartTime, void* expFunc);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2017-, Copyrigths of AirM2M Ltd.
|
||||
* File name: cache.h
|
||||
* Description: EC618 cache controller driver header file
|
||||
* History: Rev1.0 2018-07-12
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CACHE_EC618_H
|
||||
#define _CACHE_EC618_H
|
||||
#include "Driver_Common.h"
|
||||
|
||||
/**
|
||||
\addtogroup icache_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\fn void EnableICache(void)
|
||||
\brief Enables Instrution cache
|
||||
\return void
|
||||
*/
|
||||
void EnableICache(void);
|
||||
/**
|
||||
\fn void DisableICache(void)
|
||||
\brief Disables Instrution cache
|
||||
\return void
|
||||
*/
|
||||
void DisableICache(void);
|
||||
/**
|
||||
\fn bool IsICacheEnabled(void)
|
||||
\brief Check whether cache is enabled
|
||||
\return enabled or not
|
||||
*/
|
||||
bool IsICacheEnabled(void);
|
||||
|
||||
/** \}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CACHE_EC618_H */
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
*(C) Copyright 2018 AirM2M International Ltd.
|
||||
|
||||
* All Rights Reserved
|
||||
|
||||
******************************************************************************
|
||||
* Filename: charge.h
|
||||
*
|
||||
* Description: header of charge.c. api for charge status detect
|
||||
*
|
||||
* History: 2021.05.07 initiated by Zhao Weiqi
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef CHARGE_H
|
||||
#define CHARGE_H
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* INCLUDES *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* MACROS *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* DATA TYPE DEFINITION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
CHARGE_STATUS_DISCONNECT = 0,
|
||||
CHARGE_STATUS_CHARGING = 1,
|
||||
CHARGE_STATUS_FINISH = 2,
|
||||
}chargeStatus_e;
|
||||
|
||||
typedef void(* chargeStatusCb)(chargeStatus_e status);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* GLOBAL FUNCTIONS DECLEARATION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief chargeGetCurStatus
|
||||
* @details Get current charge status
|
||||
*
|
||||
* @return charge status:
|
||||
CHARGE_STATUS_DISCONNECT = 0,
|
||||
CHARGE_STATUS_CHARGING = 1,
|
||||
CHARGE_STATUS_FINISH = 2,
|
||||
*/
|
||||
chargeStatus_e chargeGetCurStatus(void);
|
||||
/**
|
||||
* @brief chargeHwInit
|
||||
* @details init hardware
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
void chargeHwInit(void);
|
||||
/**
|
||||
* @brief chargeHwDeinit
|
||||
* @details deinit hardware
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
void chargeHwDeinit(void);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,509 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
|
||||
* File name: clock.h
|
||||
* Description: EC618 clock driver header file
|
||||
* History: Rev1.0 2019-02-20
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CLOCK_EC618_H
|
||||
#define _CLOCK_EC618_H
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
|
||||
|
||||
/**
|
||||
\addtogroup clock_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
#ifndef __CLOCK_DECLARATION_DEFINED__
|
||||
#define __CLOCK_DECLARATION_DEFINED__
|
||||
|
||||
#include "gpr_common.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* clock ID with clock source select start */
|
||||
CLK_CC = CONSTRUCT_CLOCK_ID(CLKEN_REG_INDEX_MAX, 0, 0),
|
||||
CLK_APB_MP = CONSTRUCT_CLOCK_ID(CLKEN_REG_INDEX_MAX, 0, 1),
|
||||
CLK_APB_XP = CONSTRUCT_CLOCK_ID(CLKEN_REG_INDEX_MAX, 0, 2),
|
||||
CLK_SMP = CONSTRUCT_CLOCK_ID(CLKEN_REG_INDEX_MAX, 0, 3),
|
||||
CLK_SYSTICK = CONSTRUCT_CLOCK_ID(CLKEN_REG_INDEX_MAX, 0, 4),
|
||||
|
||||
FCLK_UART0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_FCLK_EN_REG_INDEX, 0, 5),
|
||||
FCLK_UART1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_FCLK_EN_REG_INDEX, 1, 6),
|
||||
FCLK_UART2 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_FCLK_EN_REG_INDEX, 2, 7),
|
||||
FCLK_SPI0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_FCLK_EN_REG_INDEX, 3, 8),
|
||||
FCLK_SPI1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_FCLK_EN_REG_INDEX, 4, 9),
|
||||
FCLK_I2S0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_FCLK_EN_REG_INDEX, 5, 10),
|
||||
FCLK_I2S1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_FCLK_EN_REG_INDEX, 6, 11),
|
||||
|
||||
FCLK_WDG = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 0, 12),
|
||||
FCLK_TIMER0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 1, 13),
|
||||
FCLK_TIMER1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 2, 14),
|
||||
FCLK_TIMER2 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 3, 15),
|
||||
FCLK_TIMER3 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 4, 16),
|
||||
FCLK_TIMER4 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 5, 17),
|
||||
FCLK_TIMER5 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 6, 18),
|
||||
FCLK_I2C0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 7, 19),
|
||||
FCLK_I2C1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 8, 20),
|
||||
FCLK_USIM0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 9, 21),
|
||||
FCLK_USIM1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 10, 22),
|
||||
FCLK_KPC = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_FCLK_EN_REG_INDEX, 11, 23),
|
||||
|
||||
CLK_FLASH = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 9, 24),
|
||||
CLK_PSRAM = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 10, 25),
|
||||
|
||||
CLK_CLKCAL = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_AP_CLKEN_REG_INDEX, 5, 26),
|
||||
|
||||
/* clock ID with clock source select end */
|
||||
|
||||
/* root clock */
|
||||
CLK_MF = CONSTRUCT_CLOCK_ID(CLKEN_REG_INDEX_MAX, 0, 27),
|
||||
CLK_32K = CONSTRUCT_CLOCK_ID(CLKEN_REG_INDEX_MAX, 0, 28),
|
||||
CLK_HF408M = CONSTRUCT_CLOCK_ID(CLKEN_REG_INDEX_MAX, 0, 29),
|
||||
|
||||
CLK_HF204M = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 0, 30),
|
||||
CLK_HF102M = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 1, 31),
|
||||
CLK_HF51M = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 2, 32),
|
||||
CLK_32K_GATED = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 3, 33),
|
||||
CLK_MF_GATED = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 4, 34),
|
||||
CLK_CC_MP = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 5, 35),
|
||||
CLK_CC_AP = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 6, 36),
|
||||
CLK_CC_CP = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 7, 37),
|
||||
CLK_AON = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 8, 38),
|
||||
|
||||
CLK_SMP_MP = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 11, 39),
|
||||
|
||||
MFAB_HCLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 16, 40),
|
||||
AFBBR_HCLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 17, 41),
|
||||
|
||||
MSMB_HCLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 19, 42),
|
||||
FLASH_HCLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 20, 43),
|
||||
PSRAM_HCLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 21, 44),
|
||||
ULOG_HCLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 22, 45),
|
||||
UTFC_HCLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 23, 46),
|
||||
ULDP_HCLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 24, 47),
|
||||
|
||||
USBC_HCLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 26, 48),
|
||||
USBC_PMU_HCLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 27, 49),
|
||||
USBC_REF_CLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 28, 50),
|
||||
USBP_REF_CLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 29, 51),
|
||||
USBC_UTMI_CLK = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_MP_CLKEN_REG_INDEX, 30, 52),
|
||||
|
||||
|
||||
CLK_DAP_AP = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_AP_CLKEN_REG_INDEX, 0, 53),
|
||||
CLK_TRACE_AP = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_AP_CLKEN_REG_INDEX, 1, 54),
|
||||
CLK_SYSTICK_AP = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_AP_CLKEN_REG_INDEX, 2, 55),
|
||||
CLK_APB_AP = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_AP_CLKEN_REG_INDEX, 3, 56),
|
||||
CLK_SMP_AP = CONSTRUCT_CLOCK_ID(APB_GPR_TOP_AP_CLKEN_REG_INDEX, 4, 57),
|
||||
|
||||
PCLK_SIPC = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 1, 58),
|
||||
PCLK_AON = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 2, 59),
|
||||
PCLK_CPMU = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 3, 60),
|
||||
PCLK_PMDIG = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 4, 61),
|
||||
PCLK_RFDIG = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 5, 62),
|
||||
PCLK_PAD = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 6, 63),
|
||||
PCLK_GPIO = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 7, 64),
|
||||
PCLK_FUSE = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 8, 65),
|
||||
PCLK_TRNG = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 9, 66),
|
||||
PCLK_USBP = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 10, 67),
|
||||
PCLK_LPUC = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 11, 68),
|
||||
PCLK_UART0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 12, 69),
|
||||
PCLK_UART1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 13, 70),
|
||||
PCLK_UART2 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 14, 71),
|
||||
PCLK_SPI0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 15, 72),
|
||||
PCLK_SPI1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 16, 73),
|
||||
PCLK_I2S0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 17, 74),
|
||||
PCLK_I2S1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_MP_PCLK_EN_REG_INDEX, 18, 75),
|
||||
|
||||
|
||||
PCLK_WDG = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 0, 76),
|
||||
PCLK_TIMER0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 1, 77),
|
||||
PCLK_TIMER1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 2, 78),
|
||||
PCLK_TIMER2 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 3, 79),
|
||||
PCLK_TIMER3 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 4, 80),
|
||||
PCLK_TIMER4 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 5, 81),
|
||||
PCLK_TIMER5 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 6, 82),
|
||||
PCLK_IPC = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 7, 83),
|
||||
PCLK_I2C0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 8, 84),
|
||||
PCLK_I2C1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 9, 85),
|
||||
PCLK_USIM0 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 10, 86),
|
||||
PCLK_USIM1 = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 11, 87),
|
||||
PCLK_KPC = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 12, 88),
|
||||
PCLK_ONEW = CONSTRUCT_CLOCK_ID(APB_GPR_APB_AP_PCLK_EN_REG_INDEX, 13, 89),
|
||||
|
||||
|
||||
TOP_PBRG_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_TOP_CLKEN_REG_INDEX, 0, 90),
|
||||
TOP_PBRG_PCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_TOP_CLKEN_REG_INDEX, 1, 91),
|
||||
TOP_GPR_PCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_TOP_CLKEN_REG_INDEX, 2, 92),
|
||||
|
||||
TRACE_CLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 1, 93),
|
||||
ETM_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 2, 94),
|
||||
ROMTABLE_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 3, 95),
|
||||
TPIU_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 4, 96),
|
||||
CACHE_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 5, 97),
|
||||
FABSUB_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 6, 98),
|
||||
SBU_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 7, 99),
|
||||
PBRG_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 8, 100),
|
||||
SPIS_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 9, 101),
|
||||
XIC_RMI_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 10, 102),
|
||||
ULOG_RMI_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 11, 103),
|
||||
TMU_RMI_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 12, 104),
|
||||
SCT_RMI_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 13, 105),
|
||||
|
||||
UTFC_RMI_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 16, 106),
|
||||
ULDP_RMI_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 17, 107),
|
||||
SCT_HCLK = CONSTRUCT_CLOCK_ID(RMI_GPR_XPSYS_CLKEN_REG_INDEX, 18, 108),
|
||||
|
||||
INVALID_CLK = CONSTRUCT_CLOCK_ID(CLKEN_REG_INDEX_MAX, 0, 109)
|
||||
} ClockId_e;
|
||||
|
||||
|
||||
/** \brief List of all configurable module's functional clock sources */
|
||||
typedef enum
|
||||
{
|
||||
// top clk sel
|
||||
|
||||
/** Core clock sourced from 26M */
|
||||
CLK_CC_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(CLK_CC), 0, CLK_MF),
|
||||
/** Core clock sourced from 204M */
|
||||
CLK_CC_SEL_204M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(CLK_CC), 1, CLK_HF204M),
|
||||
/** Core clock sourced from 102M */
|
||||
CLK_CC_SEL_102M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(CLK_CC), 2, CLK_HF102M),
|
||||
/** Core clock sourced from 32K */
|
||||
CLK_CC_SEL_32K = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(CLK_CC), 3, CLK_32K),
|
||||
|
||||
|
||||
/** APB MP clock sourced from 26M */
|
||||
CLK_APB_MP_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(CLK_APB_MP), 0, CLK_MF),
|
||||
/** APB MP clock sourced from 51M */
|
||||
CLK_APB_MP_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(CLK_APB_MP), 1U, CLK_HF51M),
|
||||
|
||||
/** APB XP clock sourced from 26M */
|
||||
CLK_APB_XP_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(CLK_APB_XP), 0, CLK_MF),
|
||||
/** APB XP sourced from 51M */
|
||||
CLK_APB_XP_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(CLK_APB_XP), 1U, CLK_HF51M),
|
||||
|
||||
/** Systick clock sourced from 32K */
|
||||
CLK_SYSTICK_SEL_32K = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(CLK_SYSTICK), 0, CLK_32K),
|
||||
/** Systick clock sourced from 26M */
|
||||
CLK_SYSTICK_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(CLK_SYSTICK), 1U, CLK_MF),
|
||||
|
||||
// apb mp func clk sel
|
||||
|
||||
/** UART0 clock sourced from 26M */
|
||||
FCLK_UART0_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_UART0), 0, CLK_MF_GATED),
|
||||
/** UART0 clock sourced from 51M */
|
||||
FCLK_UART0_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_UART0), 1U, CLK_HF51M),
|
||||
|
||||
/** UART1 clock sourced from 26M */
|
||||
FCLK_UART1_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_UART1), 0, CLK_MF_GATED),
|
||||
/** UART1 clock sourced from 51M */
|
||||
FCLK_UART1_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_UART1), 1U, CLK_HF51M),
|
||||
|
||||
/** UART2 clock sourced from 26M */
|
||||
FCLK_UART2_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_UART2), 0, CLK_MF_GATED),
|
||||
/** UART2 clock sourced from 51M */
|
||||
FCLK_UART2_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_UART2), 1U, CLK_HF51M),
|
||||
|
||||
/** SPI0 clock sourced from 26M */
|
||||
FCLK_SPI0_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_SPI0), 0, CLK_MF_GATED),
|
||||
/** SPI0 clock sourced from 51M */
|
||||
FCLK_SPI0_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_SPI0), 1U, CLK_HF51M),
|
||||
|
||||
/** SPI1 clock sourced from 26M */
|
||||
FCLK_SPI1_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_SPI1), 0, CLK_MF_GATED),
|
||||
/** SPI1 clock sourced from 51M */
|
||||
FCLK_SPI1_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_SPI1), 1U, CLK_HF51M),
|
||||
|
||||
/** I2S0 clock sourced from 26M */
|
||||
FCLK_I2S0_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_I2S0), 0, CLK_MF_GATED),
|
||||
/** I2S0 clock sourced from 51M */
|
||||
FCLK_I2S0_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_I2S0), 1U, CLK_HF51M),
|
||||
|
||||
/** I2S1 clock sourced from 26M */
|
||||
FCLK_I2S1_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_I2S1), 0, CLK_MF_GATED),
|
||||
/** I2S1 clock sourced from 51M */
|
||||
FCLK_I2S1_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_I2S1), 1U, CLK_HF51M),
|
||||
|
||||
// apb ap func clk sel
|
||||
|
||||
/** WDG clock sourced from 32K */
|
||||
FCLK_WDG_SEL_32K = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_WDG), 0, CLK_32K_GATED),
|
||||
/** WDG clock sourced from 26M */
|
||||
FCLK_WDG_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_WDG), 1U, CLK_MF_GATED),
|
||||
|
||||
/** TIMER0 clock sourced from 32K */
|
||||
FCLK_TIMER0_SEL_32K = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER0), 0, CLK_32K_GATED),
|
||||
/** TIMER0 clock sourced from 26M */
|
||||
FCLK_TIMER0_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER0), 1U, CLK_MF_GATED),
|
||||
|
||||
/** TIMER1 clock sourced from 32K */
|
||||
FCLK_TIMER1_SEL_32K = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER1), 0, CLK_32K_GATED),
|
||||
/** TIMER1 clock sourced from 26M */
|
||||
FCLK_TIMER1_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER1), 1U, CLK_MF_GATED),
|
||||
|
||||
/** TIMER2 clock sourced from 32K */
|
||||
FCLK_TIMER2_SEL_32K = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER2), 0, CLK_32K_GATED),
|
||||
/** TIMER2 clock sourced from 26M */
|
||||
FCLK_TIMER2_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER2), 1U, CLK_MF_GATED),
|
||||
|
||||
/** TIMER3 clock sourced from 32K */
|
||||
FCLK_TIMER3_SEL_32K = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER3), 0, CLK_32K_GATED),
|
||||
/** TIMER3 clock sourced from 26M */
|
||||
FCLK_TIMER3_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER3), 1U, CLK_MF_GATED),
|
||||
|
||||
/** TIMER4 clock sourced from 32K */
|
||||
FCLK_TIMER4_SEL_32K = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER4), 0, CLK_32K_GATED),
|
||||
/** TIMER4 clock sourced from 26M */
|
||||
FCLK_TIMER4_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER4), 1U, CLK_MF_GATED),
|
||||
|
||||
/** TIMER5 clock sourced from 32K */
|
||||
FCLK_TIMER5_SEL_32K = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER5), 0, CLK_32K_GATED),
|
||||
/** TIMER5 clock sourced from 26M */
|
||||
FCLK_TIMER5_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER5), 1U, CLK_MF_GATED),
|
||||
|
||||
/** I2C0 clock sourced from 26M */
|
||||
FCLK_I2C0_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_I2C0), 0, CLK_MF_GATED),
|
||||
/** I2C0 clock sourced from 51M */
|
||||
FCLK_I2C0_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_I2C0), 1U, CLK_HF51M),
|
||||
|
||||
/** I2C1 clock sourced from 26M */
|
||||
FCLK_I2C1_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_I2C1), 0, CLK_MF_GATED),
|
||||
/** I2C1 clock sourced from 51M */
|
||||
FCLK_I2C1_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_I2C1), 1U, CLK_HF51M),
|
||||
|
||||
/** USIM0 clock sourced from 26M */
|
||||
FCLK_USIM0_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_USIM0), 0, CLK_MF_GATED),
|
||||
/** USIM0 clock sourced from 51M */
|
||||
FCLK_USIM0_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_USIM0), 1U, CLK_HF51M),
|
||||
|
||||
/** USIM1 clock sourced from 26M */
|
||||
FCLK_USIM1_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_USIM1), 0, CLK_MF_GATED),
|
||||
/** USIM1 clock sourced from 51M */
|
||||
FCLK_USIM1_SEL_51M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_USIM1), 1U, CLK_HF51M),
|
||||
|
||||
/** KPC clock sourced from 26M */
|
||||
FCLK_KPC_SEL_32K = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_KPC), 0, CLK_32K_GATED),
|
||||
/** KPC clock sourced from 51M */
|
||||
FCLK_KPC_SEL_26M = MAKE_CLOCK_SEL_VALUE(GET_INDEX_FROM_CLOCK_ID(FCLK_KPC), 1U, CLK_MF_GATED),
|
||||
|
||||
} ClockSelect_e;
|
||||
|
||||
|
||||
#endif //__CLOCK_DECLARATION_DEFINED__
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \name Clock Configuration */
|
||||
/* \{ */
|
||||
|
||||
/**
|
||||
\fn int32_t CLOCK_clockEnable(ClockId_e id)
|
||||
\brief Enable clock for selected module
|
||||
\param[in] id clock item to enable
|
||||
\return ARM_DRIVER_OK if the setting is successful
|
||||
ARM_DRIVER_ERROR_PARAMETER on parameter check failure(setting is not available for specified clock id)
|
||||
*/
|
||||
int32_t CLOCK_clockEnable(ClockId_e id);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_clockReset(ClockId_e id)
|
||||
\brief Reset clock for selected module
|
||||
\param[in] id clock item to reset
|
||||
*/
|
||||
void CLOCK_clockReset(ClockId_e id);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_updateClockTreeElement(ClockId_e id, ClockId_e parentId, uint8_t enableCount)
|
||||
\brief Update clock tree node item value, interrnal used only
|
||||
\param[in] id clock item to update
|
||||
\param[in] parentId parent clock id
|
||||
\param[in] enableCount new enable count
|
||||
*/
|
||||
void CLOCK_updateClockTreeElement(ClockId_e id, ClockId_e parentId, uint8_t enableCount);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_clockDisable(ClockId_e id)
|
||||
\brief Disable clock for selected module
|
||||
\param[in] id clock item to disable
|
||||
*/
|
||||
void CLOCK_clockDisable(ClockId_e id);
|
||||
|
||||
/**
|
||||
\fn int32_t CLOCK_setClockSrc(ClockId_e id, ClockSelect_e select)
|
||||
\brief Set clock source for selected module
|
||||
\param[in] id clock item to set
|
||||
\param[in] select select one of clock sources \ref ClockSelect_e
|
||||
\return ARM_DRIVER_OK if the setting is successful
|
||||
ARM_DRIVER_ERROR_PARAMETER on parameter check failure(setting is not available for specified clock id)
|
||||
ARM_DRIVER_ERROR if specific clock has been enabled
|
||||
*/
|
||||
int32_t CLOCK_setClockSrc(ClockId_e id, ClockSelect_e select);
|
||||
|
||||
/**
|
||||
\fn int32_t CLOCK_setClockDiv(ClockId_e id, uint32 div)
|
||||
\brief Set clock divider for selected module
|
||||
\param[in] id clock item to set
|
||||
\param[in] div divider value
|
||||
\return ARM_DRIVER_OK if the setting is successful
|
||||
ARM_DRIVER_ERROR_PARAMETER on parameter check failure(setting is not available for specified clock id or div value is set to 0)
|
||||
ARM_DRIVER_ERROR if specific clock has been enabled
|
||||
*/
|
||||
int32_t CLOCK_setClockDiv(ClockId_e id, uint32_t div);
|
||||
|
||||
/**
|
||||
\fn uint32_t CLOCK_getClockFreq(ClockId_e id)
|
||||
\brief Get clock frequency for selected module
|
||||
\param[in] id clock item to get
|
||||
\return clock frequency in unit of HZ
|
||||
*/
|
||||
uint32_t CLOCK_getClockFreq(ClockId_e id);
|
||||
|
||||
/**
|
||||
\fn int32_t CLOCK_setFracDivConfig(FracDivConfig_t * config)
|
||||
\brief fracdiv clock config
|
||||
\param[in] config pointer to fracdiv setting
|
||||
\return ARM_DRIVER_OK if the setting is successful
|
||||
ARM_DRIVER_ERROR_PARAMETER on parameter check failure
|
||||
*/
|
||||
int32_t CLOCK_setFracDivConfig(FracDivConfig_t * config);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_fracDivOutCLkEnable(FracDivOutClkId_e id)
|
||||
\brief fracdiv out clock enable
|
||||
\param[in] id fracdiv out clock id
|
||||
*/
|
||||
void CLOCK_fracDivOutCLkEnable(FracDivOutClkId_e id);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_fracDivOutClkDisable(FracDivOutClkId_e id)
|
||||
\brief fracdiv out clock disable
|
||||
\param[in] id fracdiv out clock id
|
||||
*/
|
||||
void CLOCK_fracDivOutClkDisable(FracDivOutClkId_e id);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_setFracDivOutClkDiv(FracDivOutClkId_e id, uint8_t div)
|
||||
\brief set fracdiv out clock divider
|
||||
\param[in] id fracdiv out clock id
|
||||
\param[in] div divider ratio to set
|
||||
*/
|
||||
void CLOCK_setFracDivOutClkDiv(FracDivOutClkId_e id, uint8_t div);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_setBclkSrc(BclkId_e id, BclkSrc_e src)
|
||||
\brief select bclk source
|
||||
\param[in] id bclk id
|
||||
\param[in] src clock source to set
|
||||
*/
|
||||
void CLOCK_setBclkSrc(BclkId_e id, BclkSrc_e src);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_setBclkDiv(BclkId_e id, uint8_t div)
|
||||
\brief set bclk divider
|
||||
\param[in] id bclk id
|
||||
\param[in] div divider ratio to set
|
||||
*/
|
||||
void CLOCK_setBclkDiv(BclkId_e id, uint8_t div);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_bclkEnable(BclkId_e id)
|
||||
\brief enable bclk
|
||||
\param[in] id bclk id
|
||||
*/
|
||||
void CLOCK_bclkEnable(BclkId_e id);
|
||||
|
||||
|
||||
/**
|
||||
\fn void CLOCK_setMclkSrc(MclkId_e id, MclkSrc_e src)
|
||||
\brief select mclk source
|
||||
\param[in] id mclk id
|
||||
\param[in] src clock source to set
|
||||
*/
|
||||
void CLOCK_setMclkSrc(MclkId_e id, MclkSrc_e src);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_mclkEnable(MclkId_e id)
|
||||
\brief mclk enable
|
||||
\param[in] id mclk id
|
||||
*/
|
||||
void CLOCK_mclkEnable(MclkId_e id);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_mclkDisable(MclkId_e id)
|
||||
\brief mclk disable
|
||||
\param[in] id mclk id
|
||||
*/
|
||||
void CLOCK_mclkDisable(MclkId_e id);
|
||||
|
||||
/**
|
||||
\fn void CLOCK_setMclkDiv(MclkId_e id, uint8_t div)
|
||||
\brief set mclk divider
|
||||
\param[in] id mclk id
|
||||
\param[in] div divider ratio to set
|
||||
*/
|
||||
void CLOCK_setMclkDiv(MclkId_e id, uint8_t div);
|
||||
/** \} */
|
||||
|
||||
/** \name HAL Driver declaration */
|
||||
/* \{ */
|
||||
|
||||
extern int32_t GPR_setClockSrc(ClockId_e id, ClockSelect_e select);
|
||||
extern int32_t GPR_setClockDiv(ClockId_e id, uint32_t div);
|
||||
extern void GPR_clockEnable(ClockId_e id);
|
||||
extern void GPR_clockDisable(ClockId_e id);
|
||||
extern uint32_t GPR_getClockFreq(ClockId_e id);
|
||||
|
||||
extern void GPR_setFracDivConfig(FracDivConfig_t * config);
|
||||
extern void GPR_fracDivOutCLkEnable(FracDivOutClkId_e id);
|
||||
extern void GPR_fracDivOutClkDisable(FracDivOutClkId_e id);
|
||||
extern void GPR_setFracDivOutClkDiv(FracDivOutClkId_e id, uint8_t div);
|
||||
|
||||
extern void GPR_setBclkSrc(BclkId_e id, BclkSrc_e src);
|
||||
extern void GPR_setBclkDiv(BclkId_e id, uint8_t div);
|
||||
extern void GPR_BclkEnable(BclkId_e id);
|
||||
|
||||
|
||||
extern void GPR_setMclkSrc(MclkId_e id, MclkSrc_e src);
|
||||
extern void GPR_mclkEnable(MclkId_e id);
|
||||
extern void GPR_mclkDisable(MclkId_e id);
|
||||
extern void GPR_setMclkDiv(MclkId_e id, uint8_t div);
|
||||
|
||||
extern void GPR_swReset(ClockResetId_e id);
|
||||
extern void GPR_swResetModule(const ClockResetVector_t *v);
|
||||
extern void GPR_initialize(void);
|
||||
extern void GPR_setApbGprAcg( void );
|
||||
extern void GPR_lockUpActionCtrl(bool enable);
|
||||
extern uint32_t GPR_getCPLockUpResetCtrl(void);
|
||||
extern ApRstSource_e GPR_apGetRstSrc(void);
|
||||
extern CpRstSource_e GPR_cpGetRstSrc(void);
|
||||
extern void GPR_cpResetCfgSet(bool wdtRstEn, bool sysRstApb, bool lockupRstEn, bool cpAPmuRst);
|
||||
extern void GPR_setApbGprAcg( void );
|
||||
extern void GPR_bootSetting( void );
|
||||
void CLOCK_AssertChkBeforeSlp(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \}*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
/******************************************************************************
|
||||
|
||||
*(C) Copyright 2018 AirM2M International Ltd.
|
||||
|
||||
* All Rights Reserved
|
||||
|
||||
******************************************************************************
|
||||
* Filename:cpxip.h
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* INCLUDES *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef CP_XIP_H
|
||||
#define CP_XIP_H
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* MACROS *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* DATA TYPE DEFINITION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* GLOBAL FUNCTIONS DECLEARATION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
void CPXIP_Enable(void);
|
||||
uint8_t CPXIP_QSPI_Erase_Sector(uint32_t SectorAddress);
|
||||
uint8_t CPXIP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
|
||||
uint8_t CPXIP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
#ifndef BSP_CSPI_H
|
||||
#define BSP_CSPI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
|
||||
#define CSPI_TRANSFER_TRUNK_SIZE 7680 ///< Each DMA descriptor data size, fixed to 7680byte
|
||||
|
||||
|
||||
typedef void (*cspiCbEvent_fn) (uint32_t event); ///< cspi callback event.
|
||||
|
||||
|
||||
/** \brief CSPI flags */
|
||||
#define CSPI_FLAG_INITIALIZED (1UL << 0) ///< CSPI initialized
|
||||
#define CSPI_FLAG_POWERED (1UL << 1) ///< CSPI powered on
|
||||
|
||||
|
||||
/** \brief CSPI DMA */
|
||||
typedef struct
|
||||
{
|
||||
DmaInstance_e rxInstance; ///< Receive DMA instance number
|
||||
int8_t rxCh; ///< Receive channel number
|
||||
uint8_t rxReq; ///< Receive DMA request number
|
||||
void (*rxCb)(uint32_t event); ///< Receive callback
|
||||
DmaDescriptor_t *descriptor; ///< Rx descriptor
|
||||
} cspiDma_t;
|
||||
|
||||
// CSPI PINS
|
||||
typedef const struct
|
||||
{
|
||||
PIN *mclk; ///< Main clk Pin identifier
|
||||
PIN *pclk; ///< Pixel clk Pin identifier
|
||||
PIN *cs; ///< Cs Pin identifier
|
||||
PIN *sdo0; ///< Din Pin identifier
|
||||
PIN *sdo1; ///< Dout Pin identifier
|
||||
} cspiPins_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t busy; ///< Transmitter/Receiver busy flag
|
||||
} cspiRteStats_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CAM_8W = 10, ///< 8w use 10 dma descriptor chain
|
||||
CAM_30W = 40, ///< 30w use 40 dma descriptor chain
|
||||
}camResolution_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CAM_6_5_M = 0, ///< camera 6.5M HZ
|
||||
CAM_13_M = 1, ///< camera 13M HZ
|
||||
CAM_25_5_M = 2, ///< camera 25.5M HZ
|
||||
CAM_24_M = 3, ///< camera 24M HZ
|
||||
CAM_20_M = 4, ///< camera 20M HZ
|
||||
}camFrequence_e;
|
||||
|
||||
|
||||
// CSPI information (Run-time)
|
||||
typedef struct
|
||||
{
|
||||
cspiCbEvent_fn cbEvent; ///< Event callback
|
||||
cspiRteStats_t status; ///< CSPI status flags
|
||||
uint8_t flags; ///< CSPI driver flags
|
||||
uint32_t busSpeed; ///< CSPI bus speed
|
||||
uint8_t dataWidth; ///< CSPI data bits select in unit of byte
|
||||
uint32_t targetAddr; ///< CSPI target address
|
||||
camResolution_e resolution; ///< Camera resolution
|
||||
} cspiInfo_t;
|
||||
|
||||
|
||||
// SPI Resources definition
|
||||
typedef struct
|
||||
{
|
||||
CSPI_TypeDef *reg; ///< SPI register pointer
|
||||
cspiPins_t pins; ///< SPI PINS configuration
|
||||
cspiDma_t *dma; ///< SPI DMA configuration pointer
|
||||
cspiInfo_t *info; ///< Run-Time Information
|
||||
} cspiRes_t;
|
||||
|
||||
|
||||
/**
|
||||
\brief General power states
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CSPI_POWER_OFF, ///< Power off: no operation possible
|
||||
CSPI_POWER_FULL ///< Power on: full operation at maximum performance
|
||||
} cspiPowerState_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t slaveModeEn : 1; ///< Slave Mode Enable
|
||||
uint32_t slotSize : 5; ///< Slot Size
|
||||
uint32_t wordSize : 5; ///< Word Size
|
||||
uint32_t alignMode : 1; ///< Align Mode
|
||||
uint32_t endianMode : 1; ///< Endian Mode
|
||||
uint32_t dataDly : 2; ///< Data Delay
|
||||
uint32_t txPad : 2; ///< Tx padding
|
||||
uint32_t rxSignExt : 1; ///< Rx Sign Entension
|
||||
uint32_t txPack : 2; ///< Tx Pack
|
||||
uint32_t rxPack : 2; ///< Rx Pack
|
||||
uint32_t txFifoEndianMode : 1; ///< Tx Fifo Endian Mode
|
||||
uint32_t rxFifoEndianMode : 1; ///< Rx Fifo Endian Mode
|
||||
}cspiDataFmt_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t slotEn : 3; ///< Slot Enable
|
||||
uint32_t slotNum : 8; ///< Slot Num
|
||||
}cspiSlotCtrl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t bclkPolarity : 1; ///< Bclk Polarity
|
||||
uint32_t fsPolarity : 1; ///< Frame Synchronization Polarity
|
||||
uint32_t fsWidth : 6; ///< Frame Synchronization Width
|
||||
}cspiBclkFsCtrl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t rxDmaReqEn : 1; ///< Rx Dma Req Enable
|
||||
uint32_t txDmaReqEn : 1; ///< Tx Dma Req Enable
|
||||
uint32_t rxDmaTimeOutEn : 1; ///< Rx Dma Timeout Enable
|
||||
uint32_t dmaWorkWaitCycle : 5; ///< Dma Work Wait Cycle
|
||||
uint32_t rxDmaBurstSizeSub1 : 4; ///< Rx Dma Burst Size subtract 1
|
||||
uint32_t txDmaBurstSizeSub1 : 4; ///< Tx Dma Burst Size subtract 1
|
||||
uint32_t rxDmaThreadHold : 4; ///< Rx Dma Threadhold
|
||||
uint32_t txDmaThreadHold : 4; ///< Tx Dma Threadhold
|
||||
uint32_t rxFifoFlush : 1; ///< Rx Fifo flush
|
||||
uint32_t txFifoFlush : 1; ///< Tx Fifo flush
|
||||
}cspiDmaCtrl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t txUnderRunIntEn : 1; ///< Tx Underrun interrupt Enable
|
||||
uint32_t txDmaErrIntEn : 1; ///< Tx Dma Err Interrupt Enable
|
||||
uint32_t txDatIntEn : 1; ///< Tx Data Interrupt Enable
|
||||
uint32_t rxOverFlowIntEn : 1; ///< Rx Overflow Interrupt Enable
|
||||
uint32_t rxDmaErrIntEn : 1; ///< Rx Dma Err Interrupt Enable
|
||||
uint32_t rxDatIntEn : 1; ///< Rx Data Interrupt Enable
|
||||
uint32_t rxTimeOutIntEn : 1; ///< Rx Timeout Interrupt Enable
|
||||
uint32_t fsErrIntEn : 1; ///< Frame Start Interrupt Enable
|
||||
uint32_t frameStartIntEn : 1; ///< Frame End Interrupt Enable
|
||||
uint32_t frameEndIntEn : 1; ///< Frame End Interrupt Enable
|
||||
uint32_t cspiBusTimeOutIntEn : 1; ///< Not use
|
||||
uint32_t txIntThreshHold : 4; ///< Tx Interrupt Threadhold
|
||||
uint32_t rxIntThreshHold : 4; ///< Rx Interrupt Threadhold
|
||||
}cspiIntCtrl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t rxTimeOutCycle : 24; ///< Rx Timeout Cycle
|
||||
}cspiTimeOutCycle_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t txUnderRun : 1; ///< Tx Underrun
|
||||
uint32_t txDmaErr : 1; ///< Tx Dma Err
|
||||
uint32_t txDataRdy : 1; ///< Tx Data ready, readOnly
|
||||
uint32_t rxOverFlow : 1; ///< Rx OverFlow
|
||||
uint32_t rxDmaErr : 1; ///< Rx Dma Err
|
||||
uint32_t rxDataRdy : 1; ///< Rx Data ready, readOnly
|
||||
uint32_t rxFifoTimeOut : 1; ///< Rx Fifo timeout
|
||||
uint32_t fsErr : 4; ///< Frame synchronization Err
|
||||
uint32_t frameStart : 1; ///< Frame start
|
||||
uint32_t frameEnd : 1; ///< Frame end
|
||||
uint32_t txFifoLevel : 6; ///< Tx Fifo Level, readOnly
|
||||
uint32_t rxFifoLevel : 6; ///< Rx Fifo level, readOnly
|
||||
uint32_t cspiBusTimeOut : 1; ///< Cspi Bus timeout
|
||||
}cspiStats_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t enable : 1; ///< Enable
|
||||
uint32_t csEn : 1; ///< CS signal check
|
||||
uint32_t rxWid : 1; ///< Rx Width
|
||||
uint32_t rxdSeq : 1; ///< Rx Sequence
|
||||
uint32_t cpol : 1; ///< SPI polarity
|
||||
uint32_t cpha : 1; ///< SPI phase
|
||||
uint32_t frameProcEn : 1; ///< Frame Process Enable
|
||||
uint32_t fillYonly : 1; ///< Fill Y Only
|
||||
uint32_t hwInitEn : 1; ///< HW Init Enable
|
||||
uint32_t lsCheckEn : 1; ///< Line Start Check Enable
|
||||
uint32_t dpCheckEn : 1; ///< Data Pcket Check Enable
|
||||
uint32_t frameProcInitEn : 1; ///< Frame Process Init Enable
|
||||
uint32_t rowScaleRatio : 4; ///< Row Scale Ratio
|
||||
uint32_t colScaleRatio : 4; ///< Column Scale Ratio
|
||||
uint32_t scaleBytes : 2; ///< Scale Bytes
|
||||
}cspiCtrl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t autoCgEn : 1; ///< Auto Configure Enable
|
||||
}cspiAutoCgCtrl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t cspiBusTimeOutCycle : 24; ///< Cspi Bus Timeout Cycle
|
||||
uint32_t dataId : 8; ///< Data Indication, readOnly
|
||||
}cspiFrameInfo0_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t cspiInit : 1; ///< Cspi Init
|
||||
}cspiInit_t;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Cspi control bits.
|
||||
*/
|
||||
#define CSPI_CTRL_TRANSABORT (1UL << 0) ///< CSPI trans abort
|
||||
#define CSPI_CTRL_BUS_SPEED (1UL << 1) ///< CSPI trans abort
|
||||
#define CSPI_CTRL_DATA_BITS (1UL << 2) ///< CSPI trans abort
|
||||
#define CSPI_CTRL_DATA_FORMAT (1UL << 3) ///< CSPI data format
|
||||
#define CSPI_CTRL_SLOT_CTRL (1UL << 4) ///< CSPI slot ctrl
|
||||
#define CSPI_CTRL_BCLK_FS_CTRL (1UL << 5) ///< CSPI bclk fs ctrl
|
||||
#define CSPI_CTRL_DMA_CTRL (1UL << 6) ///< CSPI dma ctrl
|
||||
#define CSPI_CTRL_INT_CTRL (1UL << 7) ///< CSPI int ctrl
|
||||
#define CSPI_CTRL_TIMEOUT_CYCLE (1UL << 8) ///< CSPI timeout cycle
|
||||
#define CSPI_CTRL_STATUS (1UL << 9) ///< CSPI status
|
||||
#define CSPI_CTRL_CSPICTL (1UL << 10) ///< CSPI control
|
||||
#define CSPI_CTRL_AUTO_CG_CTRL (1UL << 11) ///< CSPI auto cg ctrl
|
||||
#define CSPI_CTRL_FRAME_INFO0 (1UL << 12) ///< CSPI frame info0
|
||||
#define CSPI_CTRL_INIT (1UL << 13) ///< CSPI init
|
||||
#define CSPI_CTRL_RXTOR (1UL << 14) ///< CSPI rx timeout cycle
|
||||
#define CSPI_CTRL_MEM_ADDR (1UL << 15) ///< CSPI memory addr set
|
||||
#define CSPI_CTRL_FLUSH_RX_FIFO (1UL << 16) ///< Flush rx fifo
|
||||
#define CSPI_CTRL_START_STOP (1UL << 17) ///< Start or stop cspi
|
||||
#define CSPI_CTRL_RESOLUTION_SET (1UL << 18) ///< Camera resolution set
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Access structure of the CSPI Driver.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*init) (cspiCbEvent_fn cb_event); ///< Initialize CSPI Interface.
|
||||
int32_t (*deInit) (void); ///< De-initialize CSPI Interface.
|
||||
int32_t (*powerCtrl) (cspiPowerState_e state); ///< Control CSPI Interface Power.
|
||||
int32_t (*recv) (void); ///< Open dma to receive data.
|
||||
int32_t (*ctrl) (uint32_t control, uint32_t arg); ///< Control CSPI Interface.
|
||||
} const cspiDrvInterface_t;
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,333 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2017-, Copyrigths of AirM2M Ltd.
|
||||
* File name: dma.h
|
||||
* Description: EC618 dma controller driver header file
|
||||
* History: Rev1.0 2018-08-08
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _DMA_EC618_H
|
||||
#define _DMA_EC618_H
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
|
||||
/**
|
||||
\addtogroup dma_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/** \brief List of DMA source/target address increment control options */
|
||||
typedef enum
|
||||
{
|
||||
DMA_ADDRESS_INCREMENT_NONE = 0, /**< Increment neither source or target address */
|
||||
DMA_ADDRESS_INCREMENT_SOURCE = 1U, /**< Increment source address */
|
||||
DMA_ADDRESS_INCREMENT_TARGET = 2U, /**< Increment target address */
|
||||
DMA_ADDRESS_INCREMENT_BOTH = 3U, /**< Increment both source and target address */
|
||||
} DmaAddressIncrement_e;
|
||||
|
||||
/** \brief List of DMA flow control options */
|
||||
typedef enum
|
||||
{
|
||||
DMA_FLOW_CONTROL_NONE = 0U, /**< No flow control */
|
||||
DMA_FLOW_CONTROL_SOURCE = 1U, /**< Only source */
|
||||
DMA_FLOW_CONTROL_TARGET = 2U, /**< Only target */
|
||||
} DmaFlowControl_e;
|
||||
|
||||
/** \brief List of DMA transfer data width in peripheral involved case */
|
||||
typedef enum
|
||||
{
|
||||
DMA_DATA_WIDTH_NO_USE = 0, /**< Data width is set to 0 in memory to memory transfer */
|
||||
DMA_DATA_WIDTH_ONE_BYTE = 1U, /**< Data widath is 1 byte in peripheral involved transfer */
|
||||
DMA_DATA_WIDTH_TWO_BYTES = 2U, /**< Data widath is 2 bytes in peripheral involved transfer */
|
||||
DMA_DATA_WIDTH_FOUR_BYTES = 3U, /**< Data widath is 4 bytes in peripheral involved transfer */
|
||||
} DmaDataWidth_e;
|
||||
|
||||
/** \brief Maximum burst size of each data transfer */
|
||||
typedef enum
|
||||
{
|
||||
DMA_BURST_4_BYTES = 0, /**< Burst size is set to reserved */
|
||||
DMA_BURST_8_BYTES = 1U, /**< Burst size is set to 8 bytes */
|
||||
DMA_BURST_16_BYTES = 2U, /**< Burst size is set to 16 bytes */
|
||||
DMA_BURST_32_BYTES = 3U, /**< Burst size is set to 32 bytes */
|
||||
DMA_BURST_64_BYTES = 4U, /**< Burst size is set to 64 bytes */
|
||||
} DmaBurstSize_e;
|
||||
|
||||
/** \brief DMA transfer configuration structure */
|
||||
typedef struct
|
||||
{
|
||||
void *sourceAddress; /**< Source address */
|
||||
void *targetAddress; /**< Target address */
|
||||
DmaFlowControl_e flowControl; /**< Flow control setting */
|
||||
DmaAddressIncrement_e addressIncrement; /**< Address increment setting */
|
||||
DmaDataWidth_e dataWidth; /**< Data width setting */
|
||||
DmaBurstSize_e burstSize; /**< Burst size setting */
|
||||
uint32_t totalLength; /**< Transfer length onetime, less than 8k bytes. In descriptor chain it means every transfer's size */
|
||||
} DmaTransferConfig_t;
|
||||
|
||||
/** \brief DMA descriptor extra configuration structure for descriptor-chain mode */
|
||||
typedef struct
|
||||
{
|
||||
void *nextDesriptorAddress; /**< Next descriptor address */
|
||||
bool stopDecriptorFetch; /**< Indicate whether this is the last descriptor */
|
||||
bool enableStartInterrupt; /**< Start interrupt control */
|
||||
bool enableEndInterrupt; /**< End interrupt control */
|
||||
} DmaExtraConfig_t;
|
||||
|
||||
/** \brief DMA descriptor structure */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t DAR; /**< DMA Descriptor Address */
|
||||
uint32_t SAR; /**< DMA Source Address */
|
||||
uint32_t TAR; /**< DMA Target Address */
|
||||
uint32_t CMDR; /**< DMA Command */
|
||||
} DmaDescriptor_t;
|
||||
|
||||
/** \brief List of DMA interrupt sources */
|
||||
typedef enum
|
||||
{
|
||||
/** Stop interrupt enable, when enabled, interrupt is triggered after the channel stops */
|
||||
DMA_STOP_INTERRUPT_ENABLE = (1U << 29U),
|
||||
/** EOR interrupt enable, when enabled, interrupt is triggered on End-Of-Receive condition */
|
||||
DMA_EOR_INTERRUPT_ENABLE = (1U << 28U),
|
||||
/** Start interrupt enable, when enabled, interrupt is triggered as soon as descriptor is loaded, valid for descriptor-chain-mode */
|
||||
DMA_START_INTERRUPT_ENABLE = (1U << 22U),
|
||||
/** End interrupt enable, when enabled, interrupt is triggered when transfer length decrements to 0 */
|
||||
DMA_END_INTERRUPT_ENABLE = (1U << 21U),
|
||||
} DmaInterruptEnable_e;
|
||||
|
||||
/** \brief List of DMA available intances */
|
||||
typedef enum
|
||||
{
|
||||
DMA_INSTANCE_AP,
|
||||
DMA_INSTANCE_MP,
|
||||
DMA_INSTANCE_MAX,
|
||||
} DmaInstance_e;
|
||||
|
||||
/** DMA specific error codes */
|
||||
#define ARM_DMA_ERROR_CHANNEL_ALLOC (ARM_DRIVER_ERROR_SPECIFIC - 1) /**< No free channel any more */
|
||||
#define ARM_DMA_ERROR_CHANNEL_NOT_OPEN (ARM_DRIVER_ERROR_SPECIFIC - 2) /**< Specific channel not open */
|
||||
#define ARM_DMA_ERROR_CHANNEL_NOT_STOPPED (ARM_DRIVER_ERROR_SPECIFIC - 3) /**< Specific channel not stopped */
|
||||
#define ARM_DMA_ERROR_ADDRESS_NOT_ALIGNED (ARM_DRIVER_ERROR_SPECIFIC - 4) /**< Address alignment check failure */
|
||||
|
||||
|
||||
/** List of events reported to application */
|
||||
#define DMA_EVENT_ERROR (1) /**< Bus error */
|
||||
#define DMA_EVENT_START (2) /**< Descriptor load successfully */
|
||||
#define DMA_EVENT_END (3) /**< Transaction end */
|
||||
#define DMA_EVENT_EOR (4) /**< Receive EOR signal */
|
||||
#define DMA_EVENT_STOP (5) /**< Channel has stopped */
|
||||
|
||||
/**
|
||||
\brief Defines callback function prototype.
|
||||
Callback function will be called in DMA interrupt service routine after a transaction is complete
|
||||
\param event transaction event for the current transaction, application can get the tansaction
|
||||
result from this paramter, available events: DMA_EVENT_ERROR, DMA_EVENT_START, DMA_EVENT_END, DMA_EVENT_EOR, DMA_EVENT_STOP
|
||||
*/
|
||||
typedef void (*dma_callback_t)(uint32_t event);
|
||||
|
||||
/** \brief timeout value when stopping channel */
|
||||
#define DMA_STOP_TIMEOUT (5000U)
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\fn void DMA_init(DmaInstance_e instance)
|
||||
\brief Intialize DMA hareware and internal used structure, call this function before any other DMA APIs
|
||||
*/
|
||||
void DMA_init(DmaInstance_e instance);
|
||||
|
||||
/** \name DMA Channel operation API */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn int32_t DMA_openChannel(DmaInstance_e instance)
|
||||
\brief Opens a DMA channel
|
||||
\return Channel on successful allocate
|
||||
ARM_DMA_ERROR_CHANNEL_ALLOC when no free channel is found
|
||||
\note Caller shall check the return code
|
||||
*/
|
||||
int32_t DMA_openChannel(DmaInstance_e instance);
|
||||
|
||||
/**
|
||||
\fn int32_t DMA_closeChannel(DmaInstance_e instance, uint32_t channel)
|
||||
\brief Closes a DMA channel
|
||||
\param[in] instance
|
||||
\param[in] channel DMA channel number
|
||||
\return ARM_DRIVER_OK if no error happens
|
||||
ARM_DMA_ERROR_CHANNEL_NOT_OPEN when channel is not open
|
||||
\note This API will call \ref DMA_stopChannel to stop channel first if channel is running before close
|
||||
*/
|
||||
int32_t DMA_closeChannel(DmaInstance_e instance, uint32_t channel);
|
||||
|
||||
/**
|
||||
\fn void DMA_startChannel(DmaInstance_e instance, uint32_t channel)
|
||||
\brief Activates the DMA channel
|
||||
\param[in] instance
|
||||
\param[in] channel DMA channel number
|
||||
*/
|
||||
void DMA_startChannel(DmaInstance_e instance, uint32_t channel);
|
||||
|
||||
/**
|
||||
\fn int32_t DMA_stopChannel(uint32_t channel, bool waitForStop)
|
||||
\brief Stops the DMA channel from running
|
||||
\param[in] channel DMA channel number
|
||||
\param[in] waitForStop whether to wait channel to fully stop or not
|
||||
\return ARM_DRIVER_OK if stops successfully
|
||||
ARM_DMA_ERROR_CHANNEL_NOT_STOPPED if channel fails to stop until timeout expires
|
||||
\note staus and interrupt flags will be cleared in this function call
|
||||
*/
|
||||
int32_t DMA_stopChannel(DmaInstance_e instance, uint32_t channel, bool waitForStop);
|
||||
|
||||
/**
|
||||
\fn void DMA_resetChannel(uint32_t channel)
|
||||
|
||||
\brief Put the DMA channel to reset state
|
||||
\param[in] channel DMA channel number
|
||||
\note Make sure DMA is stopped before calling this function
|
||||
*/
|
||||
void DMA_resetChannel(DmaInstance_e instance, uint32_t channel);
|
||||
|
||||
/**
|
||||
\fn void DMA_rigisterChannelCallback(uint32_t channel, dma_callback_t callback)
|
||||
\brief Registers a DMA callback
|
||||
\param[in] channel DMA channel number
|
||||
\param[in] callback Given by the application and will be called in DMA interrupt service routine
|
||||
*/
|
||||
void DMA_rigisterChannelCallback(DmaInstance_e instance, uint32_t channel, dma_callback_t callback);
|
||||
|
||||
/**
|
||||
\fn void DMA_enableChannelInterrupts(uint32_t channel, uint32_t mask)
|
||||
\brief Enables DMA interrupts
|
||||
\param[in] channel DMA channel number
|
||||
\param[in] mask Mask of interrupt source to be set, can be ORed by items list in \ref DmaInterruptEnable_e
|
||||
\note In no-descriptor-fetch mode, all interrupt sources can be enabled by calling this API, however, in descritor-fetch
|
||||
mode, only \ref DMA_STOP_INTERRUPT_ENABLE \ref DMA_EOR_INTERRUPT_ENABLE can be done by this function call,
|
||||
the \ref DMA_START_INTERRUPT_ENABLE and \ref DMA_END_INTERRUPT_ENABLE is controlled by setting in \ref DmaExtraConfig_t respectively.
|
||||
*/
|
||||
void DMA_enableChannelInterrupts(DmaInstance_e instance, uint32_t channel, uint32_t mask);
|
||||
|
||||
/**
|
||||
\fn void DMA_disableChannelInterrupts(uint32_t channel, uint32_t mask)
|
||||
\brief Disables DMA interrupts
|
||||
\param[in] channel DMA channel number
|
||||
\param[in] mask Mask of interrupt source to be disabled, can be ORed by items list in \ref DmaInterruptEnable_e
|
||||
\note In no-descriptor-fetch mode, all interrupt sources can be disabled by calling this API, however, in descritor-fetch
|
||||
mode, only \ref DMA_STOP_INTERRUPT_ENABLE \ref DMA_EOR_INTERRUPT_ENABLE can be done by this function call ,
|
||||
the \ref DMA_START_INTERRUPT_ENABLE and \ref DMA_END_INTERRUPT_ENABLE is controlled by setting in \ref DmaExtraConfig_t respectively.
|
||||
*/
|
||||
void DMA_disableChannelInterrupts(DmaInstance_e instance, uint32_t channel, uint32_t mask);
|
||||
|
||||
/**
|
||||
\fn uint32_t DMA_getEnabledInterrupts(uint32_t channel)
|
||||
\brief Gets current enabled DMA channel interrupts
|
||||
\param[in] channel DMA channel number
|
||||
\return The logical OR of members of the enumeration \ref DmaInterruptEnable_e
|
||||
*/
|
||||
uint32_t DMA_getEnabledInterrupts(DmaInstance_e instance, uint32_t channel);
|
||||
|
||||
/**
|
||||
\fn uint32_t DMA_getChannelCount(uint32_t channel)
|
||||
\brief Obtains courrent transferred data length of a transaction in unit of byte
|
||||
\param[in] channel DMA channel number
|
||||
\return Size of data has been transferred
|
||||
\note In descritor-fetch mode, Start Interrupt shall be enabled by enableStartInterrupt setting in \ref DmaExtraConfig_t
|
||||
so that driver can load total transfer number for calculation before transferring.
|
||||
*/
|
||||
uint32_t DMA_getChannelCount(DmaInstance_e instance, uint32_t channel);
|
||||
|
||||
/**
|
||||
\fn void DMA_setChannelRequestSource(uint32_t channel, DmaRequestSource_e request)
|
||||
\brief Configures DMA request source
|
||||
\param[in] channel DMA channel number
|
||||
\param[in] request DMA request binded to this channel
|
||||
*/
|
||||
void DMA_setChannelRequestSource(DmaInstance_e instance, uint32_t channel, DmaRequestSource_e request);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name DMA register mode API */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void DMA_transferSetup(DmaInstance_e instance, uint32_t channel, const DmaTransferConfig_t* config)
|
||||
\brief Setups DMA channel according to user's transfer configuration, usded for register mode
|
||||
\param[in] instance
|
||||
\param[in] channel DMA channel number
|
||||
\param[in] config Pointer to transfer configuration
|
||||
\note user configuration shall be retaining(global variable) for it will be used again after exit from low power
|
||||
*/
|
||||
void DMA_transferSetup(DmaInstance_e instance, uint32_t channel, const DmaTransferConfig_t* config);
|
||||
/** \} */
|
||||
|
||||
/** \name DMA descriptor chain mode API */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void DMA_buildDescriptor(DmaDescriptor_t* descriptor, const DmaTransferConfig_t* config, const DmaExtraConfig_t* extraConfig)
|
||||
\brief Builds a descritor for DMA mode use
|
||||
\param[out] descriptor Pointer to DMA descriptor instance
|
||||
\param[in] config Pointer to transfer configuration
|
||||
\param[in] extraConfig Pointer to extra configuration which is invalid in descriptor-chain-mode only
|
||||
\note descriptor shall be retaining(global variable) for it will be used again after exit from low power
|
||||
*/
|
||||
|
||||
void DMA_buildDescriptor(DmaDescriptor_t* descriptor, const DmaTransferConfig_t* config, const DmaExtraConfig_t* extraConfig);
|
||||
|
||||
/**
|
||||
\fn void DMA_buildDescriptorChain(DmaDescriptor_t* descriptorArray, const DmaTransferConfig_t* config, const uint16_t chainCnt)
|
||||
\brief Builds a descritor for DMA chain mode use
|
||||
\param[out] descriptorArray Pointer to DMA descriptor chain array, should aligned with 16byte
|
||||
\param[in] config Pointer to transfer configuration
|
||||
\param[in] chainCnt The count of descriptor chain
|
||||
\param[in] needStop Need cycling transfer data or not
|
||||
\note descriptor shall be retaining(global variable) for it will be used again after exit from low power
|
||||
*/
|
||||
|
||||
void DMA_buildDescriptorChain(DmaDescriptor_t* descriptorArray, const DmaTransferConfig_t* config, const uint16_t chainCnt, bool needStop);
|
||||
|
||||
/**
|
||||
\fn int32_t DMA_loadChannelFirstDescriptor(DmaInstance_e instance, uint32_t channel, void* descriptorAddress)
|
||||
\brief Loads first descritor
|
||||
\param[in] instance
|
||||
\param[in] channel DMA channel number
|
||||
\param[in] descriptorAddress Address of descriptor from which to load, shall be aligend on a 16-byte boundary in memory
|
||||
\return ARM_DRIVER_OK if success
|
||||
ARM_DMA_ERROR_ADDRESS_NOT_ALIGNED on address alignment check failure
|
||||
*/
|
||||
int32_t DMA_loadChannelFirstDescriptor(DmaInstance_e instance, uint32_t channel, void* descriptorAddress);
|
||||
|
||||
/**
|
||||
\fn void DMA_loadChannelDescriptorAndRun(DmaInstance_e instance, uint32_t channel, void* descriptorAddress)
|
||||
\brief Loads first descritor and run
|
||||
\param[in] instance
|
||||
\param[in] channel DMA channel number
|
||||
\param[in] descriptorAddress Address of descriptor from which to load, shall be aligend on a 16-byte boundary in memory
|
||||
\return ARM_DRIVER_OK if success
|
||||
ARM_DMA_ERROR_ADDRESS_NOT_ALIGNED on address alignment check failure
|
||||
*/
|
||||
void DMA_loadChannelDescriptorAndRun(DmaInstance_e instance, uint32_t channel, void* descriptorAddress);
|
||||
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,80 @@
|
||||
/******************************************************************************
|
||||
|
||||
*(C) Copyright 2018 AirM2M International Ltd.
|
||||
|
||||
* All Rights Reserved
|
||||
|
||||
******************************************************************************
|
||||
* Filename:flash_rt.h
|
||||
*
|
||||
* Description:EC618 flash header file
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#ifndef _FLASH_EC618_RT_H
|
||||
#define _FLASH_EC618_RT_H
|
||||
/*----------------------------------------------------------------------------*
|
||||
* INCLUDES *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* MACROS *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/* QSPI Error codes */
|
||||
#define QSPI_OK ((uint8_t)0x00)
|
||||
#define QSPI_ERROR ((uint8_t)0x01)
|
||||
#define QSPI_BUSY ((uint8_t)0x02)
|
||||
#define QSPI_NOT_SUPPORTED ((uint8_t)0x04)
|
||||
#define QSPI_SUSPENDED ((uint8_t)0x08)
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* DATA TYPE DEFINITION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
|
||||
QSPI_OP_ERASE = 0,
|
||||
QSPI_OP_WRITE,
|
||||
}QSPI_OpType_e;
|
||||
|
||||
|
||||
/**
|
||||
\brief definition of the flash operation callback, register using BSP_QSPI_Reg_Operation_Cb
|
||||
call when flash erase and write happens.
|
||||
\param[in] result the QSPI Error codes, listed above
|
||||
\param[in] type to indicate erase or write
|
||||
\param[in] address operation address
|
||||
\param[in] size operation size
|
||||
\return null
|
||||
*/
|
||||
typedef void (*BSP_QSPI_OperCallback_t)(uint8_t result, QSPI_OpType_e type, uint32_t address, uint32_t size);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* GLOBAL FUNCTIONS DECLEARATION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
uint8_t BSP_QSPI_Cfg_Gran_Size(uint16_t WriteGranSize);
|
||||
uint8_t BSP_QSPI_Erase_Safe(uint32_t SectorAddress, uint32_t Size);
|
||||
uint8_t BSP_QSPI_Write_Safe(uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
|
||||
uint8_t BSP_QSPI_Read_Safe(uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
|
||||
|
||||
/**
|
||||
\fn void BSP_QSPI_Reg_Operation_Cb(BSP_QSPI_OperCallback_t cb);
|
||||
\brief register a user callback to get flash operation info. No time consuming operation allowed in this callback.
|
||||
*/
|
||||
void BSP_QSPI_Reg_Operation_Cb(BSP_QSPI_OperCallback_t cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2017-, Copyrigths of AirM2M Ltd.
|
||||
* File name: gpio.h
|
||||
* Description: EC618 gpio driver header file
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _GPIO_EC618_H
|
||||
#define _GPIO_EC618_H
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
|
||||
/**
|
||||
\addtogroup gpio_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/** \brief GPIO pin direction */
|
||||
typedef enum
|
||||
{
|
||||
GPIO_DIRECTION_INPUT = 0U, /**< Set pin as input */
|
||||
GPIO_DIRECTION_OUTPUT = 1U, /**< Set pin as output */
|
||||
} GpioPinDirection_e;
|
||||
|
||||
/** \brief GPIO pin interrupt configuration */
|
||||
typedef enum
|
||||
{
|
||||
GPIO_INTERRUPT_DISABLED = 0U, /**< Disable interrupt */
|
||||
GPIO_INTERRUPT_LOW_LEVEL = 1U, /**< Low-level interrupt */
|
||||
GPIO_INTERRUPT_HIGH_LEVEL = 2U, /**< High-level interrupt */
|
||||
GPIO_INTERRUPT_FALLING_EDGE = 3U, /**< Falling edge interrupt */
|
||||
GPIO_INTERRUPT_RISING_EDGE = 4U, /**< Rising edge interrupt */
|
||||
} GpioInterruptConfig_e;
|
||||
|
||||
/** \brief GPIO pin configuration structure */
|
||||
typedef struct
|
||||
{
|
||||
GpioPinDirection_e pinDirection; /**< GPIO direction, input or output */
|
||||
union
|
||||
{
|
||||
GpioInterruptConfig_e interruptConfig; /**< Pin's interrupt configuration, valid when pinDirection is input */
|
||||
uint32_t initOutput; /**< Initial pin output value, valid when pinDirection is output*/
|
||||
} misc;
|
||||
} GpioPinConfig_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \name GPIO Driver Initialization */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void GPIO_driverInit(void);
|
||||
\brief Intialize GPIO driver internal data
|
||||
\note It is not necessarty to call this function before using GPIO driver since it has been
|
||||
called in \ref GPIO_pinConfig() api.
|
||||
*/
|
||||
void GPIO_driverInit(void);
|
||||
|
||||
/**
|
||||
\fn void GPIO_driverDeInit(void);
|
||||
\brief De-Intialize GPIO driver, disable GPIO clock and perform some clearups
|
||||
*/
|
||||
void GPIO_driverDeInit(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name GPIO Configuration */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void GPIO_pinConfig(uint32_t port, uint16_t pin, const GpioPinConfig_t *config);
|
||||
\brief Configure a GPIO pin
|
||||
\param[in] port GPIO number (0, 1, ...)
|
||||
\param[in] pin GPIO pin number
|
||||
\param[in] config Pointer to GPIO pin configuration
|
||||
*/
|
||||
void GPIO_pinConfig(uint32_t port, uint16_t pin, const GpioPinConfig_t *config);
|
||||
|
||||
/**
|
||||
\fn void GPIO_interruptConfig(uint32_t port, uint16_t pin, GpioInterruptConfig_e config);
|
||||
\brief Configure a GPIO pin's interrupt type(valid when this pin has been set as input)
|
||||
\param[in] port GPIO number (0, 1, ...)
|
||||
\param[in] pin GPIO pin number
|
||||
\param[in] config GPIO interrupt configuration
|
||||
*/
|
||||
void GPIO_interruptConfig(uint32_t port, uint16_t pin, GpioInterruptConfig_e config);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name GPIO Output Operations */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void GPIO_pinWrite(uint32_t port, uint16_t pinMask, uint16_t output);
|
||||
\brief Sets output level of multiple GPIO pins to logic 1 or 0
|
||||
|
||||
\code
|
||||
Example to set bits[15,1:0] to 1 and clear bits[12:11, 7:6]
|
||||
|
||||
// pinMask shall be b10011000 11000011 = 0x98C3
|
||||
// output shall be b10000000 00000011 = 0x8003
|
||||
GPIO_pinWrite(0, 0x98C3, 0x8003);
|
||||
// To set a single pin, let's say, pin 12 of GPIO0
|
||||
GPIO_pinWrite(0, 1 << 12, 1 << 12);
|
||||
// To clear a single pin, let's say, pin 12 of GPIO0
|
||||
GPIO_pinWrite(0, 1 << 12, 0);
|
||||
|
||||
\endcode
|
||||
|
||||
\param[in] port GPIO number (0, 1, ...)
|
||||
\param[in] pinMask GPIO pin mask to set
|
||||
\param[in] output GPIO pin output logic level.
|
||||
- 0: corresponding pin output low-logic level.
|
||||
- 1: corresponding pin output high-logic level.
|
||||
*/
|
||||
void GPIO_pinWrite(uint32_t port, uint16_t pinMask, uint16_t output);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name GPIO Input Operations */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn uint32_t GPIO_pinRead(uint32_t port, uint16_t pin)
|
||||
\brief Reads current input value of GPIO specific pin
|
||||
\param[in] port GPIO number (0, 1, ...)
|
||||
\param[in] pin GPIO pin number
|
||||
\return GPIO corresponding pin input value
|
||||
*/
|
||||
uint32_t GPIO_pinRead(uint32_t port, uint16_t pin);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name GPIO Interrupt */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn uint16_t GPIO_getInterruptFlags(uint32_t port)
|
||||
\brief Reads GPIO port interrupt status flags
|
||||
\param[in] port GPIO number (0, 1, ...)
|
||||
\return current GPIO interrupt status flag
|
||||
*/
|
||||
uint16_t GPIO_getInterruptFlags(uint32_t port);
|
||||
|
||||
/**
|
||||
\fn void GPIO_clearInterruptFlags(uint32_t port, uint16_t mask)
|
||||
\brief Clears multiple GPIO pin interrupt status flags
|
||||
\param[in] port GPIO number (0, 1, ...)
|
||||
\param[in] mask GPIO pin number macro
|
||||
*/
|
||||
void GPIO_clearInterruptFlags(uint32_t port, uint16_t mask);
|
||||
|
||||
/**
|
||||
\fn uint16_t GPIO_saveAndSetIrqMask(uint32_t port)
|
||||
\brief Reads GPIO port interrupt enable mask and diables whole port interrupts
|
||||
\param[in] port GPIO number (0, 1, ...)
|
||||
\return current GPIO port interrupt enable mask
|
||||
\note Used in GPIO ISR to disable GPIO interrupts temporarily
|
||||
*/
|
||||
uint16_t GPIO_saveAndSetIrqMask(uint32_t port);
|
||||
|
||||
/**
|
||||
\fn void GPIO_restoreIrqMask(uint32_t port, uint16_t mask)
|
||||
\brief Restore GPIO port interrupt enable setting
|
||||
\param[in] port GPIO number (0, 1, ...)
|
||||
\param[in] mask GPIO interrupt enable mask
|
||||
\note Used in GPIO ISR to restore GPIO enable setting upon exit
|
||||
*/
|
||||
void GPIO_restoreIrqMask(uint32_t port, uint16_t mask);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GPIO_EC618_H */
|
||||
@@ -0,0 +1,310 @@
|
||||
#define RMI_GPR_TOP_CLKEN_REG_INDEX (0)
|
||||
#define RMI_GPR_XPSYS_CLKEN_REG_INDEX (1)
|
||||
|
||||
#define APB_GPR_TOP_MP_CLKEN_REG_INDEX (2)
|
||||
#define APB_GPR_TOP_AP_CLKEN_REG_INDEX (3)
|
||||
|
||||
#define APB_GPR_APB_MP_PCLK_EN_REG_INDEX (4)
|
||||
#define APB_GPR_APB_AP_PCLK_EN_REG_INDEX (5)
|
||||
|
||||
#define APB_GPR_APB_MP_FCLK_EN_REG_INDEX (6)
|
||||
#define APB_GPR_APB_AP_FCLK_EN_REG_INDEX (7)
|
||||
|
||||
#define APB_GPR_TOP_ALL_CLKEN_REG_INDEX (8)
|
||||
|
||||
#define CLKEN_REG_INDEX_MAX (0xF)
|
||||
|
||||
/**
|
||||
|-----registerAccessIndex-----|-----bitPosition-----|---------index---------|
|
||||
|------------4 bit------------|--------5 bit--------|---------8 bit---------|
|
||||
*/
|
||||
#define CONSTRUCT_CLOCK_ID(registerAccessIndex, bitPosition, index) \
|
||||
(((registerAccessIndex) << 13) | ((bitPosition) << 8) | (index))
|
||||
|
||||
|
||||
/** Macro to extract index from clock id value */
|
||||
#define GET_INDEX_FROM_CLOCK_ID(value) ((value) & 0xFFU)
|
||||
|
||||
/** Macro to extract bitPosition from clock id value */
|
||||
#define GET_BP_FROM_CLOCK_ID(value) ((value >> 8U) & 0x1FU)
|
||||
|
||||
/** Macro to extract registerAccessIndex from clock id value */
|
||||
#define GET_RAI_FROM_CLOCK_ID(value) ((value >> 13U) & 0xFU)
|
||||
|
||||
/**
|
||||
|-----clockIdIndex-----|-----value-----|-----parentClockId-----|
|
||||
|---------8 bit--------|-----4 bit-----|--------17 bit---------|
|
||||
*/
|
||||
/** Macro to compose clock select value */
|
||||
#define MAKE_CLOCK_SEL_VALUE(clockIdIndex, value, parentClockId) \
|
||||
((clockIdIndex << 21U) | value << 17U | parentClockId)
|
||||
|
||||
/** Macro to extract clockId from clock select value */
|
||||
#define GET_CLOCKIDINDEX_FROM_CLOCK_SEL_VALUE(value) ((value >> 21U) & 0xFFUL)
|
||||
|
||||
/** Macro to extract value from clock select value */
|
||||
#define GET_VALUE_FROM_CLOCK_SEL_VALUE(value) ((value >> 17U) & 0xFUL)
|
||||
|
||||
/** Macro to extract parentClockId from clock select value */
|
||||
#define GET_PARENTCLOCKID_FROM_CLOCK_SEL_VALUE(value) (value & 0x1FFFFUL)
|
||||
|
||||
|
||||
#define APB_GPR_TOP_AP_RST_REQ_REG_INDEX (0)
|
||||
#define APB_GPR_APB_MP_PRST_REQ_REG_INDEX (1)
|
||||
|
||||
#define APB_GPR_APB_AP_PRST_REQ_REG_INDEX (2)
|
||||
#define APB_GPR_APB_MP_FRST_REQ_REG_INDEX (3)
|
||||
#define APB_GPR_APB_AP_FRST_REQ_REG_INDEX (4)
|
||||
|
||||
#define RMI_GPR_TOP_RSTREQ_REG_INDEX (5)
|
||||
#define RMI_GPR_XPSYS_RSTREQ_REG_INDEX (6)
|
||||
|
||||
|
||||
/**
|
||||
|-----registerAccessIndex-----|-----bitPosition-----|
|
||||
|------------4 bit------------|--------8 bit--------|
|
||||
*/
|
||||
#define CONSTRUCT_CLOCK_RESET_ID(registerAccessIndex, bitPosition) \
|
||||
(((registerAccessIndex) << 8) | (bitPosition))
|
||||
|
||||
/** Macro to extract bitPosition from clock reset id value */
|
||||
#define GET_BP_FROM_CLOCK_RESET_ID(value) ((value) & 0xFFU)
|
||||
|
||||
/** Macro to extract registerAccessIndex from clock reset id value */
|
||||
#define GET_RAI_FROM_CLOCK_RESET_ID(value) ((value >> 8U) & 0xFU)
|
||||
|
||||
|
||||
/** \brief List of IDs used for sw reset control */
|
||||
typedef enum
|
||||
{
|
||||
/* Top AP Reset */
|
||||
RST_AP_FABSYS_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 0), /**< Ap fab sys AHB reset */
|
||||
RST_AP_RMI_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 1), /**< Ap RMI AHB reset */
|
||||
RST_MFAB_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 2), /**< MFAB AHB reset */
|
||||
RST_AFBBR_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 3), /**< AFBBR AHB reset */
|
||||
RST_CFBBR_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 4), /**< CFBBR AHB reset */
|
||||
RST_MSMB_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 5), /**< MSMB AHB reset */
|
||||
RST_FLASH_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 6), /**< Flash AHB reset */
|
||||
RST_PSRAM_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 7), /**< Psram AHB reset */
|
||||
RST_ULOG_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 8), /**< Unilog AHB reset */
|
||||
RST_USBC_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 9), /**< Usbc AHB reset */
|
||||
RST_CLK_FLASH = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 10), /**< Flash Func reset */
|
||||
RST_CLK_PSRAM = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 11), /**< Psram Func reset */
|
||||
RST_AONIF = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 12), /**< Aonif reset */
|
||||
RST_LPUA = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 13), /**< Lpua reset */
|
||||
RST_CLK_FRACDIV = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 14), /**< Fracdiv reset */
|
||||
RST_ULOG_SMP = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 15), /**< Unilog Smp reset */
|
||||
RST_FCLK_FUSE = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 16), /**< Fuse Func reset */
|
||||
RST_UTFC_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 17), /**< UTfc AHB reset */
|
||||
RST_ULDP_HCLK = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 18), /**< Uldp AHB reset */
|
||||
// reserved = 19~26,
|
||||
RST_USBC_PHY = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 27), /**< Usbc PHY reset */
|
||||
RST_USBP_POR = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 28), /**< USBP Por reset */
|
||||
RST_USBP_UTMI = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_TOP_AP_RST_REQ_REG_INDEX, 29), /**< USBP Utmi reset */
|
||||
|
||||
/* APB MP Reset */
|
||||
// reserved = 0,
|
||||
RST_PCLK_SIPC = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 1), /**< Sipc APB reset */
|
||||
RST_PCLK_AON = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 2), /**< Aon APB reset */
|
||||
RST_PCLK_CPMU = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 3), /**< Cpmu APB reset */
|
||||
RST_PCLK_PMDIG = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 4), /**< Pmdig APBreset */
|
||||
RST_PCLK_RFDIG = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 5), /**< Rfdig APB reset */
|
||||
RST_PCLK_PAD = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 6), /**< Pad APB reset */
|
||||
RST_PCLK_GPIO = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 7), /**< Gpio APB reset */
|
||||
RST_PCLK_FUSE = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 8), /**< Fuse APB reset */
|
||||
RST_PCLK_TRNG = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 9), /**< Trng APB reset */
|
||||
RST_PCLK_USBP = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 10), /**< Usbp APB reset */
|
||||
RST_PCLK_LPUC = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 11), /**< Lpuc APB reset */
|
||||
RST_PCLK_UART0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 12), /**< Uart0 APB reset */
|
||||
RST_PCLK_UART1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 13), /**< Uart1 APB reset */
|
||||
RST_PCLK_UART2 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 14), /**< Uart2 APB reset */
|
||||
RST_PCLK_SPI0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 15), /**< Ssp 0 APB reset */
|
||||
RST_PCLK_SPI1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 16), /**< Ssp 1 APB reset */
|
||||
RST_PCLK_I2S0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 17), /**< I2s 0 APB reset */
|
||||
RST_PCLK_I2S1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_PRST_REQ_REG_INDEX, 18), /**< I2s 1 APB reset */
|
||||
|
||||
/* APB AP Reset */
|
||||
RST_PCLK_WDG = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 0), /**< WDG APB reset */
|
||||
RST_PCLK_TIMER0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 1), /**< Timer0 APB reset */
|
||||
RST_PCLK_TIMER1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 2), /**< Timer1 APBreset */
|
||||
RST_PCLK_TIMER2 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 3), /**< Timer2 APB reset */
|
||||
RST_PCLK_TIMER3 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 4), /**< Timer3 APB reset */
|
||||
RST_PCLK_TIMER4 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 5), /**< Timer4 APB reset */
|
||||
RST_PCLK_TIMER5 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 6), /**< Timer5 APB reset */
|
||||
RST_PCLK_IPC = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 7), /**< IPC APB reset */
|
||||
RST_PCLK_I2C0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 8), /**< I2C0 APB reset */
|
||||
RST_PCLK_I2C1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 9), /**< I2C1 APB reset */
|
||||
RST_PCLK_USIM0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 10), /**< USIM0 APB reset */
|
||||
RST_PCLK_USIM1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 11), /**< USIM1 APB reset */
|
||||
RST_PCLK_KPC = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 12), /**< KPC APB reset */
|
||||
RST_PCLK_ONEW = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_PRST_REQ_REG_INDEX, 13), /**< ONEW APB reset */
|
||||
|
||||
|
||||
/* APB MP Func Reset */
|
||||
RST_FCLK_UART0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_FRST_REQ_REG_INDEX, 0), /**< Uart0 Func reset */
|
||||
RST_FCLK_UART1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_FRST_REQ_REG_INDEX, 1), /**< Uart1 Func reset */
|
||||
RST_FCLK_UART2 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_FRST_REQ_REG_INDEX, 2), /**< Uart2 Func reset */
|
||||
RST_FCLK_SPI0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_FRST_REQ_REG_INDEX, 3), /**< SSP0 Func reset */
|
||||
RST_FCLK_SPI1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_FRST_REQ_REG_INDEX, 4), /**< SSP1 Func reset */
|
||||
RST_FCLK_I2S0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_FRST_REQ_REG_INDEX, 5), /**< I2S0 Func reset */
|
||||
RST_FCLK_I2S1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_MP_FRST_REQ_REG_INDEX, 6), /**< I2S1 Func reset */
|
||||
|
||||
/* APB AP Func Reset */
|
||||
RST_FCLK_WDG = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 0), /**< WDG Func reset */
|
||||
RST_FCLK_TIMER0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 1), /**< TIMER0 Func reset */
|
||||
RST_FCLK_TIMER1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 2), /**< TIMER1 Func reset */
|
||||
RST_FCLK_TIMER2 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 3), /**< TIMER2 Func reset */
|
||||
RST_FCLK_TIMER3 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 4), /**< TIMER3 Func reset */
|
||||
RST_FCLK_TIMER4 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 5), /**< TIMER4 Func reset */
|
||||
RST_FCLK_TIMER5 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 6), /**< TIMER5 Func reset */
|
||||
RST_FCLK_I2C0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 7), /**< I2C0 Func reset */
|
||||
RST_FCLK_I2C1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 8), /**< I2C1 Func reset */
|
||||
RST_FCLK_USIM0 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 9), /**< USIM0 Func reset */
|
||||
RST_FCLK_USIM1 = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 10), /**< USIM1 Func reset */
|
||||
RST_FCLK_KPC = CONSTRUCT_CLOCK_RESET_ID(APB_GPR_APB_AP_FRST_REQ_REG_INDEX, 11), /**< KPC Func reset */
|
||||
|
||||
/* RMI TOP Reset */
|
||||
RST_TOP_PBRG_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_TOP_RSTREQ_REG_INDEX, 0), /**< DMA AHB domain reset */
|
||||
RST_TOP_PBRG_PCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_TOP_RSTREQ_REG_INDEX, 1), /**< DMA APB domain reset */
|
||||
RST_TOP_GPR_PCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_TOP_RSTREQ_REG_INDEX, 2), /**< GPR APB domain reset */
|
||||
|
||||
/* RMI XPSYS Reset */
|
||||
RST_CACHE_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 0), /**< GPR CACHE AHB domain reset */
|
||||
RST_FABSUB_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 1), /**< GPR FABSUB AHB domain reset */
|
||||
RST_SBU_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 2), /**< GPR SBU AHB domain reset */
|
||||
RST_PBRG_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 3), /**< GPR PDMA AHB domain reset */
|
||||
RST_SPIS_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 4), /**< GPR SPIS AHB domain reset */
|
||||
RST_XIC_RMI_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 5), /**< GPR XIC AHB domain reset */
|
||||
RST_ULOG_RMI_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 6), /**< GPR ULOG AHB domain reset */
|
||||
RST_TMU_RMI_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 7), /**< GPR TMU AHB domain reset */
|
||||
RST_SCT_RMI_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 8), /**< GPR SCT AHB domain reset */
|
||||
|
||||
RST_UTFC_RMI_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 11), /**< GPR UTFC AHB domain reset */
|
||||
RST_ULDP_RMI_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 12), /**< GPR ULDP AHB domain reset */
|
||||
RST_SCT_HCLK = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 13), /**< GPR SCT AHB reset */
|
||||
RST_PCLK_DMA = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 15), /**< GPR PDMA APB reset */
|
||||
RST_TMU_SMP = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 16), /**< GPR TMU SMP reset */
|
||||
RST_TMU_CLKCAL = CONSTRUCT_CLOCK_RESET_ID(RMI_GPR_XPSYS_RSTREQ_REG_INDEX, 17), /**< GPR TMU CLKCAL reset */
|
||||
} ClockResetId_e;
|
||||
|
||||
/** \brief typedef for reset whole module */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t idNumber; /**< number of ids this module contains */
|
||||
uint32_t delayCpuCycles; /**< the cycles need to delay after release */
|
||||
const ClockResetId_e* resetReleaseQueue; /**< pointer to the queue(array) of ids, reset & release operation sequence
|
||||
depends on the position of id in the array, so arrange it properly */
|
||||
} ClockResetVector_t;
|
||||
|
||||
#define RESET_RELEASE_DELAY_US (204)
|
||||
|
||||
#define MAKE_RESET_VECTOR(delay, ...) \
|
||||
{ \
|
||||
(sizeof((ClockResetId_e [])__VA_ARGS__) / sizeof(ClockResetId_e)), \
|
||||
(delay), \
|
||||
(const ClockResetId_e [])__VA_ARGS__ \
|
||||
}
|
||||
|
||||
#define RESET_VECTOR_PTR(v) ((ClockResetVector_t [])v)
|
||||
|
||||
#define UART0_RESET_VECTOR MAKE_RESET_VECTOR(RESET_RELEASE_DELAY_US, {RST_PCLK_UART0, RST_FCLK_UART0, RST_PCLK_UART0, RST_FCLK_UART0})
|
||||
#define UART1_RESET_VECTOR MAKE_RESET_VECTOR(RESET_RELEASE_DELAY_US, {RST_PCLK_UART1, RST_FCLK_UART1, RST_PCLK_UART1, RST_FCLK_UART1})
|
||||
#define UART2_RESET_VECTOR MAKE_RESET_VECTOR(RESET_RELEASE_DELAY_US, {RST_PCLK_UART2, RST_FCLK_UART2, RST_PCLK_UART2, RST_FCLK_UART2})
|
||||
|
||||
#define SPI0_RESET_VECTOR MAKE_RESET_VECTOR(RESET_RELEASE_DELAY_US, {RST_PCLK_SPI0, RST_FCLK_SPI0, RST_PCLK_SPI0, RST_FCLK_SPI0})
|
||||
#define SPI1_RESET_VECTOR MAKE_RESET_VECTOR(RESET_RELEASE_DELAY_US, {RST_PCLK_SPI1, RST_FCLK_SPI1, RST_PCLK_SPI1, RST_FCLK_SPI1})
|
||||
|
||||
#define KPC_RESET_VECTOR MAKE_RESET_VECTOR(RESET_RELEASE_DELAY_US, {RST_PCLK_KPC, RST_FCLK_KPC, RST_PCLK_KPC, RST_FCLK_KPC})
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FRACDIV_ROOT_CLK_26M,
|
||||
FRACDIC_ROOT_CLK_408M
|
||||
} FracDivRootClk_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FracDivRootClk_e source;
|
||||
uint32_t fracDiv0DivRatioInteger;
|
||||
uint32_t fracDiv0DivRatioFrac;
|
||||
uint32_t fracDiv1DivRatioInteger;
|
||||
uint32_t fracDiv1DivRatioFrac;
|
||||
} FracDivConfig_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FRACDIV0_OUT0,
|
||||
FRACDIV0_OUT1,
|
||||
FRACDIV0_OUT2,
|
||||
FRACDIV0_OUT3,
|
||||
|
||||
FRACDIV1_OUT0,
|
||||
FRACDIV1_OUT1,
|
||||
FRACDIV1_OUT2,
|
||||
FRACDIV1_OUT3
|
||||
} FracDivOutClkId_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BCLK0,
|
||||
BCLK1
|
||||
} BclkId_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MCLK0,
|
||||
MCLK1,
|
||||
MCLK2
|
||||
} MclkId_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BCLK_SRC_FRACDIV0_OUT0 = 1,
|
||||
BCLK_SRC_FRACDIV0_OUT1 = 2,
|
||||
BCLK_SRC_FRACDIV0_OUT2 = 3,
|
||||
BCLK_SRC_FRACDIV0_OUT3 = 4,
|
||||
|
||||
BCLK_SRC_FRACDIV1_OUT0 = 5,
|
||||
BCLK_SRC_FRACDIV1_OUT1 = 6,
|
||||
BCLK_SRC_FRACDIV1_OUT2 = 7,
|
||||
BCLK_SRC_FRACDIV1_OUT3 = 8,
|
||||
BCLK_SRC_CLK_MFG = 9,
|
||||
BCLK_SRC_19P2M = 10
|
||||
} BclkSrc_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MCLK_SRC_FRACDIV0_OUT0 = 1,
|
||||
MCLK_SRC_FRACDIV0_OUT1 = 2,
|
||||
MCLK_SRC_FRACDIV0_OUT2 = 3,
|
||||
MCLK_SRC_FRACDIV0_OUT3 = 4,
|
||||
|
||||
MCLK_SRC_FRACDIV1_OUT0 = 5,
|
||||
MCLK_SRC_FRACDIV1_OUT1 = 6,
|
||||
MCLK_SRC_FRACDIV1_OUT2 = 7,
|
||||
MCLK_SRC_FRACDIV1_OUT3 = 8,
|
||||
MCLK_SRC_CLK_MFG = 9,
|
||||
MCLK_SRC_19P2M = 10,
|
||||
MCLK_SRC_CLK_SMP = 11,
|
||||
MCLK_SRC_CLK_USBP_12M = 12,
|
||||
MCLK_SRC_CLK_USBP_48M = 13,
|
||||
MCLK_SRC_CLK_USBC_PHY = 14,
|
||||
} MclkSrc_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GPR_APRST_SWRST = 0,
|
||||
GPR_APRST_WDG,
|
||||
GPR_APRST_LOCKUP,
|
||||
GPR_APRST_INVALID,
|
||||
}ApRstSource_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GPR_CPRST_SWRST = 0,
|
||||
GPR_CPRST_WDG,
|
||||
GPR_CPRST_LOCKUP,
|
||||
GPR_CPRST_INVALID,
|
||||
}CpRstSource_e;
|
||||
|
||||
|
||||
@@ -0,0 +1,319 @@
|
||||
#ifndef BSP_I2S_H
|
||||
#define BSP_I2S_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
#include "hal_i2s.h" // To use some of typedef in this H file and the macro of DMA_CHAIN_NUM(can dynamic array in C99?)
|
||||
|
||||
#define POLLING_MODE 0x1
|
||||
#define DMA_MODE 0x2
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// I2S Setting field Start
|
||||
// All the I2S's parameters that need user to set are all put here
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define ES8388_IICADDR 0x11
|
||||
#define NAU88C22_IICADDR 0x1A
|
||||
#define ES8311_IICADDR 0x18
|
||||
|
||||
// Sample rate that 618 supports
|
||||
#define SAMPLE_RATE_8K 0x1
|
||||
#define SAMPLE_RATE_16K 0x2
|
||||
#define SAMPLE_RATE_32K 0x3
|
||||
#define SAMPLE_RATE_22_05K 0x4
|
||||
#define SAMPLE_RATE_44_1K 0x5
|
||||
#define SAMPLE_RATE_48K 0x6
|
||||
#define SAMPLE_RATE_96K 0x7
|
||||
|
||||
|
||||
// I2S0 Configuration
|
||||
#define RTE_I2S0 1
|
||||
#define RTE_I2S0_IO_MODE DMA_MODE
|
||||
|
||||
#define RTE_I2S0_MCLK_PAD_ADDR 39
|
||||
#define RTE_I2S0_MCLK_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_I2S0_BCLK_PAD_ADDR 35
|
||||
#define RTE_I2S0_BCLK_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_I2S0_LRCK_PAD_ADDR 36
|
||||
#define RTE_I2S0_LRCK_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_I2S0_DIN_PAD_ADDR 37
|
||||
#define RTE_I2S0_DIN_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_I2S0_DOUT_PAD_ADDR 38
|
||||
#define RTE_I2S0_DOUT_FUNC PAD_MUX_ALT1
|
||||
|
||||
// I2S1 Configuration
|
||||
#define RTE_I2S1 0
|
||||
#define RTE_I2S1_IO_MODE DMA_MODE
|
||||
|
||||
#define RTE_I2S1_MCLK_PAD_ADDR 18
|
||||
#define RTE_I2S1_MCLK_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_I2S1_BCLK_PAD_ADDR 19
|
||||
#define RTE_I2S1_BCLK_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_I2S1_LRCK_PAD_ADDR 20
|
||||
#define RTE_I2S1_LRCK_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_I2S1_DIN_PAD_ADDR 21
|
||||
#define RTE_I2S1_DIN_FUNC PAD_MUX_ALT1
|
||||
|
||||
#define RTE_I2S1_DOUT_PAD_ADDR 22
|
||||
#define RTE_I2S1_DOUT_FUNC PAD_MUX_ALT1
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// I2S Setting field End
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
/****** I2S Event *****/
|
||||
#define I2S_EVENT_TRANSFER_COMPLETE (1UL << 0) // Data Transfer completed
|
||||
#define I2S_EVENT_DATA_LOST (1UL << 1) // Data lost: Receive overflow / Transmit underflow
|
||||
#define I2S_EVENT_MODE_FAULT (1UL << 2) // Master Mode Fault (SS deactivated when Master)
|
||||
|
||||
// DMA I2S0 Request ID
|
||||
#define RTE_I2S0_DMA_TX_REQID DMA_REQUEST_I2S0_TX
|
||||
#define RTE_I2S0_DMA_RX_REQID DMA_REQUEST_I2S0_RX
|
||||
|
||||
// DMA I2S1 Request ID
|
||||
#define RTE_I2S1_DMA_TX_REQID DMA_REQUEST_I2S1_TX
|
||||
#define RTE_I2S1_DMA_RX_REQID DMA_REQUEST_I2S1_RX
|
||||
|
||||
typedef void (*i2sCbEvent_fn) (uint32_t event, uint32_t arg); // i2s callback event.
|
||||
|
||||
|
||||
// I2S IRQ
|
||||
typedef struct
|
||||
{
|
||||
IRQn_Type irqNum; // I2S IRQ Number
|
||||
IRQ_Callback_t cbIrq;
|
||||
} i2sIrq_t;
|
||||
|
||||
// I2S DMA
|
||||
typedef struct
|
||||
{
|
||||
DmaInstance_e txInstance; // Transmit DMA instance number
|
||||
int8_t txCh; // Transmit channel number
|
||||
uint8_t txReq; // Transmit DMA request number
|
||||
void (*txCb)(uint32_t event); // Transmit callback
|
||||
DmaDescriptor_t *txDescriptor; // Tx descriptor
|
||||
DmaInstance_e rxInstance; // Receive DMA instance number
|
||||
int8_t rxCh; // Receive channel number
|
||||
uint8_t rxReq; // Receive DMA request number
|
||||
void (*rxCb)(uint32_t event); // Receive callback
|
||||
DmaDescriptor_t *rxDescriptor; // Rx descriptor
|
||||
} i2sDma_t;
|
||||
|
||||
|
||||
// I2S PINS
|
||||
typedef const struct
|
||||
{
|
||||
PIN *mclk; // main clk Pin identifier
|
||||
PIN *bclk; // pixel clk Pin identifier
|
||||
PIN *lrck; // cs Pin identifier
|
||||
PIN *din; // din Pin identifier
|
||||
PIN *dout; // dout Pin identifier
|
||||
} i2sPins_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t busy; // Transmitter/Receiver busy flag
|
||||
uint8_t dataLost; // Data lost: Receive overflow / Transmit underflow (cleared on start of transfer operation)
|
||||
uint8_t modeFault; // Mode fault detected; optional (cleared on start of transfer operation)
|
||||
} i2sStatus_t;
|
||||
|
||||
// I2S Transfer Information (Run-Time)
|
||||
typedef struct
|
||||
{
|
||||
uint32_t num; // Total number of transfers
|
||||
uint8_t *rxBuf; // Pointer to in data buffer
|
||||
uint8_t *txBuf; // Pointer to out data buffer
|
||||
uint32_t rxCnt; // Number of data received
|
||||
uint32_t txCnt; // Number of data sent
|
||||
uint32_t dumpVal; // Variable for dumping DMA data
|
||||
uint16_t defVal; // Default transfer value
|
||||
} i2sTransferInfo_t;
|
||||
|
||||
// I2S information (Run-time)
|
||||
typedef struct
|
||||
{
|
||||
i2sCbEvent_fn txCbEvent; // tx event callback
|
||||
i2sCbEvent_fn rxCbEvent; // rx event callback
|
||||
uint32_t mode; // I2S mode
|
||||
uint32_t busSpeed; // I2S bus speed
|
||||
uint16_t chainCnt;
|
||||
uint32_t totalNum; // Total length of audio source
|
||||
} i2sInfo_t;
|
||||
|
||||
|
||||
// I2S Resources definition
|
||||
typedef struct
|
||||
{
|
||||
I2S_TypeDef *reg; // I2S register pointer
|
||||
i2sPins_t pins; // I2S PINS configuration
|
||||
i2sDma_t *dma; // I2S DMA configuration pointer
|
||||
i2sIrq_t *irq; // I2S IRQ configuration pointer
|
||||
i2sInfo_t *info; // Run-Time Information
|
||||
} i2sResources_t;
|
||||
|
||||
/**
|
||||
\brief General power states
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
I2S_POWER_OFF, // Power off: no operation possible
|
||||
I2S_POWER_FULL // Power on: full operation at maximum performance
|
||||
} i2sPowerState_e;
|
||||
|
||||
|
||||
/**
|
||||
\brief Access structure of the I2S Driver.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*init) (i2sCbEvent_fn txCbEvent, i2sCbEvent_fn rxCbEvent); // Initialize I2S Interface.
|
||||
int32_t (*deInit) (void); // De-initialize I2S Interface.
|
||||
int32_t (*powerCtrl) (i2sPowerState_e state); // Control I2S Interface Power.
|
||||
int32_t (*send) (void *data, uint32_t chunkNum); // Start sending data from I2S Interface.
|
||||
int32_t (*recv) (void *data, uint32_t chunkNum); // Start receiving data from I2S Interface.
|
||||
int32_t (*ctrl) (uint32_t control, uint32_t arg); // Control I2S Interface.
|
||||
uint32_t (*getTotalCnt) (void);
|
||||
} const i2sDrvInterface_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t slaveModeEn : 1; // Slave Mode Enable
|
||||
uint32_t slotSize : 5; // Slot Size
|
||||
uint32_t wordSize : 5; // Word Size
|
||||
uint32_t alignMode : 1; // Align Mode
|
||||
uint32_t endianMode : 1; // Endian Mode
|
||||
uint32_t dataDly : 2; // Data Delay
|
||||
uint32_t txPad : 2; // Tx Padding
|
||||
uint32_t rxSignExt : 1; // Rx Sign extention
|
||||
uint32_t txPack : 2; // Tx Pack
|
||||
uint32_t rxPack : 2; // Rx Pack
|
||||
uint32_t txFifoEndianMode : 1; // Tx Fifo Endian Mode
|
||||
uint32_t rxFifoEndianMode : 1; // Rx Fifo Endian Mode
|
||||
}i2sDataFmt_t;
|
||||
|
||||
/** \brief I2S Slot Control */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t slotEn : 8; // Slot Enable
|
||||
uint32_t slotNum : 3; // Slot number per frame synchronization
|
||||
}i2sSlotCtrl_t;
|
||||
|
||||
/** \brief I2S Bclk Frame Synchronization Control */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t bclkPolarity : 1; // Bclk Polarity
|
||||
uint32_t fsPolarity : 1; // Frame Synchronization Polarity
|
||||
uint32_t fsWidth : 6; // Frame Synchronization width
|
||||
}i2sBclkFsCtrl_t;
|
||||
|
||||
/** \brief I2S DMA Control */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t rxDmaReqEn : 1; // Rx Dma Req Enable
|
||||
uint32_t txDmaReqEn : 1; // Tx Dma Req Enable
|
||||
uint32_t rxDmaTimeOutEn : 1; // Rx Dma Timeout Enable
|
||||
uint32_t dmaWorkWaitCycle : 5; // Dma Work Wait Cycle
|
||||
uint32_t rxDmaBurstSizeSub1 : 4; // Rx Dma Burst Size subtract 1
|
||||
uint32_t txDmaBurstSizeSub1 : 4; // Tx Dma Burst Size subtract 1
|
||||
uint32_t rxDmaThreadHold : 4; // Rx Dma Threadhold
|
||||
uint32_t txDmaThreadHold : 4; // Tx Dma Threadhold
|
||||
uint32_t rxFifoFlush : 1; // Rx Fifo flush
|
||||
uint32_t txFifoFlush : 1; // Tx Fifo flush
|
||||
}i2sDmaCtrl_t;
|
||||
|
||||
/** \brief I2S Interrupt Control */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t txUnderRunIntEn : 1; // Tx Underrun interrupt Enable
|
||||
uint32_t txDmaErrIntEn : 1; // Tx Dma Err Interrupt Enable
|
||||
uint32_t txDatIntEn : 1; // Tx Data Interrupt Enable
|
||||
uint32_t rxOverFlowIntEn : 1; // Rx Overflow Interrupt Enable
|
||||
uint32_t rxDmaErrIntEn : 1; // Rx Dma Err Interrupt Enable
|
||||
uint32_t rxDatIntEn : 1; // Rx Data Interrupt Enable
|
||||
uint32_t rxTimeOutIntEn : 1; // Rx Timeout Interrupt Enable
|
||||
uint32_t fsErrIntEn : 1; // Frame Start Interrupt Enable
|
||||
uint32_t frameStartIntEn : 1; // Frame End Interrupt Enable
|
||||
uint32_t frameEndIntEn : 1; // Frame End Interrupt Enable
|
||||
uint32_t cspiBusTimeOutIntEn : 1; // Not use
|
||||
uint32_t txIntThreshHold : 4; // Tx Interrupt Threadhold
|
||||
uint32_t rxIntThreshHold : 4; // Rx Interrupt Threadhold
|
||||
}i2sIntCtrl_t;
|
||||
|
||||
/** \brief I2S Timeout Cycle */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t rxTimeOutCycle : 24; // Rx Timeout cycle
|
||||
}i2sTimeOutCycle_t;
|
||||
|
||||
/** \brief I2S Status */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t txUnderRun : 1; // Tx Underrun
|
||||
uint32_t txDmaErr : 1; // Tx Dma Err
|
||||
uint32_t txDataRdy : 1; // Tx Data ready, readOnly
|
||||
uint32_t rxOverFlow : 1; // Rx OverFlow
|
||||
uint32_t rxDmaErr : 1; // Rx Dma Err
|
||||
uint32_t rxDataRdy : 1; // Rx Data ready, readOnly
|
||||
uint32_t rxFifoTimeOut : 1; // Rx Fifo timeout
|
||||
uint32_t fsErr : 4; // Frame synchronization Err
|
||||
uint32_t frameStart : 1; // Frame start
|
||||
uint32_t frameEnd : 1; // Frame end
|
||||
uint32_t txFifoLevel : 6; // Tx Fifo Level, readOnly
|
||||
uint32_t rxFifoLevel : 6; // Rx Fifo level, readOnly
|
||||
uint32_t cspiBusTimeOut : 1; // Not use
|
||||
}i2sStats_t;
|
||||
|
||||
/** \brief I2S Control */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t i2sMode : 2; // I2S Mode
|
||||
}i2sCtrl_t;
|
||||
|
||||
/** \brief I2S Auto Configure Control */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t autoCgEn : 1; // Auto Configure Enable
|
||||
}i2sAutoCgCtrl_t;
|
||||
|
||||
/**
|
||||
\brief I2S control bits.
|
||||
*/
|
||||
#define I2S_CTRL_TRANSABORT (1UL << 0) // I2S trans abort
|
||||
#define I2S_CTRL_SAMPLE_RATE_SLAVE (1UL << 1) // I2S sample rate setting, used in ec618 slave mode
|
||||
#define I2S_CTRL_SAMPLE_RATE_MASTER (1UL << 2) // I2S sample rate setting, used in ec618 master mode
|
||||
#define I2S_CTRL_SET_TOTAL_NUM (1UL << 3) // Audio source total num
|
||||
#define I2S_CTRL_DATA_FORMAT (1UL << 4) // I2S data format
|
||||
#define I2S_CTRL_SLOT_CTRL (1UL << 5) // I2S slot ctrl
|
||||
#define I2S_CTRL_BCLK_FS_CTRL (1UL << 6) // I2S bclk fs ctrl
|
||||
#define I2S_CTRL_DMA_CTRL (1UL << 7) // I2S dma ctrl
|
||||
#define I2S_CTRL_INT_CTRL (1UL << 8) // I2S int ctrl
|
||||
#define I2S_CTRL_TIMEOUT_CYCLE (1UL << 9) // I2S timeout cycle
|
||||
#define I2S_CTRL_STATUS (1UL << 10) // I2S status
|
||||
#define I2S_CTRL_I2SCTL (1UL << 11) // I2S control
|
||||
#define I2S_CTRL_AUTO_CG_CTRL (1UL << 12) // I2S auto cg ctrl
|
||||
#define I2S_CTRL_INIT (1UL << 13) // I2S init
|
||||
#define I2S_CTRL_START_STOP (1UL << 14) // I2S audio play start/stop ctrl
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BSP_I2S_H */
|
||||
@@ -0,0 +1,147 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2018-, Copyrigths of AirM2M Ltd.
|
||||
* File name: ic.h
|
||||
* Description: EC618 interrupt controller header file
|
||||
* History: Rev1.0 2018-11-15
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _IC_EC618_H
|
||||
#define _IC_EC618_H
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
|
||||
/**
|
||||
\addtogroup xic_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define NUM_APXIC_MODULE (4U) /**< number of XIC module */
|
||||
#define NUM_APXIC0_INT (32U) /**< number of interrupts in XIC0 */
|
||||
#define NUM_APXIC1_INT (32U) /**< number of interrupts in XIC1 */
|
||||
#define NUM_APXIC2_INT (32U) /**< number of interrupts in XIC2 */
|
||||
#define NUM_APXIC3_INT (32U) /**< number of interrupts in XIC3 */
|
||||
|
||||
/** ISR function type define */
|
||||
typedef void ( *ISRFunc_T )(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\fn void IC_PowupInit(void)
|
||||
\brief Initialize the interrupt controller, including HW configuration and ISR initialization,
|
||||
called when POR or wakeup from Hibernate, in which the SRAM contents have been lost.
|
||||
*/
|
||||
void IC_PowupInit(void);
|
||||
/**
|
||||
\fn void IC_Powoff(void)
|
||||
\brief DeInitialize the interrupt controller, including HW configuration and ISR initialization.
|
||||
*/
|
||||
void IC_Powoff(void);
|
||||
/**
|
||||
\fn void XIC_SetVector(IRQn_Type IRQn, ISRFunc_T vector)
|
||||
\brief Sets an XIC interrupt vector in SRAM based interrupt vector table.
|
||||
Use this function to bind the XIC interrupt and application ISR.
|
||||
\param[in] IRQn Interrupt number
|
||||
\param[in] vector Address of interrupt handler function
|
||||
\note The interrupt number must be positive
|
||||
*/
|
||||
void XIC_SetVector(IRQn_Type IRQn, ISRFunc_T vector);
|
||||
|
||||
/**
|
||||
\fn void XIC_EnableIRQ(IRQn_Type IRQn)
|
||||
\brief Enables a device specific interrupt in the XIC interrupt controller.
|
||||
\param[in] IRQn Interrupt number
|
||||
\note The interrupt number must be positive
|
||||
*/
|
||||
void XIC_EnableIRQ(IRQn_Type IRQn);
|
||||
|
||||
/**
|
||||
\fn void XIC_DisableIRQ(IRQn_Type IRQn)
|
||||
\brief Disables a device specific interrupt in the XIC interrupt controller.
|
||||
\param[in] IRQn Interrupt number
|
||||
\note The interrupt number must be positive
|
||||
*/
|
||||
void XIC_DisableIRQ(IRQn_Type IRQn);
|
||||
|
||||
/**
|
||||
\fn void XIC_BackupIRQSetting(uint32_t *mask_array, uint32_t *clrovf_array)
|
||||
|
||||
\brief backup the interrupt mask and ovf setting before sleep
|
||||
\param[out] mask_array mask0, mask1, clrovf0 to store the irq mask and ovf setting
|
||||
\param[out] clrovf_array
|
||||
\note
|
||||
*/
|
||||
|
||||
void XIC_BackupIRQSetting(uint32_t *mask_array, uint32_t *clrovf_array);
|
||||
|
||||
/**
|
||||
\fn void XIC_RestoreIRQSetting(uint32_t *mask_array, uint32_t *clrovf_array)
|
||||
|
||||
\brief restore the interrupt mask and ovf setting after sleep
|
||||
\param[in] mask_array mask0, mask1, clrovf0 is the stored value before sleep
|
||||
\param[out] clrovf_array
|
||||
\note
|
||||
*/
|
||||
void XIC_RestoreIRQSetting(uint32_t *mask_array, uint32_t *clrovf_array);
|
||||
|
||||
/**
|
||||
\fn void XIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
\brief Sets the pending bit of a device specific interrupt in the XIC pending register,
|
||||
mainly used for SW generating interrupt.
|
||||
\param[in] IRQn Interrupt number
|
||||
\note The interrupt number must be positive
|
||||
*/
|
||||
void XIC_SetPendingIRQ(IRQn_Type IRQn);
|
||||
|
||||
/**
|
||||
\fn void XIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
\brief Clears the pending bit of a device specific interrupt in the XIC pending register.
|
||||
\param[in] IRQn Interrupt number
|
||||
\note The interrupt number must be positive
|
||||
*/
|
||||
void XIC_ClearPendingIRQ(IRQn_Type IRQn);
|
||||
|
||||
/**
|
||||
\fn uint32_t XIC_LatchIRQ(XIC_TypeDef* xic)
|
||||
\brief Latch the pending interrupt status to the latch register and read out.
|
||||
\param[in] xic Pointer to XIC instance
|
||||
\return Interrupt status
|
||||
*/
|
||||
uint32_t XIC_LatchIRQ(XIC_TypeDef* xic);
|
||||
|
||||
/**
|
||||
\fn void XIC_SuppressOvfIRQ(IRQn_Type IRQn)
|
||||
\brief Suppress overflow IRQ
|
||||
\param[in] IRQn Interrupt number
|
||||
\note The interrupt number must be positive
|
||||
*/
|
||||
void XIC_SuppressOvfIRQ(IRQn_Type IRQn);
|
||||
|
||||
/**
|
||||
\fn void XIC_ClearAllPendingIRQ(XIC_TypeDef* xic)
|
||||
\brief Clears all pending bits of a XIC interrupt controller.
|
||||
\param[in] xic Pointer to XIC instance
|
||||
*/
|
||||
void XIC_ClearAllPendingIRQ(XIC_TypeDef* xic);
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2020-, Copyrigths of AirM2M Ltd.
|
||||
* File name: kpc_ec618.h
|
||||
* Description: EC618 kpc driver header file
|
||||
* History: Rev1.0 2021-07-23
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _KPC_EC618_H
|
||||
#define _KPC_EC618_H
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
|
||||
/**
|
||||
\addtogroup kpc_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/** \brief List of debounce clock divider ratio */
|
||||
typedef enum
|
||||
{
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_2 = 1U, /**< KPC debounce clock divider ratio select as 2 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_4 = 2U, /**< KPC debounce clock divider ratio select as 4 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_8 = 3U, /**< KPC debounce clock divider ratio select as 8 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_16 = 4U, /**< KPC debounce clock divider ratio select as 16 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_32 = 5U, /**< KPC debounce clock divider ratio select as 32 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_64 = 6U, /**< KPC debounce clock divider ratio select as 64 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_128 = 7U, /**< KPC debounce clock divider ratio select as 128 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_256 = 8U, /**< KPC debounce clock divider ratio select as 256 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_512 = 9U, /**< KPC debounce clock divider ratio select as 512 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_1024 = 10U, /**< KPC debounce clock divider ratio select as 1024 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_2048 = 11U, /**< KPC debounce clock divider ratio select as 2048 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_4096 = 12U, /**< KPC debounce clock divider ratio select as 4096 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_8192 = 13U, /**< KPC debounce clock divider ratio select as 8192 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_16384 = 14U, /**< KPC debounce clock divider ratio select as 16384 */
|
||||
KPC_DEBOUNCE_CLK_DIV_RATIO_32768 = 15U, /**< KPC debounce clock divider ratio select as 32768 */
|
||||
} KpcDebounceClkDivRatio_t;
|
||||
|
||||
/** \brief List of debounce width */
|
||||
typedef enum
|
||||
{
|
||||
KPC_DEBOUNCE_WIDTH_5_CYCLES = 5U, /**< KPC debounce width is 5 Cycles of debounce clock */
|
||||
KPC_DEBOUNCE_WIDTH_6_CYCLES = 6U, /**< KPC debounce width is 6 Cycles of debounce clock */
|
||||
KPC_DEBOUNCE_WIDTH_7_CYCLES = 7U, /**< KPC debounce width is 7 Cycles of debounce clock */
|
||||
KPC_DEBOUNCE_WIDTH_8_CYCLES = 8U, /**< KPC debounce width is 8 Cycles of debounce clock */
|
||||
KPC_DEBOUNCE_WIDTH_9_CYCLES = 9U, /**< KPC debounce width is 9 Cycles of debounce clock */
|
||||
KPC_DEBOUNCE_WIDTH_10_CYCLES = 10U, /**< KPC debounce width is 10 Cycles of debounce clock */
|
||||
KPC_DEBOUNCE_WIDTH_11_CYCLES = 11U, /**< KPC debounce width is 11 Cycles of debounce clock */
|
||||
KPC_DEBOUNCE_WIDTH_12_CYCLES = 12U, /**< KPC debounce width is 12 Cycles of debounce clock */
|
||||
KPC_DEBOUNCE_WIDTH_13_CYCLES = 13U, /**< KPC debounce width is 13 Cycles of debounce clock */
|
||||
KPC_DEBOUNCE_WIDTH_14_CYCLES = 14U, /**< KPC debounce width is 14 Cycles of debounce clock */
|
||||
KPC_DEBOUNCE_WIDTH_15_CYCLES = 15U, /**< KPC debounce width is 15 Cycles of debounce clock */
|
||||
} KpcDebounceWidth_t;
|
||||
|
||||
/** \brief List of key scan polarity */
|
||||
typedef enum
|
||||
{
|
||||
KPC_SCAN_POLARITY_0 = 0U, /**< KPC outputs low level scan waveform for active row while other valid rows is high */
|
||||
KPC_SCAN_POLARITY_1 = 1U, /**< KPC outputs high level scan waveform for active row while other valid rows is low */
|
||||
} KpcScanPolarity_t;
|
||||
|
||||
/** \brief List of key scan divider ratio */
|
||||
typedef enum
|
||||
{
|
||||
KPC_SCAN_DIV_RATIO_2 = 1U, /**< KPC scan frequence divider ratio set as 2 */
|
||||
KPC_SCAN_DIV_RATIO_4 = 2U, /**< KPC scan frequence divider ratio set as 4 */
|
||||
KPC_SCAN_DIV_RATIO_8 = 3U, /**< KPC scan frequence divider ratio set as 8 */
|
||||
KPC_SCAN_DIV_RATIO_16 = 4U, /**< KPC scan frequence divider ratio set as 16 */
|
||||
KPC_SCAN_DIV_RATIO_32 = 5U, /**< KPC scan frequence divider ratio set as 32 */
|
||||
KPC_SCAN_DIV_RATIO_64 = 6U, /**< KPC scan frequence divider ratio set as 64 */
|
||||
KPC_SCAN_DIV_RATIO_128 = 7U, /**< KPC scan frequence divider ratio set as 128 */
|
||||
} KpcScanDivRatio_t;
|
||||
|
||||
/** \brief List of debounce width */
|
||||
typedef enum
|
||||
{
|
||||
KPC_ROW_0 = 1U, /**< KPC row0 enable mask */
|
||||
KPC_ROW_1 = 2U, /**< KPC row1 enable mask */
|
||||
KPC_ROW_2 = 4U, /**< KPC row2 enable mask */
|
||||
KPC_ROW_3 = 8U, /**< KPC row3 enable mask */
|
||||
KPC_ROW_4 = 16U, /**< KPC row4 enable mask */
|
||||
KPC_ROW_ALL = 0x1FU /**< KPC all rows enable mask */
|
||||
} KpcRow_t;
|
||||
|
||||
/** \brief List of debounce width */
|
||||
typedef enum
|
||||
{
|
||||
KPC_COLUMN_0 = 1U, /**< KPC column0 enable mask */
|
||||
KPC_COLUMN_1 = 2U, /**< KPC column1 enable mask */
|
||||
KPC_COLUMN_2 = 4U, /**< KPC column2 enable mask */
|
||||
KPC_COLUMN_3 = 8U, /**< KPC column3 enable mask */
|
||||
KPC_COLUMN_4 = 16U, /**< KPC column4 enable mask */
|
||||
KPC_COLUMN_ALL = 0x1FU /**< KPC all columns enable mask */
|
||||
} KpcColumn_t;
|
||||
|
||||
/** \brief KPC debounce configuration, decounce exits when consecutive debounceWidth scans give the same result */
|
||||
typedef struct
|
||||
{
|
||||
KpcDebounceClkDivRatio_t debounceClkDivRatio; /**< debounce clock divider ratio */
|
||||
KpcDebounceWidth_t debounceWidth; /**< debounce width */
|
||||
} KpcDebounceConfig_t;
|
||||
|
||||
/** \brief KPC auto repeat configuration */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t enable; /**< enable auto repeat or not */
|
||||
uint8_t delay; /**< auto repeat delay cycles of scan period, if scan period is 50ms and this value is set as 10,
|
||||
then autorepeat event will start to be reported 500ms later after key press is detected and key press keeps hold */
|
||||
|
||||
uint8_t period; /**< auto repeat report interval of scan period, if scan period is 50ms and this value is set as 2,
|
||||
then autorepeat event will be reported in interval of 100ms until key is released */
|
||||
} KpcAutoRepeatConfig_t;
|
||||
|
||||
/** \brief KPC configuration structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t validRowMask; /**< Bitmap of valid rows */
|
||||
uint8_t validColumnMask; /**< Bitmap of valid columns */
|
||||
KpcDebounceConfig_t debounceConfig; /**< KPC debounce configuration */
|
||||
KpcAutoRepeatConfig_t autoRepeat; /**< KPC auto repeat configuration */
|
||||
KpcScanPolarity_t scanPolarity; /**< KPC scan polarity */
|
||||
KpcScanDivRatio_t scanDivRatio; /**< KPC scan divider ratio */
|
||||
} KpcConfig_t;
|
||||
|
||||
/** \brief List of kpc report key value */
|
||||
typedef enum
|
||||
{
|
||||
KPC_REPORT_KEY_RELEASE = 0U, /**< Key is released */
|
||||
KPC_REPORT_KEY_PRESS = 1U, /**< Key is pressed */
|
||||
KPC_REPORT_KEY_REPEAT = 2U, /**< Key holds pressed */
|
||||
} KpcReportValue_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t value : 2; /**< Key value */
|
||||
uint8_t column : 3; /**< Key column */
|
||||
uint8_t row : 3; /**< Key row */
|
||||
} KpcReportEvent_t;
|
||||
|
||||
/**
|
||||
\brief Defines callback function prototype.
|
||||
Callback function will be called in KPC interrupt service routine
|
||||
\param report key event value
|
||||
*/
|
||||
|
||||
typedef void (*kpc_callback_t)(KpcReportEvent_t event);
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \name KPC Configuration */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void KPC_getDefaultConfig(KpcConfig_t *config)
|
||||
\brief Gets the KPC default configuartion.
|
||||
This function sets the configuration structure to default values as below:
|
||||
\code
|
||||
config->debounceConfig.debounceClkDivRatio = KPC_DEBOUNCE_CLK_DIV_RATIO_16384;
|
||||
config->debounceConfig.debounceWidth = KPC_DEBOUNCE_WIDTH_7_CYCLES;
|
||||
|
||||
config->validRowMask = KPC_ROW_ALL;
|
||||
config->validColumnMask = KPC_COLUMN_ALL;
|
||||
|
||||
config->scanPolarity = KPC_SCAN_POLARITY_0;
|
||||
config->scanDivRatio = KPC_SCAN_DIV_RATIO_16;
|
||||
|
||||
config->autoRepeat.enable = 1;
|
||||
config->autoRepeat.delay = 10;
|
||||
config->autoRepeat.period = 1;
|
||||
|
||||
\endcode
|
||||
|
||||
\details debouncer and scan setting explaination:
|
||||
KPC input clock is 26M, if debouncer divider is set as KPC_DEBOUNCE_CLK_DIV_RATIO_16384, then one cycle is 16384/26M = 630us,
|
||||
debouncer depth set as 7, means we can filter out 630*7us(4.4ms) jitter
|
||||
|
||||
scan clock is sourced from debouncer clock, which means if scan frequency divider ratio is set as KPC_SCAN_DIV_RATIO_16 and
|
||||
when 5 rows are enabled, the scan frequency is 26M/16384/16/5 = 20HZ, each row scan signal width will be 1/20/5 = 10ms
|
||||
|
||||
\param[in] config Pointer to KPC configuration structure
|
||||
*/
|
||||
void KPC_getDefaultConfig(KpcConfig_t *config);
|
||||
|
||||
/**
|
||||
\fn void KPC_init(const KpcConfig_t *config, kpc_callback_t callback)
|
||||
\brief Initialize KPC
|
||||
\param[in] config Pointer to KPC configuration
|
||||
\param[in] callback Function to be called when KPC interrupt occurs
|
||||
\return ARM_DRIVER_OK if the setting is successful
|
||||
ARM_DRIVER_ERROR_PARAMETER on parameter check failure
|
||||
*/
|
||||
int32_t KPC_init(const KpcConfig_t *config, kpc_callback_t callback);
|
||||
|
||||
/**
|
||||
\fn void KPC_deInit(void)
|
||||
\brief Deinitialize KPC
|
||||
*/
|
||||
void KPC_deInit(void);
|
||||
|
||||
/**
|
||||
\fn void KPC_startScan(void)
|
||||
\brief Starts KPC scan
|
||||
*/
|
||||
void KPC_startScan(void);
|
||||
|
||||
/**
|
||||
\fn void KPC_stopScan(void)
|
||||
\brief Stops KPC scan
|
||||
*/
|
||||
void KPC_stopScan(void);
|
||||
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _KPC_EC618_H */
|
||||
@@ -0,0 +1,143 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2020-, Copyrigths of AirM2M Ltd.
|
||||
* File name: oneWire.h
|
||||
* Description: EC618 one wire bus driver file
|
||||
* History: Rev1.0 2020-12-17
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _ONEWIRE_EC618_H
|
||||
#define _ONEWIRE_EC618_H
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
|
||||
/**
|
||||
\addtogroup onewire_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/** \brief OW Mode Select */
|
||||
typedef enum
|
||||
{
|
||||
STANDARD = 0, /**< Stand speed of onewire */
|
||||
OVERDRIVE /**< High speed of onewire */
|
||||
}OwModeSel_e;
|
||||
|
||||
/** \brief OW Status */
|
||||
typedef enum
|
||||
{
|
||||
OW_IDLE = 0x0,
|
||||
OW_RESET_SUCCESS = 0x2,
|
||||
OW_RESETPD_SUCCESS = 0x4,
|
||||
OW_READ_SUCCESS = 0x8,
|
||||
OW_WRITE_SUCCESS = 0x10,
|
||||
OW_TIMEOUT = 0x20,
|
||||
}OwStats_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *dataWrite;
|
||||
uint8_t *dataRead;
|
||||
uint8_t mode;
|
||||
}OwRes_t;
|
||||
|
||||
#define OWDRV_OK (0)
|
||||
#define OWDRV_RESET_ERR (-1)
|
||||
#define OWDRV_RESETPD_ERR (-2)
|
||||
#define OWDRV_READ_ERR (-3)
|
||||
#define OWDRV_WRITE_ERR (-4)
|
||||
#define OWDRV_TIMEOUT (-5)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\fn void owInit()
|
||||
\brief Initialize ow
|
||||
*/
|
||||
void owInit(void);
|
||||
|
||||
/**
|
||||
\fn void owDeInit()
|
||||
\brief DeInitialize ow
|
||||
*/
|
||||
void owDeInit(void);
|
||||
|
||||
|
||||
/**
|
||||
\fn void owSetMode(OwModeSel_e mode)
|
||||
\brief ow set mode
|
||||
\param[in] mode ow mode
|
||||
*/
|
||||
void owSetMode(OwModeSel_e mode);
|
||||
|
||||
/**
|
||||
\fn int32_t owReset()
|
||||
\brief ow reset
|
||||
\return ow reset status
|
||||
*/
|
||||
int32_t owReset(void);
|
||||
|
||||
/**
|
||||
\fn int32_t owResetPd()
|
||||
\brief ow reset for presence detect
|
||||
\return ow reset presence detect status
|
||||
*/
|
||||
int32_t owResetPd(void);
|
||||
|
||||
/**
|
||||
\fn int32_t owWriteBit(uint8_t data)
|
||||
\brief write 1bit data to ow
|
||||
\param[in] data data to write to ow, LSB is effective
|
||||
\return ow write 1 bit status
|
||||
*/
|
||||
int32_t owWriteBit(uint8_t data);
|
||||
|
||||
/**
|
||||
\fn int32_t owWriteByte(uint8_t data)
|
||||
\brief write 1byte data to ow
|
||||
\param[in] data 1 byte data to write to ow
|
||||
\return ow write 1 byte status
|
||||
*/
|
||||
int32_t owWriteByte(uint8_t data);
|
||||
|
||||
/**
|
||||
\fn int32_t owReadBit()
|
||||
\brief read 1bit data
|
||||
\return ow read 1 bit status
|
||||
*/
|
||||
int32_t owReadBit(uint8_t * dataRead);
|
||||
|
||||
/**
|
||||
\fn int32_t owReadByte()
|
||||
\brief ow read 1 byte
|
||||
\return ow read 1 byte status
|
||||
*/
|
||||
int32_t owReadByte(uint8_t * dataRead);
|
||||
|
||||
/**
|
||||
\fn int32_t owTouchByte(uint8_t data)
|
||||
\brief read and write ow at the same time
|
||||
\return ow touch 1 byte status
|
||||
*/
|
||||
int32_t owTouchByte(uint8_t data);
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,173 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2017-, Copyrigths of AirM2M Ltd.
|
||||
* File name: pad.h
|
||||
* Description: EC618 pad driver header file
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _PAD_EC618_H_
|
||||
#define _PAD_EC618_H_
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
|
||||
|
||||
/**
|
||||
\addtogroup pad_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/** \brief PAD pin mux selection */
|
||||
typedef enum
|
||||
{
|
||||
PAD_MUX_ALT0 = 0U, /**< Chip-specific */
|
||||
PAD_MUX_ALT1 = 1U, /**< Chip-specific */
|
||||
PAD_MUX_ALT2 = 2U, /**< Chip-specific */
|
||||
PAD_MUX_ALT3 = 3U, /**< Chip-specific */
|
||||
PAD_MUX_ALT4 = 4U, /**< Chip-specific */
|
||||
PAD_MUX_ALT5 = 5U, /**< Chip-specific */
|
||||
PAD_MUX_ALT6 = 6U, /**< Chip-specific */
|
||||
PAD_MUX_ALT7 = 7U, /**< Chip-specific */
|
||||
} PadMux_e;
|
||||
|
||||
|
||||
/** \brief Internal pull-up resistor configuration */
|
||||
typedef enum
|
||||
{
|
||||
PAD_PULL_UP_DISABLE = 0U, /**< Internal pull-up resistor is disabled */
|
||||
PAD_PULL_UP_ENABLE = 1U, /**< Internal pull-up resistor is enabled */
|
||||
} PadPullUp_e;
|
||||
|
||||
/** \brief Internal pull-down resistor configuration */
|
||||
typedef enum
|
||||
{
|
||||
PAD_PULL_DOWN_DISABLE = 0U, /**< Internal pull-down resistor is disabled */
|
||||
PAD_PULL_DOWN_ENABLE = 1U, /**< Internal pull-down resistor is enabled */
|
||||
} PadPullDown_e;
|
||||
|
||||
/** \brief Pull feature selection */
|
||||
typedef enum
|
||||
{
|
||||
PAD_PULL_AUTO = 0U, /**< Pull up/down is controlled by muxed alt function */
|
||||
PAD_PULL_INTERNAL = 1U, /**< Use internal pull-up/down resistor */
|
||||
} PadPullSel_e;
|
||||
|
||||
/** \brief Input buffer enable/disable */
|
||||
typedef enum
|
||||
{
|
||||
PAD_INPUT_BUFFER_DISABLE = 0U, /**< Input Buffer is disabled */
|
||||
PAD_INPUT_BUFFER_ENABLE = 1U, /**< Input Buffer is enabled */
|
||||
} PadInputBuffer_e;
|
||||
|
||||
/** \brief Configures pull feature */
|
||||
typedef enum
|
||||
{
|
||||
PAD_INTERNAL_PULL_UP = 0U, /**< select internal pull up */
|
||||
PAD_INTERNAL_PULL_DOWN = 1U, /**< select internal pull down */
|
||||
PAD_AUTO_PULL = 2U, /**< Pull up/down is controlled by muxed alt function */
|
||||
} PadPullConfig_e;
|
||||
|
||||
/** \brief PAD configuration structure */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t : 4;
|
||||
uint32_t mux : 3; /**< Pad mux configuration */
|
||||
uint32_t : 1;
|
||||
uint32_t pullUpEnable : 1; /**< Enable pull-up */
|
||||
uint32_t pullDownEnable : 1; /**< Enable pull-down */
|
||||
uint32_t pullSelect : 1; /**< Pull select, external or internal control */
|
||||
uint32_t : 2;
|
||||
uint32_t inputBufferEnable : 1; /**< Enable/disable input buffer */
|
||||
uint32_t : 18;
|
||||
} PadConfig_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \name PAD Driver Initialization */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void PAD_driverInit(void);
|
||||
\brief Intialize PAD driver internal data, must be called before any other APIs
|
||||
*/
|
||||
void PAD_driverInit(void);
|
||||
|
||||
/**
|
||||
\fn void PAD_driverInit(void);
|
||||
\brief De-Intialize PAD driver, disable PAD clock and perform some clearups
|
||||
*/
|
||||
void PAD_driverDeInit(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name Configuration */
|
||||
/* \{ */
|
||||
|
||||
/**
|
||||
\fn void PAD_getDefaultConfig(PadConfig_t *config)
|
||||
\brief Gets the PAD default configuartion
|
||||
This function sets the configuration structure to default values as below:
|
||||
\code
|
||||
config->mux = PAD_MUX_ALT0;
|
||||
config->inputBufferEnable = PAD_INPUT_BUFFER_DISABLE;
|
||||
config->pullSelect = PAD_PULL_AUTO;
|
||||
config->pullUpEnable = PAD_PULL_UP_DISABLE;
|
||||
config->pullDownEnable = PAD_PULL_DOWN_DISABLE;
|
||||
\endcode
|
||||
\param config Pointer to PAD configuration structure
|
||||
*/
|
||||
void PAD_getDefaultConfig(PadConfig_t *config);
|
||||
|
||||
/**
|
||||
\fn void PAD_setPinConfig(uint32_t pin, const PadConfig_t *config)
|
||||
\brief Sets the pad PCR register
|
||||
\param pin PAD pin number
|
||||
\param config Pointer to PAD configuration structure
|
||||
*/
|
||||
void PAD_setPinConfig(uint32_t paddr, const PadConfig_t *config);
|
||||
|
||||
/**
|
||||
\fn void PAD_setPinMux(uint32_t pin, PadMux_e mux)
|
||||
\brief Configures pin mux
|
||||
\param pin PAD pin number
|
||||
\param mux pin signal source selection
|
||||
*/
|
||||
void PAD_setPinMux(uint32_t paddr, PadMux_e mux);
|
||||
|
||||
/**
|
||||
\fn void PAD_enablePinInputBuffer(uint32_t pin, bool enable)
|
||||
\brief Enable/disable pin's input buffer
|
||||
\param pin PAD pin number
|
||||
\param enable true to enable, false to disable
|
||||
*/
|
||||
void PAD_enablePinInputBuffer(uint32_t paddr, bool enable);
|
||||
|
||||
/**
|
||||
\fn void PAD_setPinPullConfig(uint32_t pin, PadPullConfig_e config)
|
||||
\brief Configures pin's pull feature
|
||||
\param pin PAD pin number
|
||||
\param config PAD pin pull configuration
|
||||
*/
|
||||
void PAD_setPinPullConfig(uint32_t paddr, PadPullConfig_e config);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PAD_EC618_H_ */
|
||||
@@ -0,0 +1,167 @@
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
*(C) Copyright 2018 AirM2M International Ltd.
|
||||
|
||||
* All Rights Reserved
|
||||
|
||||
******************************************************************************
|
||||
* Filename: pwrkey.h
|
||||
*
|
||||
* Description: header of pwrkey.c, power on/off and software debounce
|
||||
*
|
||||
* History: 2021.04.29 initiated by Zhao Weiqi
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef PWR_KEY_H
|
||||
#define PWR_KEY_H
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* INCLUDES *
|
||||
*----------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* MACROS *
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define KEY_BUF_SIZE 8
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* DATA TYPE DEFINITION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
int16_t longPressTimeout;
|
||||
int16_t repeatTimeout;
|
||||
int16_t pwrOffTimeout;
|
||||
}pwrKeyDly_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PWRKEY_PWRON_MODE = 0,
|
||||
PWRKEY_WAKEUP_LOWACTIVE_MODE,
|
||||
PWRKEY_WAKEUP_HIGHACTIVE_MODE,
|
||||
PWRKEY_UNKNOW_MODE,
|
||||
}pwrKeyWorkMode;
|
||||
|
||||
/*
|
||||
typedef enum
|
||||
{
|
||||
PWRKEY_SYSTEM_ON = 0,
|
||||
PWRKEY_SYSTEM_OFF,
|
||||
}pwrKeySysStatus;
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PWRKEY_RELEASE = 0,
|
||||
PWRKEY_PRESS,
|
||||
PWRKEY_LONGPRESS,
|
||||
PWRKEY_REPEAT,
|
||||
}pwrKeyPressStatus;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool negEdgeEn;
|
||||
bool posEdgeEn;
|
||||
}pwrKeyWakeupCfg_t;
|
||||
|
||||
|
||||
typedef void(* pwrKeyCallback_t)(pwrKeyPressStatus status);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pwrKeyWorkMode workMode;
|
||||
pwrKeyWakeupCfg_t wakeupCfg;
|
||||
pwrKeyDly_t delayCfg;
|
||||
pwrKeyCallback_t pwrKeyCallback;
|
||||
pwrKeyPressStatus curStatus;
|
||||
pwrKeyPressStatus keyBuf[KEY_BUF_SIZE];
|
||||
uint8_t bufOffset;
|
||||
}pwrKeyInfo_t;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* GLOBAL FUNCTIONS DECLEARATION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief pwrKeyPushKey
|
||||
* @details push a key to power key buffer
|
||||
*
|
||||
* @param pwrKeyInfo
|
||||
@param status
|
||||
|
||||
* @return null
|
||||
*/
|
||||
void pwrKeyPushKey(pwrKeyInfo_t *pwrKeyInfo, pwrKeyPressStatus status);
|
||||
/**
|
||||
* @brief pwrKeyPopKey
|
||||
* @details pop a key from power key buffer and return the key status
|
||||
*
|
||||
* @param pwrKeyInfo
|
||||
* @return null
|
||||
*/
|
||||
pwrKeyPressStatus pwrKeyPopKey(pwrKeyInfo_t *pwrKeyInfo);
|
||||
/**
|
||||
* @brief pwrKeyStartPowerOff
|
||||
* @details force to enter power off status
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
void pwrKeyStartPowerOff(void);
|
||||
/**
|
||||
* @brief pwrkeyPwrOnDebounce
|
||||
* @details power on debounce flow according to the configures
|
||||
*
|
||||
* @param tmpDelay in ms
|
||||
* @return null
|
||||
*/
|
||||
void pwrkeyPwrOnDebounce(int16_t tmpDelay);
|
||||
/**
|
||||
* @brief pwrKeyHwInit
|
||||
* @details power key hardware init
|
||||
*
|
||||
* @param pullUpEn
|
||||
* @return null
|
||||
*/
|
||||
void pwrKeyHwInit(bool pullUpEn);
|
||||
/**
|
||||
* @brief pwrKeyHwDeinit
|
||||
* @details power key hardware deinit
|
||||
*
|
||||
* @param pullUpEn
|
||||
* @return null
|
||||
*/
|
||||
void pwrKeyHwDeinit(bool pullUpEn);
|
||||
/**
|
||||
* @brief pwrKeyGetPinLevel
|
||||
* @details get power key pin value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
bool pwrKeyGetPinLevel(void);
|
||||
/**
|
||||
* @brief pwrKeyGetPwrKeyMode
|
||||
* @details get power key mode in bootloader
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
pwrKeyWorkMode pwrKeyGetPwrKeyMode(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
#ifndef __RNG_EC618_H__
|
||||
#define __RNG_EC618_H__
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
#include "clock.h"
|
||||
#include "ic.h"
|
||||
#include "string.h"
|
||||
|
||||
#define RNG_DEBUG_USING_PRINTF 0
|
||||
#define RNG_DEBUG_USING_UNILOG 0
|
||||
|
||||
#define RNG_IRQ_MODE 0
|
||||
|
||||
#define RNG_MAX_POLL_DELAY_US (8000*2)
|
||||
#define RNG_MAX_TRY_NUM 10
|
||||
#define RNG ((RngDesc_t*)MP_TRNG_BASE_ADDR)
|
||||
#define RNG_R_MAGIC 0xf45a97d4
|
||||
|
||||
|
||||
|
||||
#if (RNG_DEBUG_USING_UNILOG == 1)
|
||||
#include DEBUG_LOG_HEADER_FILE
|
||||
#endif
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
#include "slpman.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if RNG_DEBUG_USING_PRINTF
|
||||
#define RNGDEBUG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define RNGDEBUG(...)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IM uint32_t rsvd1[64];
|
||||
__IO uint32_t imrReg; //Interrupt mask reg ,0x100
|
||||
__IO uint32_t isrReg; //Interrupt status reg
|
||||
__OM uint32_t icrReg; //Interrupt clear reg
|
||||
__IO uint32_t cfgReg; //Configuration reg
|
||||
__IM uint32_t validReg; //Valid reg
|
||||
__IM uint32_t dataReg[6];
|
||||
__IO uint32_t srcEnableReg; //Random source enable reg
|
||||
__IO uint32_t sampleCntReg; //Sample Count reg
|
||||
__IO uint32_t autoCorrReg; //Auto correlation reg
|
||||
__IM uint32_t debugCtrlReg; //Debug Control reg
|
||||
__IM uint32_t rsvd2;
|
||||
__OM uint32_t swRstReg; //Reset reg
|
||||
__IM uint32_t rsvd3[29];
|
||||
__IM uint32_t busyReg; //Busy reg
|
||||
__OM uint32_t rstBitsCntReg; //Reset bits counter reg
|
||||
__IM uint32_t rsvd4[8];
|
||||
__IM uint32_t bistCntReg[3]; //BIST Counter reg
|
||||
__IO uint32_t rsvd5[5];
|
||||
}RngDesc_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RNG_SRC_SHORT_TEST_TYPE = 0,
|
||||
RNG_SRC_SHORT_TYPE = 1,
|
||||
RNG_SRC_LONG_TYPE = 2,
|
||||
RNG_SRC_LONGEST_TYPE = 3,
|
||||
}RngSrcSelType_e;
|
||||
|
||||
#define RNGDRV_OK (0)
|
||||
#define RNGDRV_IntErr (-1)
|
||||
#define RNGDRV_TimeOutErr (-2)
|
||||
|
||||
typedef enum{
|
||||
RNG_EHR_VALID_TYPE = 1,
|
||||
RNG_AUTO_CORR_ERR_TYPE = 2,
|
||||
RNG_CRNGT_ERR_TYPE = 4,
|
||||
RNG_VN_ERR_TYPE = 8
|
||||
}RngIntStatType_e;
|
||||
|
||||
/**
|
||||
\brief When rand is null, means generate random number to efuse. If rand isn't null, means generate to this parameter.
|
||||
\param[out] rand Memory address to receive generated random number.
|
||||
\return status
|
||||
*/
|
||||
int32_t rngGenRandom(uint8_t rand[24]);
|
||||
#endif
|
||||
@@ -0,0 +1,543 @@
|
||||
#ifndef __SCT_REG_H__
|
||||
#define __SCT_REG_H__
|
||||
|
||||
/******************************************************************************
|
||||
******************************************************************************
|
||||
Copy right: 2017-, Copyrigths of AirM2M Ltd.
|
||||
File name: sctreg.h
|
||||
Description: SCT register, Security Top is a HW use to do:
|
||||
* 1) cipher & integrity check
|
||||
* 2) AES/SHA
|
||||
* 3) PPP escape & CRC
|
||||
* 4) USB TX
|
||||
History: 2020/12/04 Originated by Jason
|
||||
******************************************************************************
|
||||
******************************************************************************/
|
||||
#include "ec618.h"
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
#pragma anon_unions
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
******************************************************************************
|
||||
* SCT control registers
|
||||
******************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Cipher 0x4005-0000~0x4005-FFFF (64KB)
|
||||
*/
|
||||
#define SCT_REG_ADDR 0x40050000
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* SCT enable/disable register
|
||||
******************************************************************************/
|
||||
|
||||
#define SCT_EN_CTRL_REG ((__IO UINT32 *)SCT_REG_ADDR)
|
||||
|
||||
|
||||
/*
|
||||
* __IO UINT32 SCTEN;
|
||||
* Bit WIDTH DESP
|
||||
* 0 1 0 - SCT disable (reset value)
|
||||
* 1- SCT enable
|
||||
* 1:31 31 RSVD
|
||||
*/
|
||||
#define ENABLE_SCT() ((*(SCT_EN_CTRL_REG)) = 1)
|
||||
#define DISABLE_SCT() ((*(SCT_EN_CTRL_REG)) = 0)
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
******************************************************************************
|
||||
* SCT RNDIS/PPP config register
|
||||
******************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* SctRndisCrcCfgReg RNDIS_CRC_CFG
|
||||
* Bit WIDTH DESP
|
||||
* 0 1 rndis_crc_in_bit_swap,
|
||||
* 0 - CRC calc from bit: inByte[0]
|
||||
* 1 - CRC calc from bit: inByte[7] (reset value)
|
||||
* 1 1 rndis_crc_comple_out
|
||||
* 0 - CRC out bit not comple
|
||||
* 1 - CRC out bit comple (reset value)
|
||||
* 2 1 rndis_crc_out_bit_swap
|
||||
* 0 - CRC out bit not swap
|
||||
* 1 - CRC out bit swap (reset value)
|
||||
* 3:6 4 rndis_crc_comple_in_num, how many input bytes need to be compled
|
||||
*
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
UINT32 crcInBitSwap : 1;
|
||||
UINT32 crcCompleOut : 1;
|
||||
UINT32 crcOutBitSwap : 1;
|
||||
UINT32 crcCompleInNum : 4;
|
||||
UINT32 : 25;
|
||||
};
|
||||
|
||||
UINT32 value32;
|
||||
}SctRndisCrcCfgReg;
|
||||
|
||||
|
||||
/*
|
||||
* SctPPPCrcInitReg PPP_CRC_INIT
|
||||
* Bit WIDTH DESP
|
||||
* 0:15 16 PPP CRC init value, reset value: 0xFFFF
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
UINT32 crcInitValue : 16;
|
||||
UINT32 : 16;
|
||||
};
|
||||
|
||||
UINT32 value32;
|
||||
}SctPPPCrcInitReg;
|
||||
|
||||
|
||||
/*
|
||||
* SctPPPCrcCfgReg PPP_CRC_CFG
|
||||
* Bit WIDTH DESP
|
||||
* 0 1 ppp_crc_in_bit_swap
|
||||
* 0 - CRC calc from bit: inByte[0], (reset value)
|
||||
* 1 - CRC calc from bit: inByte[7]
|
||||
* 1 1 ppp_crc_comple_out
|
||||
* 0 - CRC out bit not comple
|
||||
* 1 - CRC out bit comple, (reset value)
|
||||
* 2 1 ppp_crc_out_bit_swap
|
||||
* 0 - CRC out bit not swap
|
||||
* 1 - CRC out bit swap (reset value)
|
||||
*
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
UINT32 crcInBitSwap : 1;
|
||||
UINT32 crcCompleOut : 1;
|
||||
UINT32 crcOutBitSwap : 1;
|
||||
UINT32 : 29;
|
||||
};
|
||||
|
||||
UINT32 value32;
|
||||
}SctPPPCrcCfgReg;
|
||||
|
||||
/*
|
||||
* PPP escape/deescape bitmap table
|
||||
*/
|
||||
#define SCT_PPP_ESCP_BITMAP_WORD_NUM 8
|
||||
#define SCT_PPP_DE_ESCP_BITMAP_WORD_NUM 8
|
||||
|
||||
|
||||
/*
|
||||
* SCT RNDIS PPP config register struct
|
||||
*/
|
||||
typedef struct SctRndisPPPCfgReg_Tag
|
||||
{
|
||||
__IO UINT32 RNDIS_CRC_INIT; /* RNDIS (802.3) CRC init value, reset value: 0, offset: 0x04 */
|
||||
__IO SctRndisCrcCfgReg RNDIS_CRC_CFG; /* RNDIS (802.3) CRC config. offset: 0x08 */
|
||||
__IO SctPPPCrcInitReg PPP_CRC_INIT; /* PPP CRC init value, reset value: 0xFFFF, offset: 0x0C */
|
||||
__IO SctPPPCrcCfgReg PPP_CRC_CFG; /* PPP CRC config, offset: 0x10 */
|
||||
|
||||
__IO UINT32 PPP_ESCP_BITMAP[SCT_PPP_ESCP_BITMAP_WORD_NUM]; /* PPP escape bitmap, offset: 0x14 */
|
||||
__IO UINT32 PPP_DE_ESCP_BITMAP[SCT_PPP_DE_ESCP_BITMAP_WORD_NUM];/* PPP de-escape bitmap, offset: 0x34 */
|
||||
}SctRndisPPPCfgReg;
|
||||
|
||||
/*
|
||||
* SCT RNDIS PPP config register start address
|
||||
*/
|
||||
#define SCT_RNDIS_PPP_CTRL_REG_ADDR (SCT_REG_ADDR + 0x04)
|
||||
|
||||
/*
|
||||
* SCT RNDIS PPP register pointer
|
||||
*/
|
||||
#define SCT_RNDIS_PPP_CFG_REG ((SctRndisPPPCfgReg *)SCT_RNDIS_PPP_CTRL_REG_ADDR)
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
******************************************************************************
|
||||
* SCT (cipher/integrity) common config register
|
||||
******************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* SctCommCfgWord0 COMM_CFG0
|
||||
* Bit WIDTH DESP
|
||||
* 0 1 sct_cfg_acg_en_rmi_acg
|
||||
* 0 - not enable auto gate, (reset value)
|
||||
* 1 - enable auto gate
|
||||
* 1 1 sct_cfg_acg_en_ahb_acg
|
||||
* 0 - not enable auto gate, (reset value)
|
||||
* 1 - enable auto gate
|
||||
* 16 1 sct_cfg_unilog_SCT_ChainStart
|
||||
* 0 - no unilog output, (reset value)
|
||||
* 1 - unilog output
|
||||
* 17 1 sct_cfg_unilog_SCT_Descriptor_done
|
||||
* 0 - no unilog output, (reset value)
|
||||
* 1 - unilog output
|
||||
* 18 1 sct_cfg_unilog_SCT_ChainEnd
|
||||
* 0 - no unilog output, (reset value)
|
||||
* 1 - unilog output
|
||||
* 19 1 sct_cfg_unilog_error_int
|
||||
* 0 - no unilog output, (reset value)
|
||||
* 1 - unilog output
|
||||
* 20 1 sct_usb_lb_ind, USB Tx big/Little endian output
|
||||
* 0 - little endian, (reset value)
|
||||
* 1 - big endian
|
||||
* 24:31 8 sct_cfg_high_addr_offst
|
||||
*
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
UINT32 rmiAcg : 1;
|
||||
UINT32 ahbAcg : 1;
|
||||
UINT32 : 14;
|
||||
UINT32 chainStartUnilog : 1;
|
||||
UINT32 descDoneUnilog : 1;
|
||||
UINT32 chainEndUnilog : 1;
|
||||
UINT32 errorIntUnilog : 1;
|
||||
UINT32 usbLBEndianInd : 1;
|
||||
UINT32 : 3;
|
||||
UINT32 memHighAddrOffset : 8;
|
||||
};
|
||||
|
||||
UINT32 value32;
|
||||
}SctCommCfgWord0;
|
||||
|
||||
|
||||
/*
|
||||
* SctCommCfgWord1 COMM_CFG1
|
||||
* Bit WIDTH DESP
|
||||
* 0:19 20 sct_cfg_d_max_time, (reset value: 0)
|
||||
* descriptor max process time, in unit of 32K ticks, if timeout, tigger interrupt: sct_dscrpt_time_out
|
||||
*
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
UINT32 descMaxProcTickTime : 20;
|
||||
UINT32 : 12;
|
||||
};
|
||||
|
||||
UINT32 value32;
|
||||
}SctCommCfgWord1;
|
||||
|
||||
|
||||
/*
|
||||
* SCT common config register struct
|
||||
*/
|
||||
typedef struct SctCommCfgReg_Tag
|
||||
{
|
||||
__IO SctCommCfgWord0 COMM_CFG0; /* SCT common CFG0, offset: 0x54 */
|
||||
__IO SctCommCfgWord1 COMM_CFG1; /* SCT common CFG1, offset: 0x58 */
|
||||
}SctCommCfgReg;
|
||||
|
||||
/*
|
||||
* SCT common control register start address
|
||||
*/
|
||||
#define SCT_COMM_CFG_REG_ADDR (SCT_REG_ADDR + 0x54)
|
||||
|
||||
/*
|
||||
* SCT RNDIS PPP register pointer
|
||||
*/
|
||||
#define SCT_COMM_CFG_REG ((SctCommCfgReg *)SCT_COMM_CFG_REG_ADDR)
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
******************************************************************************
|
||||
* SCT (cipher/integrity) channel config register
|
||||
******************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
*
|
||||
* Bit WIDTH DESP
|
||||
* 0:7 8 sct_fifo_len_ch0
|
||||
* Chain FIFO length, MAX set to 255, (reset value: 0)
|
||||
* 8 1 sct_chain_int_en_ch0, (reset value: 0)
|
||||
* Generate interrupt when each chain in this channel is finished
|
||||
* 9 1 sct_fifo_empty_int_en_ch0, (reset value: 0)
|
||||
* FIFO empty interrupt enable, Generate interrupt when chain FIFO is empty (all done)
|
||||
* 10 1 sct_fifo_full_int_en_ch0, (reset value: 0)
|
||||
* FIFI full interrupt enable, Generate interrupt when chain FIFO is full (>sct_fifo_len_ch0)
|
||||
* 11 1 sct_ck_bl_ch0, input CK is big/little endian
|
||||
* 0 - little endian, (reset value: 0)
|
||||
* 1 - big endian
|
||||
* 12 1 sct_aes_iv_bl_ch0, input AES IV is big/little endian
|
||||
* 0 - little endian, (reset value: 0)
|
||||
* 1 - big endian
|
||||
* 13 1 sct_ck_opt_dis_ch0, whether disable CK optimization, whether need to re-load CK from SRAM, when process descriptors in the same chain
|
||||
* 0 - enable CK opt, (reset value: 0)
|
||||
* 1 - disable CK opt
|
||||
* 16:17 1 comm_crc_poly_len_ch0, common CRC poly length
|
||||
* 0 <20>C 8 bits CRC, (reset value: 0)
|
||||
* 1 <20>C 16 bits CRC
|
||||
* 2 <20>C 24 bits CRC
|
||||
* 3 <20>C 32 bits CRC
|
||||
* 19 1 comm_crc_comple_out_ch0
|
||||
* 0 - CRC output not need to comple, (reset value: 0)
|
||||
* 1 - CRC output need to comple
|
||||
* 20:23 4 comm_crc_comple_in_num_ch0, how many input bytes need to comple, before start CRC,
|
||||
* 24 1 comm_crc_out_bit_swap_ch0
|
||||
* 0 <20>C crcbyte from s[x] to s[x+7], s[x+7] is placed in LSB, (reset value: 0)
|
||||
* 1 <20>C crcbyte from s[x+7] to s[x], s[x+7] is placed in MSB
|
||||
* 25 1 comm_crc_in_bit_swap_ch0
|
||||
* 0 <20>C CRC start from bit[0] of input byte, (reset value: 0)
|
||||
* 1 <20>C CRC start from bit[7] of input byte
|
||||
*
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
UINT32 fifoLen : 8;
|
||||
UINT32 chainIntEn : 1;
|
||||
UINT32 chainEmptyIntEn : 1;
|
||||
UINT32 chainFullIntEn : 1;
|
||||
UINT32 ckBLEndian : 1;
|
||||
UINT32 aesIvBLEndian : 1; /* bit: 12 */
|
||||
UINT32 ckOptDis : 1; /* bit: 13 */
|
||||
UINT32 : 2;
|
||||
UINT32 crcPolyLen : 2; /* bit: 16:17 */
|
||||
UINT32 : 1;
|
||||
UINT32 crcOutComple : 1; /* bit: 19 */
|
||||
UINT32 crcInCompleByteNum : 4; /* bit: 20:23 */
|
||||
UINT32 crcOutBitSwap : 1; /* bit: 24 */
|
||||
UINT32 crcInBitSwap : 1; /* bit: 25 */
|
||||
UINT32 : 6;
|
||||
};
|
||||
|
||||
UINT32 value32;
|
||||
}SctChCfgWord0;
|
||||
|
||||
/*
|
||||
* UINT32 CHA_BASE_ADDR
|
||||
* Chain Base Address. Chain FIFO start address, should be 4 bytes aligned, and with length: 4*CHAINFIFOLEN
|
||||
*/
|
||||
|
||||
/*
|
||||
* UINT32 CK_BASE_ADDR, EEA/EIA CK Base Address
|
||||
* 1. Should be 4 bytes aligned
|
||||
* 2. one CK/IK 16 bytes
|
||||
* 3. Total 8 CK/IK keys, so total byte length: 8*16 = 128
|
||||
*/
|
||||
|
||||
/*
|
||||
* SctChCtrlReg CH_CTRL //write only
|
||||
* Bit WIDTH DESP
|
||||
* 0 1 sct_chain_trigger_ch0
|
||||
* Set 1, Chain trigger, a chain already insert into the chain list, and trigger SCT to process
|
||||
* 1 1 sct_channel_reset_ch0
|
||||
* Set 1, to reset current channel
|
||||
*
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
UINT32 chainTrg : 1;
|
||||
UINT32 chnReset : 1;
|
||||
UINT32 : 30;
|
||||
};
|
||||
|
||||
UINT32 value32;
|
||||
}SctChCtrlReg;
|
||||
|
||||
/*
|
||||
* SCT channel config register struct
|
||||
*/
|
||||
typedef struct SctChannelCfgReg_Tag
|
||||
{
|
||||
__IO SctChCfgWord0 CH_CFG0; /* SCT channel CFG0, offset: 0x5C */
|
||||
__IO UINT32 CHA_BASE_ADDR; /* SCT channel chain base address, offset: 0x60 */
|
||||
__IO UINT32 CK_BASE_ADDR; /* SCT channel CK/IK base address, offset: 0x64 */
|
||||
__IO UINT32 CRC_POLY; /* SCT channel common CRC poly, offset: 0x68 */
|
||||
__IO UINT32 CRC_INIT; /* SCT channel common CRC init value, offset: 0x6C */
|
||||
__O SctChCtrlReg CH_CTRL; /* SCT channel control register, write only, offset: 0x70 */
|
||||
}SctChannelCfgReg;
|
||||
|
||||
/*
|
||||
* SCT totoal channel number: 6
|
||||
*/
|
||||
#define SCT_CHANNEL_NUM 6
|
||||
|
||||
/*
|
||||
* SCT channels config register struct
|
||||
*/
|
||||
typedef struct SctCHSCfgReg_Tag
|
||||
{
|
||||
SctChannelCfgReg chCfg[SCT_CHANNEL_NUM];
|
||||
}SctCHSCfgReg;
|
||||
|
||||
|
||||
/*
|
||||
* SCT channels config register start address
|
||||
*/
|
||||
#define SCT_CHANNEL_CFG_REG_ADDR (SCT_REG_ADDR + 0x5C)
|
||||
|
||||
|
||||
/*
|
||||
* SCT channels config register pointer
|
||||
*/
|
||||
#define SCT_CHANNELS_CFG_REG ((SctCHSCfgReg *)SCT_CHANNEL_CFG_REG_ADDR)
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
******************************************************************************
|
||||
* SCT memory guard register
|
||||
******************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO UINT32 hAddr0; /*sct_mpr_addr_h0, offset: 0xEC */
|
||||
__IO UINT32 lAddr0; /*sct_mpr_addr_l0, offset: 0xF0 */
|
||||
__IO UINT32 hAddr1; /*sct_mpr_addr_h1, offset: 0xF4 */
|
||||
__IO UINT32 lAddr1; /*sct_mpr_addr_l1, offset: 0xF8 */
|
||||
__IO UINT32 hAddr2; /*sct_mpr_addr_h2, offset: 0xFC */
|
||||
__IO UINT32 lAddr2; /*sct_mpr_addr_l2, offset: 0x100 */
|
||||
__IO UINT32 hAddr3; /*sct_mpr_addr_h3, offset: 0x104 */
|
||||
__IO UINT32 lAddr3; /*sct_mpr_addr_l3, offset: 0x108 */
|
||||
}SctMemGuardReg;
|
||||
|
||||
/*
|
||||
* SCT memory guard register start address
|
||||
*/
|
||||
#define SCT_MEM_GUARD_REG_ADDR (SCT_REG_ADDR + 0xEC)
|
||||
|
||||
/*
|
||||
* SCT memory guard register pointer
|
||||
*/
|
||||
#define SCT_MEM_GUARD_CFG_REG ((SctMemGuardReg *)SCT_MEM_GUARD_REG_ADDR)
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
******************************************************************************
|
||||
* SCT channel state register
|
||||
******************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* SCT channel state register
|
||||
* Bit WIDTH DESP
|
||||
* 0:7 8 sct_cfg_fifo_idx_ch0, Channel next configure index
|
||||
* a) reset/init value: 0
|
||||
* b) increase 1, when chain triggered.
|
||||
* c) Range: [0: fifoLen-1]
|
||||
* 8:15 8 sct_done_fifo_idx_ch0, Channel next done index
|
||||
* a) reset/init value: 0
|
||||
* b) increase 1, when one chain process done.
|
||||
* c) Range: [0: fifoLen-1]
|
||||
* 16:23 8 sct_free_fifo_space_ch0
|
||||
* Channel FIFO free space
|
||||
* 24 1 sct_fifo_full_ch0
|
||||
* Whether chain full (overflow), 0 - not, 1 - full
|
||||
* 25 1 sct_fifo_empty_ch0
|
||||
* Whether chain empty (all done), 0 - not, 1 - empty
|
||||
* 26 1 sct_dscrpt_act_ch0
|
||||
* Whether channel is activate, if descriptor in current channel is ongoing, then set 1, so only one channel could be set to 1
|
||||
* 27 1 sct_rst_done_ch0, Whether channel reset done.
|
||||
* a) SW: "SctChCtrlReg->chnReset" set 1, tigger SCT reset current channel
|
||||
* b) HW: SCT should stop current descriptor, and ignore all the pending chain request
|
||||
* c) HW: After reset done, SCT set this flag, and trigger ISR
|
||||
* d) SW: when process this ISR, if need to write USB EP in this channel, need to reflush/reset USB
|
||||
* e) HW: When this channel config/trigger again (SctChCtrlReg->chainTrg = 1), SCT clear this flag
|
||||
* 28 1 sct_dscrpt_time_out_ch0, whether SCT process this descriptor time out
|
||||
* a) HW: SCT start a guard timer, when start processing a descriptor, and stop it when done
|
||||
* b) HW: When timeout, SCT set this flag, and trigger ISR
|
||||
* c) HW: when SW reset current channel (SctChCtrlReg->chnReset = 1), SCT clear this flag
|
||||
*
|
||||
*
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
UINT32 chaNextCfgIdx : 8;
|
||||
UINT32 chaNextDoneIdx : 8;
|
||||
UINT32 chnFreeLen : 8;
|
||||
UINT32 chnBeFull : 1;
|
||||
UINT32 chnBeEmpty : 1;
|
||||
UINT32 chnBeAct : 1;
|
||||
UINT32 chnBeRstDone : 1;
|
||||
UINT32 descBeTimeOut : 1;
|
||||
|
||||
UINT32 : 3;
|
||||
};
|
||||
|
||||
UINT32 value32;
|
||||
}SctChannelStateReg;
|
||||
|
||||
/*
|
||||
* SCT channels state registers
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__I SctChannelStateReg chState[SCT_CHANNEL_NUM]; /* SCT channel state, read only, offset: 0x120 */
|
||||
}SctCHSStateReg;
|
||||
|
||||
/*
|
||||
* SCT channels state register start address
|
||||
*/
|
||||
#define SCT_CHS_STATE_REG_ADDR (SCT_REG_ADDR + 0x120)
|
||||
|
||||
/*
|
||||
* SCT channels state register pointer
|
||||
*/
|
||||
#define SCT_CHS_STATE_REG ((SctCHSStateReg *)SCT_CHS_STATE_REG_ADDR)
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
******************************************************************************
|
||||
* SCT error status register
|
||||
******************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* SctErrStatusWord0 errStatus
|
||||
* Bit WIDTH DESP
|
||||
* 0:5 6 master error (AHB error)
|
||||
* 6:11 6 memory guard error
|
||||
* 12:17 6 descriptor info error (PPP/CRC not byte aligned)
|
||||
*
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
UINT32 masterErr : 6;
|
||||
UINT32 mgrErr : 6;
|
||||
UINT32 descErr : 6;
|
||||
UINT32 : 14;
|
||||
};
|
||||
|
||||
UINT32 value32;
|
||||
}SctErrStatusWord0;
|
||||
|
||||
|
||||
/*
|
||||
* SCT error status register struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__I SctErrStatusWord0 errStatus; /* sct_err_status, read only, offset: 0x138 */
|
||||
__I UINT32 rdErrMem; /* sct_err_mpr_rd, SCT read error address, offset: 0x13C */
|
||||
__I UINT32 wtErrMem; /* sct_err_mpr_wt, SCT write error address, offset: 0x140 */
|
||||
}SctErrStatusReg;
|
||||
|
||||
/*
|
||||
* SCT error status register start address
|
||||
*/
|
||||
#define SCT_ERR_STATUS_REG_ADDR (SCT_REG_ADDR + 0x138)
|
||||
|
||||
/*
|
||||
* SCT error status register pointer
|
||||
*/
|
||||
#define SCT_ERR_STATUS_REG ((SctErrStatusReg *)SCT_ERR_STATUS_REG_ADDR)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2017-, Copyrigths of AirM2M Ltd.
|
||||
* File name: timer.h
|
||||
* Description: EC618 timer driver header file
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _TIMER_EC618_H
|
||||
#define _TIMER_EC618_H
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
|
||||
/**
|
||||
\addtogroup timer_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/** \brief List of TIMER clock source */
|
||||
typedef enum
|
||||
{
|
||||
TIMER_INTERNAL_CLOCK = 0U, /**< Internal clock */
|
||||
TIMER_EXTERNAL_CLOCK = 1U, /**< External clock */
|
||||
} TimerClockSource_t;
|
||||
|
||||
/** \brief List of TIMER match value select */
|
||||
typedef enum
|
||||
{
|
||||
TIMER_MATCH0_SELECT = 0U, /**< Select Match0 */
|
||||
TIMER_MATCH1_SELECT = 1U, /**< Select Match1 */
|
||||
TIMER_MATCH2_SELECT = 2U, /**< Select Match2 */
|
||||
} TimerMatchSelect_t;
|
||||
|
||||
/** \brief List of TIMER reload option, counter will be reloaded to init value upon reach it */
|
||||
typedef enum
|
||||
{
|
||||
TIMER_RELOAD_DISABLE = 0U, /**< Counter will run freely */
|
||||
TIMER_RELOAD_ON_MATCH0 = 1U, /**< Counter will be reloaded on reaching match0 value */
|
||||
TIMER_RELOAD_ON_MATCH1 = 2U, /**< Counter will be reloaded on reaching match1 value */
|
||||
TIMER_RELOAD_ON_MATCH2 = 3U, /**< Counter will be reloaded on reaching match1 value */
|
||||
} TimerReloadOption_t;
|
||||
|
||||
/** \brief PWM configuration structure */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t pwmFreq_HZ; /**< PWM signal frequency in HZ */
|
||||
uint32_t srcClock_HZ; /**< TIMER counter clock in HZ */
|
||||
uint32_t dutyCyclePercent; /**< PWM pulse width, the valid range is 0 to 100 */
|
||||
} TimerPwmConfig_t;
|
||||
|
||||
/** \brief TIMER configuration structure */
|
||||
typedef struct
|
||||
{
|
||||
TimerClockSource_t clockSource; /**< Clock source */
|
||||
TimerReloadOption_t reloadOption; /**< Reload option */
|
||||
uint32_t initValue; /**< Counter init value */
|
||||
uint32_t match0; /**< Match0 value */
|
||||
uint32_t match1; /**< Match1 value */
|
||||
uint32_t match2; /**< Match2 value */
|
||||
} TimerConfig_t;
|
||||
|
||||
/** \brief TIMER interrupt configuration */
|
||||
typedef enum
|
||||
{
|
||||
TIMER_INTERRUPT_DISABLED = 0U, /**< Disable interrupt */
|
||||
TIMER_INTERRUPT_LEVEL = 1U, /**< Level interrupt, a high level interrupt signal is generated */
|
||||
TIMER_INTERRUPT_PULSE = 2U, /**< Pulse interrupt, a pulse of one clock width
|
||||
is generated after counter matches */
|
||||
} TimerInterruptConfig_t;
|
||||
|
||||
|
||||
/** \brief List of TIMER interrupts */
|
||||
typedef enum
|
||||
{
|
||||
TIMER_MATCH0_INTERRUPT_ENABLE = TIMER_TCTLR_IE_0_Msk, /**< Match0 interrupt */
|
||||
TIMER_MATCH1_INTERRUPT_ENABLE = TIMER_TCTLR_IE_1_Msk, /**< Match1 interrupt */
|
||||
TIMER_MATCH2_INTERRUPT_ENABLE = TIMER_TCTLR_IE_2_Msk, /**< Match2 interrupt */
|
||||
} TimerInterruptEnable_t;
|
||||
|
||||
/** \brief List of TIMER interrupt flags */
|
||||
typedef enum
|
||||
{
|
||||
TIMER_MATCH0_INTERRUPT_FLAG = TIMER_TSR_ICLR_0_Msk, /**< Match0 interrupt flag */
|
||||
TIMER_MATCH1_INTERRUPT_FLAG = TIMER_TSR_ICLR_1_Msk, /**< Match1 interrupt flag */
|
||||
TIMER_MATCH2_INTERRUPT_FLAG = TIMER_TSR_ICLR_2_Msk, /**< Match2 interrupt flag */
|
||||
} TimerInterruptFlags_t;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \name TIMER Driver Initialization */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void TIMER_driverInit(void);
|
||||
\brief Intialize TIMER driver internal data, must be called before any other APIs
|
||||
*/
|
||||
void TIMER_driverInit(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name TIMER Configuration */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void TIMER_getDefaultConfig(TimerConfig_t *config)
|
||||
\brief Gets the TIMER default configuartion.
|
||||
This function sets the configuration structure to default values as below:
|
||||
\code
|
||||
config->clockSource = TIMER_INTERNAL_CLOCK;
|
||||
config->reloadOption = TIMER_RELOAD_ON_MATCH1;
|
||||
config->initValue = 0;
|
||||
config->match0 = 0x10000 >> 1;
|
||||
config->match1 = 0x10000;
|
||||
config->match2 = 0xFFFFFFFF;
|
||||
\endcode
|
||||
|
||||
\param[in] config Pointer to TIMER configuration structure
|
||||
*/
|
||||
void TIMER_getDefaultConfig(TimerConfig_t *config);
|
||||
|
||||
/**
|
||||
\fn void TIMER_init(uint32_t instance, const TimerConfig_t *config)
|
||||
\brief Intialize TIMER
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
\param[in] config Pointer to TIMER configuration
|
||||
\note PWM out is disabled after this function's call, use \ref TIMER_setupPwm function to eable PWM
|
||||
*/
|
||||
void TIMER_init(uint32_t instance, const TimerConfig_t *config);
|
||||
|
||||
/**
|
||||
\fn void TIMER_deInit(uint32_t instance)
|
||||
\brief Deintialize TIMER
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
*/
|
||||
void TIMER_deInit(uint32_t instance);
|
||||
|
||||
/**
|
||||
\fn void TIMER_setMatch(uint32_t instance, TimerMatchSelect_t match)
|
||||
\brief Sets one of TIMER match values
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
\param[in] matchNum TIMER match select
|
||||
\param[in] matchValue TIMER match value
|
||||
*/
|
||||
void TIMER_setMatch(uint32_t instance, TimerMatchSelect_t matchNum, uint32_t matchValue);
|
||||
|
||||
/**
|
||||
\fn void TIMER_setMatch(uint32_t instance, TimerMatchSelect_t match)
|
||||
\brief Sets TIMER counter initial value
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
\param[in] initValue TIMER initial value
|
||||
*/
|
||||
void TIMER_setInitValue(uint32_t instance, uint32_t initValue);
|
||||
|
||||
/**
|
||||
\fn void TIMER_setMatch(uint32_t instance, TimerMatchSelect_t match)
|
||||
\brief Sets TIMER counter reload option
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
\param[in] option TIMER counter reload option
|
||||
*/
|
||||
void TIMER_setReloadOption(uint32_t instance, TimerReloadOption_t option);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name TIMER Counter */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void TIMER_start(uint32_t instance)
|
||||
\brief Starts TIMER counter
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
*/
|
||||
void TIMER_start(uint32_t instance);
|
||||
|
||||
/**
|
||||
\fn void TIMER_stop(uint32_t instance)
|
||||
\brief Stops TIMER counter
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
*/
|
||||
void TIMER_stop(uint32_t instance);
|
||||
|
||||
/**
|
||||
\fn uint32_t TIMER_getCount(uint32_t instance)
|
||||
\brief Reads current TIMER counter value
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
\return current TIMER counter value
|
||||
*/
|
||||
uint32_t TIMER_getCount(uint32_t instance);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name TIMER PWM */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn int32_t TIMER_setupPwm(uint32_t instance, const TimerPwmConfig_t *config)
|
||||
\brief Configures the PWM signals period, mode, etc.
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
\param[in] config Pointer to PWM parameter
|
||||
\return ARM_DRIVER_OK if the PWM setup is successful
|
||||
ARM_DRIVER_ERROR_PARAMETER on parameter check failure
|
||||
*/
|
||||
int32_t TIMER_setupPwm(uint32_t instance, const TimerPwmConfig_t *config);
|
||||
|
||||
/**
|
||||
\fn void TIMER_updatePwmDutyCycle(uint32_t instance, uint32_t dutyCyclePercent)
|
||||
\brief Updates the duty cycle of PWM signal
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
\param[in] dutyCyclePercent New PWM pulse width, value shall be between 0 to 100,
|
||||
if the value exceeds 100, dutyCyclePercent is set to 100.
|
||||
*/
|
||||
void TIMER_updatePwmDutyCycle(uint32_t instance, uint32_t dutyCyclePercent);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name TIMER Interrupt */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void TIMER_interruptConfig(uint32_t instance, TimerMatchSelect_t match, TimerInterruptConfig_t config)
|
||||
\brief Configures the selected TIMER interrupt
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
\param[in] match TIMER match select
|
||||
\param[in] config TIMER interrupt configuration
|
||||
*/
|
||||
void TIMER_interruptConfig(uint32_t instance, TimerMatchSelect_t match, TimerInterruptConfig_t config);
|
||||
|
||||
/**
|
||||
\fn TimerInterruptConfig_t TIMER_getInterruptConfig(uint32_t instance, TimerMatchSelect_t match)
|
||||
\brief Gets current configuration of the selected TIMER interrupt
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
\param[in] match TIMER match select
|
||||
\return Current TIMER interrupt configuration
|
||||
*/
|
||||
TimerInterruptConfig_t TIMER_getInterruptConfig(uint32_t instance, TimerMatchSelect_t match);
|
||||
|
||||
/**
|
||||
\fn uint32_t TIMER_getInterruptFlags(uint32_t instance)
|
||||
\brief Reads TIMER interrupt status flags
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
\return Interrupt flags. This is the logical OR of members of the
|
||||
enumeration \ref TimerInterruptFlags_t
|
||||
*/
|
||||
uint32_t TIMER_getInterruptFlags(uint32_t instance);
|
||||
|
||||
/**
|
||||
\fn void TIMER_clearInterruptFlags(uint32_t instance, uint32_t mask)
|
||||
\brief Clears TIMER interrupt flags
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
\param[in] mask Interrupt flags to clear. This is a logic OR of members of the
|
||||
enumeration \ref TimerInterruptFlags_t
|
||||
*/
|
||||
void TIMER_clearInterruptFlags(uint32_t instance, uint32_t mask);
|
||||
|
||||
/**
|
||||
\fn void TIMER_netlightEnable(uint32_t instance)
|
||||
\brief Set Netlight Enable, called by user in bsp_custom.c to define specific timer instance for netlight
|
||||
\param[in] instance TIMER instance number (0, 1, ...)
|
||||
*/
|
||||
void TIMER_netlightEnable(uint8_t instance);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TIMER_EC618_H */
|
||||
@@ -0,0 +1,259 @@
|
||||
#ifndef __TLS_H__
|
||||
#define __TLS_H__
|
||||
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
|
||||
#define SCT_BASE_ADDR (0x40050000)
|
||||
|
||||
#define AES_SHA_CH4_CFG_REG (SCT_BASE_ADDR + 0xbc) // AES/SHA uses sct channel4
|
||||
#define AES_SHA_CH4_STATE_REG (SCT_BASE_ADDR + 0x130)
|
||||
|
||||
#define SCT_ENABLE_REG (SCT_BASE_ADDR + 0x00)
|
||||
#define SCT_COMM_CFG0_REG (SCT_BASE_ADDR + 0x54)
|
||||
#define SCT_COMM_CFG1_REG (SCT_BASE_ADDR + 0x58)
|
||||
#define SCT_MEM_GUARD_REG (SCT_BASE_ADDR + 0xec)
|
||||
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SHA_TYPE_1,
|
||||
SHA_TYPE_224,
|
||||
SHA_TYPE_256,
|
||||
}shaType_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t length : 16;
|
||||
uint32_t dir : 1; // 0 - Encryption, 1 - Decryption
|
||||
uint32_t aesMode : 2; // 0 <20>C ECB, 1 <20>C CBC, 2 <20>C CTR
|
||||
uint32_t paddingMode : 3;
|
||||
uint32_t ckLen : 2; // 0 <20>C 128, 1 <20>C 192, 2 <20>C 256
|
||||
uint32_t aesCkSel : 1; // 0 <20>C from configured CK address, 1 <20>C from efuse
|
||||
uint32_t : 2;
|
||||
uint32_t subType : 2; // 0 <20>C AES descriptor; 1 <20>C SHA descriptor
|
||||
uint32_t type : 3; // Default 101
|
||||
}aesField_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t length : 16; // sha can handle 64k data one time
|
||||
uint32_t shaMode : 2; // 0: sha1; 1: sha224; 2: sha256
|
||||
uint32_t shaBls : 1; // sha output endian. 0: LE; 1: BE
|
||||
uint32_t rcs : 1; // 0: current is last data; 1: current data is continuous
|
||||
uint32_t outEn : 1; // open output
|
||||
uint32_t : 6;
|
||||
uint32_t subType : 2; // // 0: aes; 1:sha
|
||||
uint32_t type : 3; // Default 101
|
||||
}shaField_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t headLen : 16;
|
||||
uint32_t : 16;
|
||||
}shaHeadLen_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union firstWord
|
||||
{
|
||||
aesField_t aesField;
|
||||
shaField_t shaField;
|
||||
}u1;
|
||||
|
||||
uint32_t srcAddr;
|
||||
uint32_t dstAddr;
|
||||
|
||||
union secondWord
|
||||
{
|
||||
uint32_t aesCkAddr;
|
||||
uint32_t shaHeaderAddr;
|
||||
}u2;
|
||||
|
||||
union thirdWord
|
||||
{
|
||||
uint32_t aesIvAddr;
|
||||
shaHeadLen_t shaHeadLen;
|
||||
}u3;
|
||||
}sctDescCfg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t trigger : 1;
|
||||
uint32_t reset : 1;
|
||||
uint32_t : 30;
|
||||
}sctChanCfg_t;
|
||||
|
||||
|
||||
typedef union {
|
||||
struct
|
||||
{
|
||||
uint32_t fifoLen : 8; // chain fifo length, max is 255
|
||||
uint32_t chainIntEn : 1;
|
||||
uint32_t chainEmptyIntEn : 1;
|
||||
uint32_t chainFullIntEn : 1;
|
||||
uint32_t ckBLEndian : 1;
|
||||
uint32_t aesIvBLEndian : 1; // bit: 12
|
||||
uint32_t ckOptDis : 1; // bit: 13
|
||||
uint32_t : 2;
|
||||
uint32_t crcPolyLen : 2; // bit: 16:17
|
||||
uint32_t : 1;
|
||||
uint32_t crcOutComple : 1; // bit: 19
|
||||
uint32_t crcInCompleByteNum: 4; // bit: 20:23
|
||||
uint32_t crcOutBitSwap : 1; // bit: 24
|
||||
uint32_t crcInBitSwap : 1; // bit: 25
|
||||
uint32_t : 6;
|
||||
};
|
||||
uint32_t val;
|
||||
}chanCfgWord0_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
chanCfgWord0_t chanCfgWord0;
|
||||
uint32_t chanCfgWord1; // First desc addr
|
||||
uint32_t rsvd[3];
|
||||
sctChanCfg_t chanCfgWord5;
|
||||
}sctCfgWord_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t chaNextCfgIdx : 8;
|
||||
uint32_t chaNextDoneIdx : 8;
|
||||
uint32_t chaFreeLen : 8;
|
||||
uint32_t chaBeFull : 1;
|
||||
uint32_t chaBeEmpty : 1;
|
||||
uint32_t chaBeAct : 1;
|
||||
uint32_t chaBeRstDone : 1;
|
||||
uint32_t descBeTimeout : 1;
|
||||
uint32_t : 3;
|
||||
}sctChaState_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t hAddr0;
|
||||
uint32_t lAddr0;
|
||||
uint32_t hAddr1;
|
||||
uint32_t lAddr1;
|
||||
uint32_t hAddr2;
|
||||
uint32_t lAddr2;
|
||||
uint32_t hAddr3;
|
||||
uint32_t lAddr3;
|
||||
}sctMemGuard_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t rmiAcg : 1;
|
||||
uint32_t ahbAcg : 1;
|
||||
uint32_t : 14;
|
||||
uint32_t chainStartUnilog : 1;
|
||||
uint32_t descDoneUnilog : 1;
|
||||
uint32_t chainEndUnilog : 1;
|
||||
uint32_t errorIntUnilog : 1;
|
||||
uint32_t usbEndianInd : 1;
|
||||
uint32_t : 3;
|
||||
uint32_t memHighAddrOffset : 8;
|
||||
};
|
||||
uint32_t val;
|
||||
}sctCfgWord0_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t descMaxProcTickTime : 20; // descriptor handle max timeout
|
||||
uint32_t : 12;
|
||||
}sctCfgWord1_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dir : 1; // 0: encrypt, 1: decrypt
|
||||
uint32_t aesMode : 2; // 0: ecb, 1:cbc, 2:ctr
|
||||
uint32_t paddingMode : 3; // 0: no padding, 1: PKCS7, 2: paddingOneZeros, 3: paddingZerosLen, 4: paddingZeros
|
||||
uint32_t ckLen : 2; // 0:128, 1:192, 2:256
|
||||
uint32_t aesCkSel : 1; // 0: from memory, 1: from efuse
|
||||
uint32_t ckBLEndian : 1; // Ignore it if key is from efuse. If key is from memory, 0: little; 1: big
|
||||
uint32_t aesIvBLEndian : 1; // input AES IV is big/little endian. 0: little; 1: big
|
||||
uint32_t : 23;
|
||||
}aesCtrl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t ivAddr;
|
||||
uint32_t srcAddr;
|
||||
uint32_t dstAddr;
|
||||
uint32_t aesCkAddr;
|
||||
uint32_t length;
|
||||
aesCtrl_t aesCtrl;
|
||||
}aesInfo_t;
|
||||
|
||||
/*
|
||||
* SCT memory guard address
|
||||
* SCT could only access MSMB: 0x00400000 ~ 0x0053FFFF
|
||||
*/
|
||||
#define MGR_LOW_ADDR 0x00400000
|
||||
#define MGR_HIGH_ADDR 0x0053FFFF
|
||||
|
||||
/*
|
||||
* SCT memory guard address
|
||||
* USB TX FIFO: 0x00400000 ~ 0x0053FFFF
|
||||
*/
|
||||
#define MGR_LOW_ADDR1 0x1A000000
|
||||
#define MGR_HIGH_ADDR1 0x1AFFFFFF
|
||||
|
||||
/*
|
||||
* AP flash, 4M: 0x0080-0000~0x00BF-FFFF
|
||||
*/
|
||||
#define MGR_LOW_ADDR2 0x00800000
|
||||
#define MGR_HIGH_ADDR2 0x00BFFFFF
|
||||
|
||||
|
||||
/*
|
||||
* CP flash, 1M: 0x0880-0000~0x088F-FFFF
|
||||
*/
|
||||
#define MGR_LOW_ADDR3 0x08800000
|
||||
#define MGR_HIGH_ADDR3 0x088FFFFF
|
||||
|
||||
|
||||
|
||||
#define SCTDRV_OK (0)
|
||||
#define SCTDRV_BUSY (-1)
|
||||
#define SCTDRV_TIMEOUT (-2)
|
||||
#define SCTDRV_PAMERR (-5)
|
||||
|
||||
/**
|
||||
\brief SCT module init.
|
||||
\return
|
||||
*/
|
||||
void sctInit();
|
||||
|
||||
/**
|
||||
\brief SCT module deInit.
|
||||
\return
|
||||
*/
|
||||
void sctDeInit();
|
||||
|
||||
|
||||
/**
|
||||
\brief Aes operation
|
||||
\param[in] aesInfo Aes information.
|
||||
\return status
|
||||
*/
|
||||
int32_t aesUpdate(aesInfo_t* aesInfo);
|
||||
|
||||
/**
|
||||
\brief Sha operation.
|
||||
\param[in] shaMode Choose SHA1, SHA224, SHA256.
|
||||
\param[in] srcAddr SHA input address.
|
||||
\param[in] dstAddr SHA output address.
|
||||
\param[in] length SHA input length.
|
||||
\param[in] lastFlag If you need to loop call this api, "lastFlag" should be 0 for intermediate steps, and last step it should be 1.
|
||||
\return status
|
||||
*/
|
||||
int32_t shaUpdate(shaType_e shaMode, uint32_t srcAddr, uint32_t dstAddr, uint32_t length, uint32_t lastFlag);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
|
||||
* File name: uart.h
|
||||
* Description: EC618 uart driver header file
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _UART_EC618_H
|
||||
#define _UART_EC618_H
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
|
||||
/**
|
||||
\addtogroup uart_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\fn void UART_init(uint32_t instance, uint32_t baudrate, bool enableFlowCtrl)
|
||||
\brief Initialize UART with specific baudrate
|
||||
\param[in] instance UART instance number (0, 1, ...)
|
||||
\param[in] baudrate The desired baudrate
|
||||
\param[in] enableFlowCtrl Enable flow control or not
|
||||
*/
|
||||
void UART_init(uint32_t instance, uint32_t baudrate, bool enableFlowCtrl);
|
||||
|
||||
/**
|
||||
\fn uint32_t UART_send(uint32_t instance, const uint8_t *data, uint32_t num, uint32_t timeout_us)
|
||||
\brief Start sending data to USART transmitter in polling way
|
||||
\param[in] instance UART instance number (0, 1, ...)
|
||||
\param[in] data Pointer to buffer with data to send to USART transmitter
|
||||
\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 UART_send(uint32_t instance, const uint8_t *data, uint32_t num, uint32_t timeout_us);
|
||||
|
||||
/**
|
||||
\fn uint32_t UART_receive(uint32_t instance, uint8_t *data, uint32_t num, uint32_t timeout_us)
|
||||
\brief Start receiving data from USART receiver in polling way
|
||||
\param[in] instance UART instance number (0, 1, ...)
|
||||
\param[out] data Pointer to buffer for data to receive from USART receiver
|
||||
\param[in] num Number of data items to receive
|
||||
\param[in] timeout_us timeout value in unit of us
|
||||
\return num of data items received in the internal of timeout
|
||||
*/
|
||||
uint32_t UART_receive(uint32_t instance, uint8_t *data, uint32_t num, uint32_t timeout_us);
|
||||
|
||||
/**
|
||||
\fn void UART_printf(uint32_t instance, const char* fmt, ...)
|
||||
\brief Print formated data to USART transmitter
|
||||
\param[in] instance UART instance number (0, 1, ...)
|
||||
\param[in] fmt C string that contains the text to be sent to UART
|
||||
\param[in] ... __VA__ARGS
|
||||
*/
|
||||
void UART_printf(uint32_t instance, const char* fmt, ...);
|
||||
|
||||
void UART_flush(uint32_t instance);
|
||||
void UART_purgeRx(uint32_t instance);
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _UART_EC618_H */
|
||||
@@ -0,0 +1,83 @@
|
||||
/******************************************************************************
|
||||
|
||||
*(C) Copyright 2018 AirM2M International Ltd.
|
||||
|
||||
* All Rights Reserved
|
||||
|
||||
******************************************************************************
|
||||
* Filename:
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _UNILOG_API_H
|
||||
#define _UNILOG_API_H
|
||||
/*----------------------------------------------------------------------------*
|
||||
* INCLUDES *
|
||||
*----------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* MACROS *
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define UNILOG_TRACE_MAX_MODULE_VALUE (1024)
|
||||
|
||||
#define UNILOG_DMA_REQ_MODE_USB (0x3)
|
||||
#define UNILOG_DMA_REQ_MODE_UART (0x0)
|
||||
|
||||
#define UNILOG_ID_CONSTRUCT(ownerId, moduleId, subId) ((ownerId << 28) | (moduleId << 21) | (subId << 11))
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* DATA TYPE DEFINITION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UART_0_FOR_UNILOG = 0,
|
||||
UART_1_FOR_UNILOG = 1,
|
||||
UART_2_FOR_UNILOG = 2,
|
||||
// SPI_0_FOR_UNILOG = 3,
|
||||
// SPI_1_FOR_UNILOG = 4,
|
||||
USB_FOR_UNILOG = 5
|
||||
} UnilogPeripheralType_e;
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* GLOBAL FUNCTIONS DECLEARATION *
|
||||
*----------------------------------------------------------------------------*/
|
||||
void uniLogModuleAllowTraces(uint16_t moduleID);
|
||||
void uniLogModuleDisableTraces(uint16_t moduleID);
|
||||
void uniLogModuleAllowAllTraces(void);
|
||||
void uniLogModuleDisableAllTraces(void);
|
||||
bool uniLogTraceAllowCheck(uint8_t debugLevel);
|
||||
void uniLogFlushOut(void);
|
||||
void uniLogForceOut(bool waitFifoOut);
|
||||
void uniLogStop(void);
|
||||
void uniLogStopHwLog(void);
|
||||
bool uniLogIsInitialized(void);
|
||||
void uniLogGetSettingFromFlash(void);
|
||||
void swLogExcep(uint32_t swLogID, uint8_t debugLevel, ...);
|
||||
void swLogPrintf(uint32_t swLogID, uint8_t debugLevel, ...);
|
||||
void swLogDump(uint32_t swLogID, uint8_t debugLevel, uint32_t dumpLen, const uint8_t*pDump);
|
||||
void swLogPrintfPolling(uint32_t swLogID, uint8_t debugLevel, ...);
|
||||
void swLogDumpPolling(uint32_t swLogID, uint8_t debugLevel, uint32_t dumpLen, const uint8_t*pDump);
|
||||
void uniLogSetPherType(UnilogPeripheralType_e periphType);
|
||||
UnilogPeripheralType_e uniLogGetPherType(void);
|
||||
bool unilogSwitch2UartLog(void);
|
||||
bool unilogSwitch2UsbLog(void);
|
||||
bool uniLogGetDumpRdyFlag(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif//_UNILOG_API_H
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2017-, Copyrigths of AirM2M Ltd.
|
||||
* File name: wdt.h
|
||||
* Description: EC618 wdt driver header file
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _WDT_EC618_H
|
||||
#define _WDT_EC618_H
|
||||
|
||||
#include "ec618.h"
|
||||
#include "Driver_Common.h"
|
||||
|
||||
/**
|
||||
\addtogroup wdt_interface_gr
|
||||
\{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/** \brief List of WDT mode */
|
||||
typedef enum
|
||||
{
|
||||
WDT_INTERRUPT_ONLY_MODE = 0U, /**< Only generate an interrupt upon timeout */
|
||||
WDT_INTERRUPT_RESET_MODE = 1U, /**< Reset upon timeout if the first interrupt is not cleared */
|
||||
} WdtMode_e;
|
||||
|
||||
/** \brief WDT configuration structure */
|
||||
typedef struct
|
||||
{
|
||||
WdtMode_e mode;
|
||||
uint16_t timeoutValue;
|
||||
} WdtConfig_t;
|
||||
|
||||
/** \brief List of WDT interrupt flags */
|
||||
typedef enum
|
||||
{
|
||||
WDT_INTERRUPT_FLAG = WDT_STAT_ISTAT_Msk, /**< Wdt interrupt flag */
|
||||
} WdtInterruptFlags_e;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \name WDT Configuration */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void WDT_getDefaultConfig(WdtConfig_t *config)
|
||||
\brief Gets the WDT default configuartion.
|
||||
This function sets the configuration structure to default values as below:
|
||||
\code
|
||||
config->mode = WDT_INTERRUPT_ONLY_MODE;
|
||||
config->timeoutValue = 0xFFFF;
|
||||
\endcode
|
||||
|
||||
\param[in] config Pointer to WDT configuration structure
|
||||
*/
|
||||
void WDT_getDefaultConfig(WdtConfig_t *config);
|
||||
|
||||
/**
|
||||
\fn void WDT_init(const WdtConfig_t *config)
|
||||
\brief Initialize WDT
|
||||
\param[in] config Pointer to WDT configuration
|
||||
*/
|
||||
void WDT_init(const WdtConfig_t *config);
|
||||
|
||||
/**
|
||||
\fn void WDT_deInit(void)
|
||||
\brief Deinitialize WDT
|
||||
*/
|
||||
void WDT_deInit(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name WDT Unlock and Kick */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void WDT_unlock(void)
|
||||
\brief Unlocks the WDT register written
|
||||
*/
|
||||
void WDT_unlock(void);
|
||||
|
||||
/**
|
||||
\fn void WDT_kick(void)
|
||||
\brief Refreshes WDT counter
|
||||
*/
|
||||
void WDT_kick(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name WDT Start and Stop */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn void WDT_start(void)
|
||||
\brief Starts WDT counter
|
||||
*/
|
||||
void WDT_start(void);
|
||||
|
||||
/**
|
||||
\fn void WDT_stop(void)
|
||||
\brief Stops WDT counter
|
||||
*/
|
||||
void WDT_stop(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \name WDT Interrupt and Status */
|
||||
/** \{ */
|
||||
|
||||
/**
|
||||
\fn uint32_t WDT_getInterruptFlags(void)
|
||||
\brief Reads WDT interrupt status flags
|
||||
\return Interrupt flags. This is the logical OR of members of the
|
||||
enumeration \ref WdtInterruptFlags_e
|
||||
*/
|
||||
uint32_t WDT_getInterruptFlags(void);
|
||||
|
||||
/**
|
||||
\fn void WDTclearInterruptFlags(uint32_t mask)
|
||||
\brief Clears WDT interrupt flags
|
||||
\param[in] mask Interrupt flags to clear. This is a logic OR of members of the
|
||||
enumeration \ref WdtInterruptFlags_e
|
||||
*/
|
||||
void WDTclearInterruptFlags(uint32_t mask);
|
||||
|
||||
/**
|
||||
\fn WdtMode_e WDT_getMode(void)
|
||||
\brief Gets current WDT mode
|
||||
\return WDT mode, see \ref WdtMode_e
|
||||
*/
|
||||
WdtMode_e WDT_getMode(void);
|
||||
|
||||
/**
|
||||
\fn bool WDT_getStartStatus(void)
|
||||
\brief Checks if WDT is started or stopped
|
||||
\return true if WDT is counting
|
||||
false if WDT is stopped
|
||||
*/
|
||||
bool WDT_getStartStatus(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _WDT_EC618_H */
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2013-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.
|
||||
*
|
||||
* $Date: 2. Feb 2017
|
||||
* $Revision: V2.0
|
||||
*
|
||||
* Project: Common Driver definitions
|
||||
*/
|
||||
|
||||
/* History:
|
||||
* Version 2.0
|
||||
* Changed prefix ARM_DRV -> ARM_DRIVER
|
||||
* Added General return codes definitions
|
||||
* Version 1.10
|
||||
* Namespace prefix ARM_ added
|
||||
* Version 1.00
|
||||
* Initial release
|
||||
*/
|
||||
|
||||
#ifndef DRIVER_COMMON_H_
|
||||
#define DRIVER_COMMON_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include "sctdef.h"
|
||||
#ifdef FEATURE_OS_ENABLE
|
||||
#include "exception_process.h"
|
||||
#endif
|
||||
|
||||
#define ARM_DRIVER_VERSION_MAJOR_MINOR(major,minor) (((major) << 8) | (minor))
|
||||
|
||||
/**
|
||||
\brief Driver Version
|
||||
*/
|
||||
typedef struct _ARM_DRIVER_VERSION {
|
||||
uint16_t api; ///< API version
|
||||
uint16_t drv; ///< Driver version
|
||||
} ARM_DRIVER_VERSION;
|
||||
|
||||
/* General return codes */
|
||||
#define ARM_DRIVER_OK 0 ///< Operation succeeded
|
||||
#define ARM_DRIVER_ERROR -1 ///< Unspecified error
|
||||
#define ARM_DRIVER_ERROR_BUSY -2 ///< Driver is busy
|
||||
#define ARM_DRIVER_ERROR_TIMEOUT -3 ///< Timeout occurred
|
||||
#define ARM_DRIVER_ERROR_UNSUPPORTED -4 ///< Operation not supported
|
||||
#define ARM_DRIVER_ERROR_PARAMETER -5 ///< Parameter error
|
||||
#define ARM_DRIVER_ERROR_SPECIFIC -6 ///< Start of driver specific errors
|
||||
|
||||
/**
|
||||
\brief General power states
|
||||
*/
|
||||
typedef enum _ARM_POWER_STATE {
|
||||
ARM_POWER_OFF, ///< Power off: no operation possible
|
||||
ARM_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events
|
||||
ARM_POWER_FULL ///< Power on: full operation at maximum performance
|
||||
} ARM_POWER_STATE;
|
||||
|
||||
typedef struct _PIN {
|
||||
uint8_t pinNum;
|
||||
uint8_t funcNum;
|
||||
} PIN;
|
||||
|
||||
#ifndef ASSERT
|
||||
#ifdef FEATURE_OS_ENABLE
|
||||
#define ASSERT(X) EC_ASSERT(X,0,0,0)
|
||||
#else
|
||||
#define ASSERT(X) assert(X)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BIT
|
||||
#define BIT(n) ((unsigned int) 1 << (n))
|
||||
#define BITS2(m,n) (BIT(m) | BIT(n))
|
||||
#define BITS(m,n) (~(BIT(m) - 1) & ((BIT(n) - 1) | BIT(n)))
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b) ? (a) : (b)))
|
||||
#endif
|
||||
|
||||
#endif /* DRIVER_COMMON_H_ */
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2013-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.
|
||||
*
|
||||
* $Date: 2. Feb 2017
|
||||
* $Revision: V2.3
|
||||
*
|
||||
* Project: I2C (Inter-Integrated Circuit) Driver definitions
|
||||
*/
|
||||
|
||||
/* History:
|
||||
* Version 2.3
|
||||
* ARM_I2C_STATUS made volatile
|
||||
* Version 2.2
|
||||
* Removed function ARM_I2C_MasterTransfer in order to simplify drivers
|
||||
* and added back parameter "xfer_pending" to functions
|
||||
* ARM_I2C_MasterTransmit and ARM_I2C_MasterReceive
|
||||
* Version 2.1
|
||||
* Added function ARM_I2C_MasterTransfer and removed parameter "xfer_pending"
|
||||
* from functions ARM_I2C_MasterTransmit and ARM_I2C_MasterReceive
|
||||
* Added function ARM_I2C_GetDataCount
|
||||
* Removed flag "address_nack" from ARM_I2C_STATUS
|
||||
* Replaced events ARM_I2C_EVENT_MASTER_DONE and ARM_I2C_EVENT_SLAVE_DONE
|
||||
* with event ARM_I2C_EVENT_TRANSFER_DONE
|
||||
* Added event ARM_I2C_EVENT_TRANSFER_INCOMPLETE
|
||||
* Removed parameter "arg" from function ARM_I2C_SignalEvent
|
||||
* Version 2.0
|
||||
* New simplified driver:
|
||||
* complexity moved to upper layer (especially data handling)
|
||||
* more unified API for different communication interfaces
|
||||
* Added:
|
||||
* Slave Mode
|
||||
* Changed prefix ARM_DRV -> ARM_DRIVER
|
||||
* Version 1.10
|
||||
* Namespace prefix ARM_ added
|
||||
* Version 1.00
|
||||
* Initial release
|
||||
*/
|
||||
|
||||
#ifndef DRIVER_I2C_H_
|
||||
#define DRIVER_I2C_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "Driver_Common.h"
|
||||
|
||||
#define ARM_I2C_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,3) /* API version */
|
||||
|
||||
|
||||
/****** I2C Control Codes *****/
|
||||
|
||||
#define ARM_I2C_OWN_ADDRESS (0x01) ///< Set Own Slave Address; arg = address
|
||||
#define ARM_I2C_BUS_SPEED (0x02) ///< Set Bus Speed; arg = speed
|
||||
#define ARM_I2C_BUS_CLEAR (0x03) ///< Execute Bus clear: send nine clock pulses
|
||||
#define ARM_I2C_ABORT_TRANSFER (0x04) ///< Abort Master/Slave Transmit/Receive
|
||||
|
||||
/*----- I2C Bus Speed -----*/
|
||||
#define ARM_I2C_BUS_SPEED_STANDARD (0x01) ///< Standard Speed (100kHz)
|
||||
#define ARM_I2C_BUS_SPEED_FAST (0x02) ///< Fast Speed (400kHz)
|
||||
#define ARM_I2C_BUS_SPEED_FAST_PLUS (0x03) ///< Fast+ Speed ( 1MHz)
|
||||
#define ARM_I2C_BUS_SPEED_HIGH (0x04) ///< High Speed (3.4MHz)
|
||||
|
||||
|
||||
/****** I2C Address Flags *****/
|
||||
|
||||
#define ARM_I2C_ADDRESS_10BIT (0x0400) ///< 10-bit address flag
|
||||
#define ARM_I2C_ADDRESS_GC (0x8000) ///< General Call flag
|
||||
|
||||
|
||||
/**
|
||||
\brief I2C Status
|
||||
*/
|
||||
typedef volatile struct _ARM_I2C_STATUS {
|
||||
uint32_t busy : 1; ///< Busy flag
|
||||
uint32_t mode : 1; ///< Mode: 0=Slave, 1=Master
|
||||
uint32_t direction : 1; ///< Direction: 0=Transmitter, 1=Receiver
|
||||
uint32_t general_call : 1; ///< General Call indication (cleared on start of next Slave operation)
|
||||
uint32_t arbitration_lost : 1; ///< Master lost arbitration (cleared on start of next Master operation)
|
||||
uint32_t bus_error : 1; ///< Bus error detected (cleared on start of next Master/Slave operation)
|
||||
uint32_t rx_nack : 1; ///< NACK detected (cleared on start of next Master/Slave operation)
|
||||
uint32_t reserved : 25;
|
||||
} ARM_I2C_STATUS;
|
||||
|
||||
|
||||
/****** I2C Event *****/
|
||||
#define ARM_I2C_EVENT_TRANSFER_DONE (1UL << 0) ///< Master/Slave Transmit/Receive finished
|
||||
#define ARM_I2C_EVENT_TRANSFER_INCOMPLETE (1UL << 1) ///< Master/Slave Transmit/Receive incomplete transfer
|
||||
#define ARM_I2C_EVENT_SLAVE_TRANSMIT (1UL << 2) ///< Addressed as Slave Transmitter but transmit operation is not set.
|
||||
#define ARM_I2C_EVENT_SLAVE_RECEIVE (1UL << 3) ///< Addressed as Slave Receiver but receive operation is not set.
|
||||
#define ARM_I2C_EVENT_ADDRESS_NACK (1UL << 4) ///< Address not acknowledged from Slave
|
||||
#define ARM_I2C_EVENT_GENERAL_CALL (1UL << 5) ///< Slave addressed with general call address
|
||||
#define ARM_I2C_EVENT_ARBITRATION_LOST (1UL << 6) ///< Master lost arbitration
|
||||
#define ARM_I2C_EVENT_BUS_ERROR (1UL << 7) ///< Bus error detected (START/STOP at illegal position)
|
||||
#define ARM_I2C_EVENT_BUS_CLEAR (1UL << 8) ///< Bus clear finished
|
||||
|
||||
|
||||
// Function documentation
|
||||
/**
|
||||
\fn ARM_DRIVER_VERSION ARM_I2C_GetVersion (void)
|
||||
\brief Get driver version.
|
||||
\return \ref ARM_DRIVER_VERSION
|
||||
|
||||
\fn ARM_I2C_CAPABILITIES ARM_I2C_GetCapabilities (void)
|
||||
\brief Get driver capabilities.
|
||||
\return \ref ARM_I2C_CAPABILITIES
|
||||
|
||||
\fn int32_t ARM_I2C_Initialize (ARM_I2C_SignalEvent_t cb_event)
|
||||
\brief Initialize I2C Interface.
|
||||
\param[in] cb_event Pointer to \ref ARM_I2C_SignalEvent
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_I2C_Uninitialize (void)
|
||||
\brief De-initialize I2C Interface.
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_I2C_PowerControl (ARM_POWER_STATE state)
|
||||
\brief Control I2C Interface Power.
|
||||
\param[in] state Power state
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_I2C_MasterTransmit (uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending)
|
||||
\brief Start transmitting data as I2C Master.
|
||||
\param[in] addr Slave address (7-bit or 10-bit)
|
||||
\param[in] data Pointer to buffer with data to transmit to I2C Slave
|
||||
\param[in] num Number of data bytes to transmit
|
||||
\param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_I2C_MasterReceive (uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending)
|
||||
\brief Start receiving data as I2C Master.
|
||||
\param[in] addr Slave address (7-bit or 10-bit)
|
||||
\param[out] data Pointer to buffer for data to receive from I2C Slave
|
||||
\param[in] num Number of data bytes to receive
|
||||
\param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_I2C_SlaveTransmit (const uint8_t *data, uint32_t num)
|
||||
\brief Start transmitting data as I2C Slave.
|
||||
\param[in] data Pointer to buffer with data to transmit to I2C Master
|
||||
\param[in] num Number of data bytes to transmit
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_I2C_SlaveReceive (uint8_t *data, uint32_t num)
|
||||
\brief Start receiving data as I2C Slave.
|
||||
\param[out] data Pointer to buffer for data to receive from I2C Master
|
||||
\param[in] num Number of data bytes to receive
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_I2C_GetDataCount (void)
|
||||
\brief Get transferred data count.
|
||||
\return number of data bytes transferred; -1 when Slave is not addressed by Master
|
||||
|
||||
\fn int32_t ARM_I2C_Control (uint32_t control, uint32_t arg)
|
||||
\brief Control I2C Interface.
|
||||
\param[in] control Operation
|
||||
\param[in] arg Argument of operation (optional)
|
||||
\return \ref execution_status
|
||||
|
||||
\fn ARM_I2C_STATUS ARM_I2C_GetStatus (void)
|
||||
\brief Get I2C status.
|
||||
\return I2C status \ref ARM_I2C_STATUS
|
||||
|
||||
\fn void ARM_I2C_SignalEvent (uint32_t event)
|
||||
\brief Signal I2C Events.
|
||||
\param[in] event \ref I2C_events notification mask
|
||||
*/
|
||||
|
||||
typedef void (*ARM_I2C_SignalEvent_t) (uint32_t event); ///< Pointer to \ref ARM_I2C_SignalEvent : Signal I2C Event.
|
||||
|
||||
|
||||
/**
|
||||
\brief I2C Driver Capabilities.
|
||||
*/
|
||||
typedef struct _ARM_I2C_CAPABILITIES {
|
||||
uint32_t address_10_bit : 1; ///< supports 10-bit addressing
|
||||
uint32_t reserved : 31; ///< Reserved (must be zero)
|
||||
} ARM_I2C_CAPABILITIES;
|
||||
|
||||
|
||||
/**
|
||||
\brief Access structure of the I2C Driver.
|
||||
*/
|
||||
typedef struct _ARM_DRIVER_I2C {
|
||||
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_I2C_GetVersion : Get driver version.
|
||||
ARM_I2C_CAPABILITIES (*GetCapabilities)(void); ///< Pointer to \ref ARM_I2C_GetCapabilities : Get driver capabilities.
|
||||
int32_t (*Initialize) (ARM_I2C_SignalEvent_t cb_event); ///< Pointer to \ref ARM_I2C_Initialize : Initialize I2C Interface.
|
||||
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_I2C_Uninitialize : De-initialize I2C Interface.
|
||||
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_I2C_PowerControl : Control I2C Interface Power.
|
||||
int32_t (*MasterTransmit) (uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending); ///< Pointer to \ref ARM_I2C_MasterTransmit : Start transmitting data as I2C Master.
|
||||
int32_t (*MasterReceive) (uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending); ///< Pointer to \ref ARM_I2C_MasterReceive : Start receiving data as I2C Master.
|
||||
int32_t (*SlaveTransmit) ( const uint8_t *data, uint32_t num); ///< Pointer to \ref ARM_I2C_SlaveTransmit : Start transmitting data as I2C Slave.
|
||||
int32_t (*SlaveReceive) ( uint8_t *data, uint32_t num); ///< Pointer to \ref ARM_I2C_SlaveReceive : Start receiving data as I2C Slave.
|
||||
int32_t (*GetDataCount) (void); ///< Pointer to \ref ARM_I2C_GetDataCount : Get transferred data count.
|
||||
int32_t (*Control) (uint32_t control, uint32_t arg); ///< Pointer to \ref ARM_I2C_Control : Control I2C Interface.
|
||||
ARM_I2C_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_I2C_GetStatus : Get I2C status.
|
||||
} const ARM_DRIVER_I2C;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DRIVER_I2C_H_ */
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 2013-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.
|
||||
*
|
||||
* $Date: 2. Feb 2017
|
||||
* $Revision: V2.2
|
||||
*
|
||||
* Project: SPI (Serial Peripheral Interface) Driver definitions
|
||||
*/
|
||||
|
||||
/* History:
|
||||
* Version 2.2
|
||||
* ARM_SPI_STATUS made volatile
|
||||
* Version 2.1
|
||||
* Renamed status flag "tx_rx_busy" to "busy"
|
||||
* Version 2.0
|
||||
* New simplified driver:
|
||||
* complexity moved to upper layer (especially data handling)
|
||||
* more unified API for different communication interfaces
|
||||
* Added:
|
||||
* Slave Mode
|
||||
* Half-duplex Modes
|
||||
* Configurable number of data bits
|
||||
* Support for TI Mode and Microwire
|
||||
* Changed prefix ARM_DRV -> ARM_DRIVER
|
||||
* Version 1.10
|
||||
* Namespace prefix ARM_ added
|
||||
* Version 1.01
|
||||
* Added "send_done_event" to Capabilities
|
||||
* Version 1.00
|
||||
* Initial release
|
||||
*/
|
||||
|
||||
#ifndef DRIVER_SPI_H_
|
||||
#define DRIVER_SPI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "Driver_Common.h"
|
||||
|
||||
#define ARM_SPI_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,2) /* API version */
|
||||
|
||||
|
||||
/****** SPI Control Codes *****/
|
||||
|
||||
#define ARM_SPI_CONTROL_Pos 0
|
||||
#define ARM_SPI_CONTROL_Msk (0xFFUL << ARM_SPI_CONTROL_Pos)
|
||||
|
||||
/*----- SPI Control Codes: Mode -----*/
|
||||
#define ARM_SPI_MODE_INACTIVE (0x00UL << ARM_SPI_CONTROL_Pos) ///< SPI Inactive
|
||||
#define ARM_SPI_MODE_MASTER (0x01UL << ARM_SPI_CONTROL_Pos) ///< SPI Master (Output on MOSI, Input on MISO); arg = Bus Speed in bps
|
||||
#define ARM_SPI_MODE_SLAVE (0x02UL << ARM_SPI_CONTROL_Pos) ///< SPI Slave (Output on MISO, Input on MOSI)
|
||||
#define ARM_SPI_MODE_MASTER_SIMPLEX (0x03UL << ARM_SPI_CONTROL_Pos) ///< SPI Master (Output/Input on MOSI); arg = Bus Speed in bps
|
||||
#define ARM_SPI_MODE_SLAVE_SIMPLEX (0x04UL << ARM_SPI_CONTROL_Pos) ///< SPI Slave (Output/Input on MISO)
|
||||
|
||||
/*----- SPI Control Codes: Mode Parameters: Frame Format -----*/
|
||||
#define ARM_SPI_FRAME_FORMAT_Pos 8
|
||||
#define ARM_SPI_FRAME_FORMAT_Msk (7UL << ARM_SPI_FRAME_FORMAT_Pos)
|
||||
#define ARM_SPI_CPOL0_CPHA0 (0UL << ARM_SPI_FRAME_FORMAT_Pos) ///< Clock Polarity 0, Clock Phase 0 (default)
|
||||
#define ARM_SPI_CPOL0_CPHA1 (1UL << ARM_SPI_FRAME_FORMAT_Pos) ///< Clock Polarity 0, Clock Phase 1
|
||||
#define ARM_SPI_CPOL1_CPHA0 (2UL << ARM_SPI_FRAME_FORMAT_Pos) ///< Clock Polarity 1, Clock Phase 0
|
||||
#define ARM_SPI_CPOL1_CPHA1 (3UL << ARM_SPI_FRAME_FORMAT_Pos) ///< Clock Polarity 1, Clock Phase 1
|
||||
#define ARM_SPI_TI_SSI (4UL << ARM_SPI_FRAME_FORMAT_Pos) ///< Texas Instruments Frame Format
|
||||
#define ARM_SPI_MICROWIRE (5UL << ARM_SPI_FRAME_FORMAT_Pos) ///< National Microwire Frame Format
|
||||
|
||||
/*----- SPI Control Codes: Mode Parameters: Data Bits -----*/
|
||||
#define ARM_SPI_DATA_BITS_Pos 12
|
||||
#define ARM_SPI_DATA_BITS_Msk (0x3FUL << ARM_SPI_DATA_BITS_Pos)
|
||||
#define ARM_SPI_DATA_BITS(n) (((n) & 0x3F) << ARM_SPI_DATA_BITS_Pos) ///< Number of Data bits
|
||||
|
||||
/*----- SPI Control Codes: Mode Parameters: Bit Order -----*/
|
||||
#define ARM_SPI_BIT_ORDER_Pos 18
|
||||
#define ARM_SPI_BIT_ORDER_Msk (1UL << ARM_SPI_BIT_ORDER_Pos)
|
||||
#define ARM_SPI_MSB_LSB (0UL << ARM_SPI_BIT_ORDER_Pos) ///< SPI Bit order from MSB to LSB (default)
|
||||
#define ARM_SPI_LSB_MSB (1UL << ARM_SPI_BIT_ORDER_Pos) ///< SPI Bit order from LSB to MSB
|
||||
|
||||
/*----- SPI Control Codes: Mode Parameters: Slave Select Mode -----*/
|
||||
#define ARM_SPI_SS_MASTER_MODE_Pos 19
|
||||
#define ARM_SPI_SS_MASTER_MODE_Msk (3UL << ARM_SPI_SS_MASTER_MODE_Pos)
|
||||
#define ARM_SPI_SS_MASTER_UNUSED (0UL << ARM_SPI_SS_MASTER_MODE_Pos) ///< SPI Slave Select when Master: Not used (default)
|
||||
#define ARM_SPI_SS_MASTER_SW (1UL << ARM_SPI_SS_MASTER_MODE_Pos) ///< SPI Slave Select when Master: Software controlled
|
||||
#define ARM_SPI_SS_MASTER_HW_OUTPUT (2UL << ARM_SPI_SS_MASTER_MODE_Pos) ///< SPI Slave Select when Master: Hardware controlled Output
|
||||
#define ARM_SPI_SS_MASTER_HW_INPUT (3UL << ARM_SPI_SS_MASTER_MODE_Pos) ///< SPI Slave Select when Master: Hardware monitored Input
|
||||
#define ARM_SPI_SS_SLAVE_MODE_Pos 21
|
||||
#define ARM_SPI_SS_SLAVE_MODE_Msk (1UL << ARM_SPI_SS_SLAVE_MODE_Pos)
|
||||
#define ARM_SPI_SS_SLAVE_HW (0UL << ARM_SPI_SS_SLAVE_MODE_Pos) ///< SPI Slave Select when Slave: Hardware monitored (default)
|
||||
#define ARM_SPI_SS_SLAVE_SW (1UL << ARM_SPI_SS_SLAVE_MODE_Pos) ///< SPI Slave Select when Slave: Software controlled
|
||||
|
||||
|
||||
/*----- SPI Control Codes: Miscellaneous Controls -----*/
|
||||
#define ARM_SPI_SET_BUS_SPEED (0x10UL << ARM_SPI_CONTROL_Pos) ///< Set Bus Speed in bps; arg = value
|
||||
#define ARM_SPI_GET_BUS_SPEED (0x11UL << ARM_SPI_CONTROL_Pos) ///< Get Bus Speed in bps
|
||||
#define ARM_SPI_SET_DEFAULT_TX_VALUE (0x12UL << ARM_SPI_CONTROL_Pos) ///< Set default Transmit value; arg = value
|
||||
#define ARM_SPI_CONTROL_SS (0x13UL << ARM_SPI_CONTROL_Pos) ///< Control Slave Select; arg: 0=inactive, 1=active
|
||||
#define ARM_SPI_ABORT_TRANSFER (0x14UL << ARM_SPI_CONTROL_Pos) ///< Abort current data transfer
|
||||
|
||||
|
||||
/****** SPI Slave Select Signal definitions *****/
|
||||
#define ARM_SPI_SS_INACTIVE 0 ///< SPI Slave Select Signal Inactive
|
||||
#define ARM_SPI_SS_ACTIVE 1 ///< SPI Slave Select Signal Active
|
||||
|
||||
|
||||
/****** SPI specific error codes *****/
|
||||
#define ARM_SPI_ERROR_MODE (ARM_DRIVER_ERROR_SPECIFIC - 1) ///< Specified Mode not supported
|
||||
#define ARM_SPI_ERROR_FRAME_FORMAT (ARM_DRIVER_ERROR_SPECIFIC - 2) ///< Specified Frame Format not supported
|
||||
#define ARM_SPI_ERROR_DATA_BITS (ARM_DRIVER_ERROR_SPECIFIC - 3) ///< Specified number of Data bits not supported
|
||||
#define ARM_SPI_ERROR_BIT_ORDER (ARM_DRIVER_ERROR_SPECIFIC - 4) ///< Specified Bit order not supported
|
||||
#define ARM_SPI_ERROR_SS_MODE (ARM_DRIVER_ERROR_SPECIFIC - 5) ///< Specified Slave Select Mode not supported
|
||||
|
||||
|
||||
/**
|
||||
\brief SPI Status
|
||||
*/
|
||||
typedef volatile struct _ARM_SPI_STATUS {
|
||||
uint32_t busy : 1; ///< Transmitter/Receiver busy flag
|
||||
uint32_t data_lost : 1; ///< Data lost: Receive overflow / Transmit underflow (cleared on start of transfer operation)
|
||||
uint32_t mode_fault : 1; ///< Mode fault detected; optional (cleared on start of transfer operation)
|
||||
uint32_t reserved : 29;
|
||||
} ARM_SPI_STATUS;
|
||||
|
||||
|
||||
/****** SPI Event *****/
|
||||
#define ARM_SPI_EVENT_TRANSFER_COMPLETE (1UL << 0) ///< Data Transfer completed
|
||||
#define ARM_SPI_EVENT_DATA_LOST (1UL << 1) ///< Data lost: Receive overflow / Transmit underflow
|
||||
#define ARM_SPI_EVENT_MODE_FAULT (1UL << 2) ///< Master Mode Fault (SS deactivated when Master)
|
||||
|
||||
|
||||
// Function documentation
|
||||
/**
|
||||
\fn ARM_DRIVER_VERSION ARM_SPI_GetVersion (void)
|
||||
\brief Get driver version.
|
||||
\return \ref ARM_DRIVER_VERSION
|
||||
|
||||
\fn ARM_SPI_CAPABILITIES ARM_SPI_GetCapabilities (void)
|
||||
\brief Get driver capabilities.
|
||||
\return \ref ARM_SPI_CAPABILITIES
|
||||
|
||||
\fn int32_t ARM_SPI_Initialize (ARM_SPI_SignalEvent_t cb_event)
|
||||
\brief Initialize SPI Interface.
|
||||
\param[in] cb_event Pointer to \ref ARM_SPI_SignalEvent
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_SPI_Uninitialize (void)
|
||||
\brief De-initialize SPI Interface.
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_SPI_PowerControl (ARM_POWER_STATE state)
|
||||
\brief Control SPI Interface Power.
|
||||
\param[in] state Power state
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_SPI_Send (const void *data, uint32_t num)
|
||||
\brief Start sending data to SPI transmitter.
|
||||
\param[in] data Pointer to buffer with data to send to SPI transmitter
|
||||
\param[in] num Number of data items to send
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_SPI_Receive (void *data, uint32_t num)
|
||||
\brief Start receiving data from SPI receiver.
|
||||
\param[out] data Pointer to buffer for data to receive from SPI receiver
|
||||
\param[in] num Number of data items to receive
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_SPI_Transfer (const void *data_out,
|
||||
void *data_in,
|
||||
uint32_t num)
|
||||
\brief Start sending/receiving data to/from SPI transmitter/receiver.
|
||||
\param[in] data_out Pointer to buffer with data to send to SPI transmitter
|
||||
\param[out] data_in Pointer to buffer for data to receive from SPI receiver
|
||||
\param[in] num Number of data items to transfer
|
||||
\return \ref execution_status
|
||||
|
||||
\fn uint32_t ARM_SPI_GetDataCount (void)
|
||||
\brief Get transferred data count.
|
||||
\return number of data items transferred
|
||||
|
||||
\fn int32_t ARM_SPI_Control (uint32_t control, uint32_t arg)
|
||||
\brief Control SPI Interface.
|
||||
\param[in] control Operation
|
||||
\param[in] arg Argument of operation (optional)
|
||||
\return common \ref execution_status and driver specific \ref spi_execution_status
|
||||
|
||||
\fn ARM_SPI_STATUS ARM_SPI_GetStatus (void)
|
||||
\brief Get SPI status.
|
||||
\return SPI status \ref ARM_SPI_STATUS
|
||||
|
||||
\fn void ARM_SPI_SignalEvent (uint32_t event)
|
||||
\brief Signal SPI Events.
|
||||
\param[in] event \ref SPI_events notification mask
|
||||
\return none
|
||||
*/
|
||||
|
||||
typedef void (*ARM_SPI_SignalEvent_t) (uint32_t event); ///< Pointer to \ref ARM_SPI_SignalEvent : Signal SPI Event.
|
||||
|
||||
|
||||
/**
|
||||
\brief SPI Driver Capabilities.
|
||||
*/
|
||||
typedef struct _ARM_SPI_CAPABILITIES {
|
||||
uint32_t simplex : 1; ///< supports Simplex Mode (Master and Slave)
|
||||
uint32_t ti_ssi : 1; ///< supports TI Synchronous Serial Interface
|
||||
uint32_t microwire : 1; ///< supports Microwire Interface
|
||||
uint32_t event_mode_fault : 1; ///< Signal Mode Fault event: \ref ARM_SPI_EVENT_MODE_FAULT
|
||||
uint32_t reserved : 28; ///< Reserved (must be zero)
|
||||
} ARM_SPI_CAPABILITIES;
|
||||
|
||||
|
||||
/**
|
||||
\brief Access structure of the SPI Driver.
|
||||
*/
|
||||
typedef struct _ARM_DRIVER_SPI {
|
||||
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_SPI_GetVersion : Get driver version.
|
||||
ARM_SPI_CAPABILITIES (*GetCapabilities) (void); ///< Pointer to \ref ARM_SPI_GetCapabilities : Get driver capabilities.
|
||||
int32_t (*Initialize) (ARM_SPI_SignalEvent_t cb_event); ///< Pointer to \ref ARM_SPI_Initialize : Initialize SPI Interface.
|
||||
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_SPI_Uninitialize : De-initialize SPI Interface.
|
||||
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_SPI_PowerControl : Control SPI Interface Power.
|
||||
int32_t (*Send) (const void *data, uint32_t num); ///< Pointer to \ref ARM_SPI_Send : Start sending data to SPI Interface.
|
||||
int32_t (*Receive) ( void *data, uint32_t num); ///< Pointer to \ref ARM_SPI_Receive : Start receiving data from SPI Interface.
|
||||
int32_t (*Transfer) (const void *data_out,
|
||||
void *data_in,
|
||||
uint32_t num); ///< Pointer to \ref ARM_SPI_Transfer : Start sending/receiving data to/from SPI.
|
||||
uint32_t (*GetDataCount) (void); ///< Pointer to \ref ARM_SPI_GetDataCount : Get transferred data count.
|
||||
int32_t (*Control) (uint32_t control, uint32_t arg); ///< Pointer to \ref ARM_SPI_Control : Control SPI Interface.
|
||||
ARM_SPI_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_SPI_GetStatus : Get SPI status.
|
||||
} const ARM_DRIVER_SPI;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DRIVER_SPI_H_ */
|
||||
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright (c) 2013-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.
|
||||
*
|
||||
* $Date: 2. Feb 2017
|
||||
* $Revision: V2.3
|
||||
*
|
||||
* Project: USART (Universal Synchronous Asynchronous Receiver Transmitter)
|
||||
* Driver definitions
|
||||
*/
|
||||
|
||||
/* History:
|
||||
* Version 2.3
|
||||
* ARM_USART_STATUS and ARM_USART_MODEM_STATUS made volatile
|
||||
* Version 2.2
|
||||
* Corrected ARM_USART_CPOL_Pos and ARM_USART_CPHA_Pos definitions
|
||||
* Version 2.1
|
||||
* Removed optional argument parameter from Signal Event
|
||||
* Version 2.0
|
||||
* New simplified driver:
|
||||
* complexity moved to upper layer (especially data handling)
|
||||
* more unified API for different communication interfaces
|
||||
* renamed driver UART -> USART (Asynchronous & Synchronous)
|
||||
* Added modes:
|
||||
* Synchronous
|
||||
* Single-wire
|
||||
* IrDA
|
||||
* Smart Card
|
||||
* Changed prefix ARM_DRV -> ARM_DRIVER
|
||||
* Version 1.10
|
||||
* Namespace prefix ARM_ added
|
||||
* Version 1.01
|
||||
* Added events:
|
||||
* ARM_UART_EVENT_TX_EMPTY, ARM_UART_EVENT_RX_TIMEOUT
|
||||
* ARM_UART_EVENT_TX_THRESHOLD, ARM_UART_EVENT_RX_THRESHOLD
|
||||
* Added functions: SetTxThreshold, SetRxThreshold
|
||||
* Added "rx_timeout_event" to capabilities
|
||||
* Version 1.00
|
||||
* Initial release
|
||||
*/
|
||||
|
||||
#ifndef DRIVER_USART_H_
|
||||
#define DRIVER_USART_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "Driver_Common.h"
|
||||
|
||||
#define ARM_USART_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,3) /* API version */
|
||||
|
||||
|
||||
/****** USART Control Codes *****/
|
||||
|
||||
#define ARM_USART_CONTROL_Pos 0
|
||||
#define ARM_USART_CONTROL_Msk (0xFFUL << ARM_USART_CONTROL_Pos)
|
||||
|
||||
/*----- USART Control Codes: Mode -----*/
|
||||
#define ARM_USART_MODE_ASYNCHRONOUS (0x01UL << ARM_USART_CONTROL_Pos) ///< UART (Asynchronous); arg = Baudrate
|
||||
#define ARM_USART_MODE_SYNCHRONOUS_MASTER (0x02UL << ARM_USART_CONTROL_Pos) ///< Synchronous Master (generates clock signal); arg = Baudrate
|
||||
#define ARM_USART_MODE_SYNCHRONOUS_SLAVE (0x03UL << ARM_USART_CONTROL_Pos) ///< Synchronous Slave (external clock signal)
|
||||
#define ARM_USART_MODE_SINGLE_WIRE (0x04UL << ARM_USART_CONTROL_Pos) ///< UART Single-wire (half-duplex); arg = Baudrate
|
||||
#define ARM_USART_MODE_IRDA (0x05UL << ARM_USART_CONTROL_Pos) ///< UART IrDA; arg = Baudrate
|
||||
#define ARM_USART_MODE_SMART_CARD (0x06UL << ARM_USART_CONTROL_Pos) ///< UART Smart Card; arg = Baudrate
|
||||
|
||||
/*----- USART Control Codes: Mode Parameters: Data Bits -----*/
|
||||
#define ARM_USART_DATA_BITS_Pos 8
|
||||
#define ARM_USART_DATA_BITS_Msk (7UL << ARM_USART_DATA_BITS_Pos)
|
||||
#define ARM_USART_DATA_BITS_5 (5UL << ARM_USART_DATA_BITS_Pos) ///< 5 Data bits
|
||||
#define ARM_USART_DATA_BITS_6 (6UL << ARM_USART_DATA_BITS_Pos) ///< 6 Data bit
|
||||
#define ARM_USART_DATA_BITS_7 (7UL << ARM_USART_DATA_BITS_Pos) ///< 7 Data bits
|
||||
#define ARM_USART_DATA_BITS_8 (0UL << ARM_USART_DATA_BITS_Pos) ///< 8 Data bits (default)
|
||||
#define ARM_USART_DATA_BITS_9 (1UL << ARM_USART_DATA_BITS_Pos) ///< 9 Data bits
|
||||
|
||||
/*----- USART Control Codes: Mode Parameters: Parity -----*/
|
||||
#define ARM_USART_PARITY_Pos 12
|
||||
#define ARM_USART_PARITY_Msk (3UL << ARM_USART_PARITY_Pos)
|
||||
#define ARM_USART_PARITY_NONE (0UL << ARM_USART_PARITY_Pos) ///< No Parity (default)
|
||||
#define ARM_USART_PARITY_EVEN (1UL << ARM_USART_PARITY_Pos) ///< Even Parity
|
||||
#define ARM_USART_PARITY_ODD (2UL << ARM_USART_PARITY_Pos) ///< Odd Parity
|
||||
|
||||
/*----- USART Control Codes: Mode Parameters: Stop Bits -----*/
|
||||
#define ARM_USART_STOP_BITS_Pos 14
|
||||
#define ARM_USART_STOP_BITS_Msk (3UL << ARM_USART_STOP_BITS_Pos)
|
||||
#define ARM_USART_STOP_BITS_1 (0UL << ARM_USART_STOP_BITS_Pos) ///< 1 Stop bit (default)
|
||||
#define ARM_USART_STOP_BITS_2 (1UL << ARM_USART_STOP_BITS_Pos) ///< 2 Stop bits
|
||||
#define ARM_USART_STOP_BITS_1_5 (2UL << ARM_USART_STOP_BITS_Pos) ///< 1.5 Stop bits
|
||||
#define ARM_USART_STOP_BITS_0_5 (3UL << ARM_USART_STOP_BITS_Pos) ///< 0.5 Stop bits
|
||||
|
||||
/*----- USART Control Codes: Mode Parameters: Flow Control -----*/
|
||||
#define ARM_USART_FLOW_CONTROL_Pos 16
|
||||
#define ARM_USART_FLOW_CONTROL_Msk (3UL << ARM_USART_FLOW_CONTROL_Pos)
|
||||
#define ARM_USART_FLOW_CONTROL_NONE (0UL << ARM_USART_FLOW_CONTROL_Pos) ///< No Flow Control (default)
|
||||
#define ARM_USART_FLOW_CONTROL_RTS (1UL << ARM_USART_FLOW_CONTROL_Pos) ///< RTS Flow Control
|
||||
#define ARM_USART_FLOW_CONTROL_CTS (2UL << ARM_USART_FLOW_CONTROL_Pos) ///< CTS Flow Control
|
||||
#define ARM_USART_FLOW_CONTROL_RTS_CTS (3UL << ARM_USART_FLOW_CONTROL_Pos) ///< RTS/CTS Flow Control
|
||||
|
||||
/*----- USART Control Codes: Mode Parameters: Clock Polarity (Synchronous mode) -----*/
|
||||
#define ARM_USART_CPOL_Pos 18
|
||||
#define ARM_USART_CPOL_Msk (1UL << ARM_USART_CPOL_Pos)
|
||||
#define ARM_USART_CPOL0 (0UL << ARM_USART_CPOL_Pos) ///< CPOL = 0 (default)
|
||||
#define ARM_USART_CPOL1 (1UL << ARM_USART_CPOL_Pos) ///< CPOL = 1
|
||||
|
||||
/*----- USART Control Codes: Mode Parameters: Clock Phase (Synchronous mode) -----*/
|
||||
#define ARM_USART_CPHA_Pos 19
|
||||
#define ARM_USART_CPHA_Msk (1UL << ARM_USART_CPHA_Pos)
|
||||
#define ARM_USART_CPHA0 (0UL << ARM_USART_CPHA_Pos) ///< CPHA = 0 (default)
|
||||
#define ARM_USART_CPHA1 (1UL << ARM_USART_CPHA_Pos) ///< CPHA = 1
|
||||
|
||||
|
||||
/*----- USART Control Codes: Miscellaneous Controls -----*/
|
||||
#define ARM_USART_SET_DEFAULT_TX_VALUE (0x10UL << ARM_USART_CONTROL_Pos) ///< Set default Transmit value (Synchronous Receive only); arg = value
|
||||
#define ARM_USART_SET_IRDA_PULSE (0x11UL << ARM_USART_CONTROL_Pos) ///< Set IrDA Pulse in ns; arg: 0=3/16 of bit period
|
||||
#define ARM_USART_SET_SMART_CARD_GUARD_TIME (0x12UL << ARM_USART_CONTROL_Pos) ///< Set Smart Card Guard Time; arg = number of bit periods
|
||||
#define ARM_USART_SET_SMART_CARD_CLOCK (0x13UL << ARM_USART_CONTROL_Pos) ///< Set Smart Card Clock in Hz; arg: 0=Clock not generated
|
||||
#define ARM_USART_CONTROL_SMART_CARD_NACK (0x14UL << ARM_USART_CONTROL_Pos) ///< Smart Card NACK generation; arg: 0=disabled, 1=enabled
|
||||
#define ARM_USART_CONTROL_TX (0x15UL << ARM_USART_CONTROL_Pos) ///< Transmitter; arg: 0=disabled, 1=enabled
|
||||
#define ARM_USART_CONTROL_RX (0x16UL << ARM_USART_CONTROL_Pos) ///< Receiver; arg: 0=disabled, 1=enabled
|
||||
#define ARM_USART_CONTROL_BREAK (0x17UL << ARM_USART_CONTROL_Pos) ///< Continuous Break transmission; arg: 0=disabled, 1=enabled
|
||||
#define ARM_USART_ABORT_SEND (0x18UL << ARM_USART_CONTROL_Pos) ///< Abort \ref ARM_USART_Send
|
||||
#define ARM_USART_ABORT_RECEIVE (0x19UL << ARM_USART_CONTROL_Pos) ///< Abort \ref ARM_USART_Receive
|
||||
#define ARM_USART_ABORT_TRANSFER (0x1AUL << ARM_USART_CONTROL_Pos) ///< Abort \ref ARM_USART_Transfer
|
||||
#define ARM_USART_CONTROL_FLUSH_TX (0x1BUL << ARM_USART_CONTROL_Pos) ///< FLUSH TX FIFO
|
||||
#define ARM_USART_CONTROL_PURGE_COMM (0x1CUL << ARM_USART_CONTROL_Pos) ///< Purge communition(clear rx & tx fifo)
|
||||
|
||||
|
||||
/****** USART specific error codes *****/
|
||||
#define ARM_USART_ERROR_MODE (ARM_DRIVER_ERROR_SPECIFIC - 1) ///< Specified Mode not supported
|
||||
#define ARM_USART_ERROR_BAUDRATE (ARM_DRIVER_ERROR_SPECIFIC - 2) ///< Specified baudrate not supported
|
||||
#define ARM_USART_ERROR_DATA_BITS (ARM_DRIVER_ERROR_SPECIFIC - 3) ///< Specified number of Data bits not supported
|
||||
#define ARM_USART_ERROR_PARITY (ARM_DRIVER_ERROR_SPECIFIC - 4) ///< Specified Parity not supported
|
||||
#define ARM_USART_ERROR_STOP_BITS (ARM_DRIVER_ERROR_SPECIFIC - 5) ///< Specified number of Stop bits not supported
|
||||
#define ARM_USART_ERROR_FLOW_CONTROL (ARM_DRIVER_ERROR_SPECIFIC - 6) ///< Specified Flow Control not supported
|
||||
#define ARM_USART_ERROR_CPOL (ARM_DRIVER_ERROR_SPECIFIC - 7) ///< Specified Clock Polarity not supported
|
||||
#define ARM_USART_ERROR_CPHA (ARM_DRIVER_ERROR_SPECIFIC - 8) ///< Specified Clock Phase not supported
|
||||
|
||||
|
||||
/**
|
||||
\brief USART Status
|
||||
*/
|
||||
typedef volatile struct _ARM_USART_STATUS {
|
||||
uint32_t tx_busy : 1; ///< Transmitter busy flag
|
||||
uint32_t rx_busy : 1; ///< Receiver busy flag
|
||||
uint32_t tx_underflow : 1; ///< Transmit data underflow detected (cleared on start of next send operation)
|
||||
uint32_t rx_overflow : 1; ///< Receive data overflow detected (cleared on start of next receive operation)
|
||||
uint32_t rx_break : 1; ///< Break detected on receive (cleared on start of next receive operation)
|
||||
uint32_t rx_framing_error : 1; ///< Framing error detected on receive (cleared on start of next receive operation)
|
||||
uint32_t rx_parity_error : 1; ///< Parity error detected on receive (cleared on start of next receive operation)
|
||||
uint32_t is_send_block : 1; ///< Whether Send API works in blocking way
|
||||
uint32_t reserved : 24;
|
||||
} ARM_USART_STATUS;
|
||||
|
||||
/**
|
||||
\brief USART Modem Control
|
||||
*/
|
||||
typedef enum _ARM_USART_MODEM_CONTROL {
|
||||
ARM_USART_RTS_CLEAR, ///< Deactivate RTS
|
||||
ARM_USART_RTS_SET, ///< Activate RTS
|
||||
ARM_USART_DTR_CLEAR, ///< Deactivate DTR
|
||||
ARM_USART_DTR_SET ///< Activate DTR
|
||||
} ARM_USART_MODEM_CONTROL;
|
||||
|
||||
/**
|
||||
\brief USART Modem Status
|
||||
*/
|
||||
typedef volatile struct _ARM_USART_MODEM_STATUS {
|
||||
uint32_t cts : 1; ///< CTS state: 1=Active, 0=Inactive
|
||||
uint32_t dsr : 1; ///< DSR state: 1=Active, 0=Inactive
|
||||
uint32_t dcd : 1; ///< DCD state: 1=Active, 0=Inactive
|
||||
uint32_t ri : 1; ///< RI state: 1=Active, 0=Inactive
|
||||
uint32_t reserved : 28;
|
||||
} ARM_USART_MODEM_STATUS;
|
||||
|
||||
|
||||
/****** USART Event *****/
|
||||
#define ARM_USART_EVENT_SEND_COMPLETE (1UL << 0) ///< Send completed; however USART may still transmit data
|
||||
#define ARM_USART_EVENT_RECEIVE_COMPLETE (1UL << 1) ///< Receive completed
|
||||
#define ARM_USART_EVENT_TRANSFER_COMPLETE (1UL << 2) ///< Transfer completed
|
||||
#define ARM_USART_EVENT_TX_COMPLETE (1UL << 3) ///< Transmit completed (optional)
|
||||
#define ARM_USART_EVENT_TX_UNDERFLOW (1UL << 4) ///< Transmit data not available (Synchronous Slave)
|
||||
#define ARM_USART_EVENT_RX_OVERFLOW (1UL << 5) ///< Receive data overflow
|
||||
#define ARM_USART_EVENT_RX_TIMEOUT (1UL << 6) ///< Receive character timeout (optional)
|
||||
#define ARM_USART_EVENT_RX_BREAK (1UL << 7) ///< Break detected on receive
|
||||
#define ARM_USART_EVENT_RX_FRAMING_ERROR (1UL << 8) ///< Framing error detected on receive
|
||||
#define ARM_USART_EVENT_RX_PARITY_ERROR (1UL << 9) ///< Parity error detected on receive
|
||||
#define ARM_USART_EVENT_CTS (1UL << 10) ///< CTS state changed (optional)
|
||||
#define ARM_USART_EVENT_DSR (1UL << 11) ///< DSR state changed (optional)
|
||||
#define ARM_USART_EVENT_DCD (1UL << 12) ///< DCD state changed (optional)
|
||||
#define ARM_USART_EVENT_RI (1UL << 13) ///< RI state changed (optional)
|
||||
#define ARM_USART_EVENT_AUTO_BAUDRATE_DONE (1UL << 14) ///< Auto baudrate dection completed
|
||||
|
||||
|
||||
// Function documentation
|
||||
/**
|
||||
\fn ARM_DRIVER_VERSION ARM_USART_GetVersion (void)
|
||||
\brief Get driver version.
|
||||
\return \ref ARM_DRIVER_VERSION
|
||||
|
||||
\fn ARM_USART_CAPABILITIES ARM_USART_GetCapabilities (void)
|
||||
\brief Get driver capabilities
|
||||
\return \ref ARM_USART_CAPABILITIES
|
||||
|
||||
\fn int32_t ARM_USART_Initialize (ARM_USART_SignalEvent_t cb_event)
|
||||
\brief Initialize USART Interface.
|
||||
\param[in] cb_event Pointer to \ref ARM_USART_SignalEvent
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_USART_Uninitialize (void)
|
||||
\brief De-initialize USART Interface.
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_USART_PowerControl (ARM_POWER_STATE state)
|
||||
\brief Control USART Interface Power.
|
||||
\param[in] state Power state
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_USART_Send (const void *data, uint32_t num)
|
||||
\brief Start sending data to USART transmitter.
|
||||
\param[in] data Pointer to buffer with data to send to USART transmitter
|
||||
\param[in] num Number of data items to send
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_USART_Receive (void *data, uint32_t num)
|
||||
\brief Start receiving data from USART receiver.
|
||||
\param[out] data Pointer to buffer for data to receive from USART receiver
|
||||
\param[in] num Number of data items to receive
|
||||
\return \ref execution_status
|
||||
|
||||
\fn int32_t ARM_USART_Transfer (const void *data_out,
|
||||
void *data_in,
|
||||
uint32_t num)
|
||||
\brief Start sending/receiving data to/from USART transmitter/receiver.
|
||||
\param[in] data_out Pointer to buffer with data to send to USART transmitter
|
||||
\param[out] data_in Pointer to buffer for data to receive from USART receiver
|
||||
\param[in] num Number of data items to transfer
|
||||
\return \ref execution_status
|
||||
|
||||
\fn uint32_t ARM_USART_GetTxCount (void)
|
||||
\brief Get transmitted data count.
|
||||
\return number of data items transmitted
|
||||
|
||||
\fn uint32_t ARM_USART_GetRxCount (void)
|
||||
\brief Get received data count.
|
||||
\return number of data items received
|
||||
|
||||
\fn int32_t ARM_USART_Control (uint32_t control, uint32_t arg)
|
||||
\brief Control USART Interface.
|
||||
\param[in] control Operation
|
||||
\param[in] arg Argument of operation (optional)
|
||||
\return common \ref execution_status and driver specific \ref usart_execution_status
|
||||
|
||||
\fn ARM_USART_STATUS ARM_USART_GetStatus (void)
|
||||
\brief Get USART status.
|
||||
\return USART status \ref ARM_USART_STATUS
|
||||
|
||||
\fn int32_t ARM_USART_SetModemControl (ARM_USART_MODEM_CONTROL control)
|
||||
\brief Set USART Modem Control line state.
|
||||
\param[in] control \ref ARM_USART_MODEM_CONTROL
|
||||
\return \ref execution_status
|
||||
|
||||
\fn ARM_USART_MODEM_STATUS ARM_USART_GetModemStatus (void)
|
||||
\brief Get USART Modem Status lines state.
|
||||
\return modem status \ref ARM_USART_MODEM_STATUS
|
||||
|
||||
\fn uint32_t ARM_USART_GetBaudRate (void)
|
||||
\brief Get current baud rate.
|
||||
\return current baud rate
|
||||
|
||||
\fn void ARM_USART_SignalEvent (uint32_t event)
|
||||
\brief Signal USART Events.
|
||||
\param[in] event \ref USART_events notification mask
|
||||
\return none
|
||||
|
||||
\fn int32_t ARM_USART_SendPolling (const void *data, uint32_t num)
|
||||
\brief Start sending data to USART transmitter in polling way.
|
||||
\param[in] data Pointer to buffer with data to send to USART transmitter
|
||||
\param[in] num Number of data items to send
|
||||
\return \ref execution_status
|
||||
*/
|
||||
|
||||
typedef void (*ARM_USART_SignalEvent_t) (uint32_t event); ///< Pointer to \ref ARM_USART_SignalEvent : Signal USART Event.
|
||||
|
||||
|
||||
/**
|
||||
\brief USART Device Driver Capabilities.
|
||||
*/
|
||||
typedef struct _ARM_USART_CAPABILITIES {
|
||||
uint32_t asynchronous : 1; ///< supports UART (Asynchronous) mode
|
||||
uint32_t synchronous_master : 1; ///< supports Synchronous Master mode
|
||||
uint32_t synchronous_slave : 1; ///< supports Synchronous Slave mode
|
||||
uint32_t single_wire : 1; ///< supports UART Single-wire mode
|
||||
uint32_t irda : 1; ///< supports UART IrDA mode
|
||||
uint32_t smart_card : 1; ///< supports UART Smart Card mode
|
||||
uint32_t smart_card_clock : 1; ///< Smart Card Clock generator available
|
||||
uint32_t flow_control_rts : 1; ///< RTS Flow Control available
|
||||
uint32_t flow_control_cts : 1; ///< CTS Flow Control available
|
||||
uint32_t event_tx_complete : 1; ///< Transmit completed event: \ref ARM_USART_EVENT_TX_COMPLETE
|
||||
uint32_t event_rx_timeout : 1; ///< Signal receive character timeout event: \ref ARM_USART_EVENT_RX_TIMEOUT
|
||||
uint32_t rts : 1; ///< RTS Line: 0=not available, 1=available
|
||||
uint32_t cts : 1; ///< CTS Line: 0=not available, 1=available
|
||||
uint32_t dtr : 1; ///< DTR Line: 0=not available, 1=available
|
||||
uint32_t dsr : 1; ///< DSR Line: 0=not available, 1=available
|
||||
uint32_t dcd : 1; ///< DCD Line: 0=not available, 1=available
|
||||
uint32_t ri : 1; ///< RI Line: 0=not available, 1=available
|
||||
uint32_t event_cts : 1; ///< Signal CTS change event: \ref ARM_USART_EVENT_CTS
|
||||
uint32_t event_dsr : 1; ///< Signal DSR change event: \ref ARM_USART_EVENT_DSR
|
||||
uint32_t event_dcd : 1; ///< Signal DCD change event: \ref ARM_USART_EVENT_DCD
|
||||
uint32_t event_ri : 1; ///< Signal RI change event: \ref ARM_USART_EVENT_RI
|
||||
uint32_t reserved : 11; ///< Reserved (must be zero)
|
||||
} ARM_USART_CAPABILITIES;
|
||||
|
||||
|
||||
/**
|
||||
\brief Access structure of the USART Driver.
|
||||
*/
|
||||
typedef struct _ARM_DRIVER_USART {
|
||||
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_USART_GetVersion : Get driver version.
|
||||
ARM_USART_CAPABILITIES (*GetCapabilities) (void); ///< Pointer to \ref ARM_USART_GetCapabilities : Get driver capabilities.
|
||||
int32_t (*Initialize) (ARM_USART_SignalEvent_t cb_event); ///< Pointer to \ref ARM_USART_Initialize : Initialize USART Interface.
|
||||
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_USART_Uninitialize : De-initialize USART Interface.
|
||||
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_USART_PowerControl : Control USART Interface Power.
|
||||
int32_t (*Send) (const void *data, uint32_t num); ///< Pointer to \ref ARM_USART_Send : Start sending data to USART transmitter.
|
||||
int32_t (*Receive) ( void *data, uint32_t num); ///< Pointer to \ref ARM_USART_Receive : Start receiving data from USART receiver.
|
||||
int32_t (*Transfer) (const void *data_out,
|
||||
void *data_in,
|
||||
uint32_t num); ///< Pointer to \ref ARM_USART_Transfer : Start sending/receiving data to/from USART.
|
||||
uint32_t (*GetTxCount) (void); ///< Pointer to \ref ARM_USART_GetTxCount : Get transmitted data count.
|
||||
uint32_t (*GetRxCount) (void); ///< Pointer to \ref ARM_USART_GetRxCount : Get received data count.
|
||||
int32_t (*Control) (uint32_t control, uint32_t arg); ///< Pointer to \ref ARM_USART_Control : Control USART Interface.
|
||||
ARM_USART_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_USART_GetStatus : Get USART status.
|
||||
int32_t (*SetModemControl) (ARM_USART_MODEM_CONTROL control); ///< Pointer to \ref ARM_USART_SetModemControl : Set USART Modem Control line state.
|
||||
ARM_USART_MODEM_STATUS (*GetModemStatus) (void); ///< Pointer to \ref ARM_USART_GetModemStatus : Get USART Modem Status lines state.
|
||||
uint32_t (*GetBaudRate) (void); ///< Pointer to \ref ARM_USART_GetBaudRate : Get current baud rate.
|
||||
int32_t (*SendPolling) (const void *data, uint32_t num); ///< Pointer to \ref ARM_USART_SendPolling : Start sending data to USART transmitter in polling way. <b> This is an extended API not inlcuded in original CMSIS driver version.</b>
|
||||
} const ARM_DRIVER_USART;
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DRIVER_USART_H_ */
|
||||
@@ -0,0 +1,93 @@
|
||||
#ifndef BSP_I2C_H
|
||||
#define BSP_I2C_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
|
||||
|
||||
// I2C Driver state flags
|
||||
#define I2C_FLAG_INIT BIT(0) // Driver initialized
|
||||
#define I2C_FLAG_POWER BIT(1) // Driver power on
|
||||
#define I2C_FLAG_SETUP BIT(2) // Master configured, clock set
|
||||
#define I2C_FLAG_MASTER_TX BIT(3) // Master tx
|
||||
#define I2C_FLAG_MASTER_RX BIT(4) // Master rx
|
||||
#define I2C_FLAG_SLAVE_TX BIT(5) // Slave tx
|
||||
#define I2C_FLAG_SLAVE_RX BIT(6) // Slave rx
|
||||
|
||||
#define I2C_NO_STARTSTOP (0x00000000U)
|
||||
#define I2C_GENERATE_STOP (I2C_SCR_STOP_Msk)
|
||||
#define I2C_GENERATE_START_READ (I2C_SCR_START_Msk | I2C_SCR_TARGET_RWN_Msk)
|
||||
#define I2C_GENERATE_START_WRITE (I2C_SCR_START_Msk)
|
||||
#define I2C_GENERATE_RESTART_READ (I2C_SCR_RESTART_Msk | I2C_SCR_TARGET_RWN_Msk)
|
||||
#define I2C_GENERATE_RESTART_WRITE (I2C_SCR_RESTART_Msk)
|
||||
|
||||
|
||||
#define I2C_MEMADD_SIZE_8BIT (0x00000001U)
|
||||
#define I2C_MEMADD_SIZE_16BIT (0x00000002U)
|
||||
|
||||
#define I2C_AUTOMATIC_MODE1 (0x01) // byte_num_unknown = 0
|
||||
#define I2C_AUTOMATIC_MODE2 (0x02) // byte_num_unknown = 1
|
||||
#define I2C_DEDICATED_MODE (0x03)
|
||||
|
||||
// I2C IRQ
|
||||
typedef const struct _I2C_IRQ {
|
||||
IRQn_Type irq_num; // I2C IRQ Number
|
||||
IRQ_Callback_t cb_irq;
|
||||
} I2C_IRQ;
|
||||
|
||||
// I2C PINS
|
||||
typedef const struct _I2C_PIN {
|
||||
PIN *pin_scl; // SCL Pin identifier
|
||||
PIN *pin_sda; // SDA Pin identifier
|
||||
} I2C_PINS;
|
||||
|
||||
// I2C DMA
|
||||
typedef struct _I2C_DMA {
|
||||
DmaInstance_e tx_instance; // Transmit DMA instance
|
||||
int8_t tx_ch; // Transmit channel number
|
||||
uint8_t tx_req; // Transmit DMA request number
|
||||
void (*tx_callback)(uint32_t event); // Transmit callback
|
||||
DmaInstance_e rx_instance; // Receive DMA instance
|
||||
int8_t rx_ch; // Receive channel number
|
||||
uint8_t rx_req; // Receive DMA request number
|
||||
void (*rx_callback)(uint32_t event); // Receive callback
|
||||
} I2C_DMA;
|
||||
|
||||
|
||||
// I2C Control Information
|
||||
typedef struct {
|
||||
ARM_I2C_SignalEvent_t cb_event; // Event callback
|
||||
ARM_I2C_STATUS status; // Status flags
|
||||
uint8_t flags; // Control and state flags
|
||||
uint8_t sla_rw; // Slave address and RW bit
|
||||
bool pending; // Transfer pending (no STOP)
|
||||
uint8_t stalled; // Stall mode status flags
|
||||
uint8_t con_aa; // I2C slave CON flag
|
||||
uint32_t cnt; // Master transfer count
|
||||
uint8_t *data; // Master data to transfer
|
||||
uint32_t num; // Number of bytes to transfer
|
||||
uint8_t *sdata; // Slave data to transfer
|
||||
uint32_t snum; // Number of bytes to transfer
|
||||
} I2C_CTRL;
|
||||
|
||||
|
||||
// I2C Resources definition
|
||||
typedef struct {
|
||||
I2C_TypeDef *reg; // I2C peripheral register interface
|
||||
I2C_PINS pins; // I2C PINS config
|
||||
I2C_DMA* dma; // I2C DMA configuration
|
||||
I2C_IRQ* irq; // I2C IRQ
|
||||
I2C_CTRL *ctrl; // Run-Time control information
|
||||
} const I2C_RESOURCES;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BSP_I2C_H */
|
||||
@@ -0,0 +1,116 @@
|
||||
#ifndef BSP_LPUSART_H
|
||||
#define BSP_LPUSART_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
|
||||
|
||||
// LPUSART flags
|
||||
#define LPUSART_FLAG_INITIALIZED (1U << 0) // LPUSARTinitialized
|
||||
#define LPUSART_FLAG_POWER_FULL (1U << 1) // LPUSART powered FULL
|
||||
#define LPUSART_FLAG_POWER_LOW (1U << 2) // LPUSART powered LOW
|
||||
#define LPUSART_FLAG_CONFIGURED (1U << 3) // LPUSART configured
|
||||
#define LPUSART_FLAG_TX_ENABLED (1U << 4) // LPUSART TX enabled
|
||||
#define LPUSART_FLAG_RX_ENABLED (1U << 5) // LPUSART RX enabled
|
||||
#define LPUSART_FLAG_SEND_ACTIVE (1U << 6) // LPUSART send active
|
||||
|
||||
#define LPUSART_FLAG_POWER_MSK (LPUSART_FLAG_POWER_LOW | LPUSART_FLAG_POWER_FULL)
|
||||
|
||||
// LPUSART IRQ
|
||||
typedef const struct _LPUSART_IRQ {
|
||||
IRQn_Type irq_num; // LPUSART IRQ Number
|
||||
IRQ_Callback_t cb_irq;
|
||||
} LPUSART_IRQ;
|
||||
|
||||
// LPUSART TX DMA
|
||||
typedef struct _LPUSART_TX_DMA {
|
||||
DmaInstance_e instance; // DMA instance
|
||||
int8_t channel; // Channel number
|
||||
uint8_t request; // DMA request number
|
||||
void (*callback)(uint32_t event); // Tx callback
|
||||
} LPUSART_TX_DMA;
|
||||
|
||||
// LPUSART RX DMA
|
||||
typedef struct _LPUSART_RX_DMA {
|
||||
DmaInstance_e instance; // DMA instance
|
||||
int8_t channel; // Channel number
|
||||
uint8_t request; // DMA request number
|
||||
DmaDescriptor_t *descriptor; // Rx descriptor
|
||||
void (*callback)(uint32_t event); // Rx callback
|
||||
} LPUSART_RX_DMA;
|
||||
|
||||
// LPUSART PINS
|
||||
typedef const struct _LPUSART_PIN {
|
||||
const PIN *pin_tx; // TX Pin identifier
|
||||
const PIN *pin_rx; // RX Pin identifier
|
||||
const PIN *pin_cts; // CTS Pin identifier
|
||||
const PIN *pin_rts; // RTS Pin identifier
|
||||
} LPUSART_PINS;
|
||||
|
||||
|
||||
typedef struct _LPUSART_TRANSFER_INFO {
|
||||
uint32_t rx_num; // Total number of receive data
|
||||
uint32_t tx_num; // Total number of transmit data
|
||||
uint8_t *rx_buf; // Pointer to in data buffer
|
||||
uint8_t *tx_buf; // Pointer to out data buffer
|
||||
uint32_t rx_cnt; // Number of data received
|
||||
uint32_t tx_cnt; // Number of data sent
|
||||
uint16_t tx_def_val; // Default transmit value
|
||||
uint16_t rx_dump_val; // Receive dump value
|
||||
uint8_t send_active; // Send active flag
|
||||
uint32_t sync_mode; // Synchronous mode flag
|
||||
} LPUSART_TRANSFER_INFO;
|
||||
|
||||
typedef struct _LPUSART_STATUS {
|
||||
uint8_t rx_busy; // Receiver busy flag
|
||||
uint8_t rx_dma_triggered; // Receive DMA transfer triggered (cleared on start of next receive operation)
|
||||
uint8_t rx_overflow; // Receive data overflow detected (cleared on start of next receive operation)
|
||||
uint8_t aon_rx_overflow; // AON FIFO receive data overflow detected (cleared on start of next receive operation)
|
||||
uint8_t rx_break; // Break detected on receive (cleared on start of next receive operation)
|
||||
uint8_t rx_framing_error; // Framing error detected on receive (cleared on start of next receive operation)
|
||||
uint8_t rx_parity_error; // Parity error detected on receive (cleared on start of next receive operation)
|
||||
} LPUSART_STATUS;
|
||||
|
||||
typedef struct _LPUSART_INFO {
|
||||
ARM_USART_SignalEvent_t cb_event; // Event Callback
|
||||
LPUSART_STATUS rx_status; // Recieve Status flags
|
||||
LPUSART_TRANSFER_INFO xfer; // LPUSART transfer information
|
||||
uint8_t flags; // Current LPUSART flags
|
||||
uint32_t frame_code; // Current LPUSART frame setting code
|
||||
uint32_t baudrate; // Baudrate
|
||||
} LPUSART_INFO;
|
||||
|
||||
// LPUSART Resources definition
|
||||
typedef const struct {
|
||||
USART_TypeDef *co_usart_regs; // LPUSART cooperating uart registers pointer
|
||||
LPUSARTAON_TypeDef *aon_regs; // LPUSART AON part registers pointer
|
||||
LPUSARTCORE_TypeDef *core_regs; // LPUSART CORE part registers pointer
|
||||
LPUSART_PINS pins; // LPUSART PINS config
|
||||
LPUSART_RX_DMA *dma_rx; // LPUSART DMA register interface
|
||||
LPUSART_TX_DMA *co_usart_dma_tx; // LPUSART DMA register interface
|
||||
LPUSART_RX_DMA *co_usart_dma_rx; // LPUSART DMA register interface
|
||||
LPUSART_IRQ *irq; // LPUSART IRQ
|
||||
LPUSART_IRQ *co_usart_irq; // LPUSART cooperating uart IRQ
|
||||
LPUSART_INFO *info; // Run-Time Information
|
||||
} LPUSART_RESOURCES;
|
||||
|
||||
|
||||
void LPUSART_ClearStopFlag(void);
|
||||
void LPUSART_SetStopFlag(void);
|
||||
/*
|
||||
* Check whether rx is ongoing, return true if rx is ongoing at this moment, otherwise false
|
||||
*/
|
||||
bool LPUSART_IsRxActive(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BSP_LPLPUSART_H */
|
||||
@@ -0,0 +1,89 @@
|
||||
#ifndef BSP_SPI_H
|
||||
#define BSP_SPI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
|
||||
|
||||
// SPI flags
|
||||
#define SPI_FLAG_INITIALIZED (1UL << 0) // SPI initialized
|
||||
#define SPI_FLAG_POWERED (1UL << 1) // SPI powered on
|
||||
#define SPI_FLAG_CONFIGURED (1UL << 2) // SPI configured
|
||||
#define SPI_FLAG_DATA_LOST (1UL << 3) // SPI data lost occurred
|
||||
#define SPI_FLAG_MODE_FAULT (1UL << 4) // SPI mode fault occurred
|
||||
|
||||
// SPI IRQ
|
||||
typedef const struct _SPI_IRQ {
|
||||
IRQn_Type irq_num; // SPI IRQ Number
|
||||
IRQ_Callback_t cb_irq;
|
||||
} SPI_IRQ;
|
||||
|
||||
// SPI DMA
|
||||
typedef struct _SPI_DMA {
|
||||
DmaInstance_e tx_instance; // Transmit DMA instance number
|
||||
int8_t tx_ch; // Transmit channel number
|
||||
uint8_t tx_req; // Transmit DMA request number
|
||||
void (*tx_callback)(uint32_t event); // Transmit callback
|
||||
DmaInstance_e rx_instance; // Receive DMA instance number
|
||||
int8_t rx_ch; // Receive channel number
|
||||
uint8_t rx_req; // Receive DMA request number
|
||||
void (*rx_callback)(uint32_t event); // Receive callback
|
||||
} SPI_DMA;
|
||||
|
||||
// SPI PINS
|
||||
typedef const struct _SPI_PIN {
|
||||
const PIN *pin_sclk; // SCLK Pin identifier
|
||||
const PIN *pin_ssn; // SSn Pin identifier
|
||||
const PIN *pin_mosi; // MOSI Pin identifier
|
||||
const PIN *pin_miso; // MISO Pin identifier
|
||||
} SPI_PINS;
|
||||
|
||||
typedef struct _SPI_STATUS {
|
||||
uint8_t busy; // Transmitter/Receiver busy flag
|
||||
uint8_t data_lost; // Data lost: Receive overflow / Transmit underflow (cleared on start of transfer operation)
|
||||
uint8_t mode_fault; // Mode fault detected; optional (cleared on start of transfer operation)
|
||||
} SPI_STATUS;
|
||||
|
||||
// SPI Transfer Information (Run-Time)
|
||||
typedef struct _SPI_TRANSFER_INFO {
|
||||
uint32_t num; // Total number of transfers
|
||||
uint8_t *rx_buf; // Pointer to in data buffer
|
||||
uint8_t *tx_buf; // Pointer to out data buffer
|
||||
uint32_t rx_cnt; // Number of data received
|
||||
uint32_t tx_cnt; // Number of data sent
|
||||
uint32_t dump_val; // Variable for dumping DMA data
|
||||
uint16_t def_val; // Default transfer value
|
||||
} SPI_TRANSFER_INFO;
|
||||
|
||||
// SPI information (Run-time)
|
||||
typedef struct _SPI_INFO {
|
||||
ARM_SPI_SignalEvent_t cb_event; // event callback
|
||||
SPI_STATUS status; // SPI status flags
|
||||
SPI_TRANSFER_INFO xfer; // SPI transfer information
|
||||
uint8_t flags; // SPI driver flags
|
||||
uint32_t mode; // SPI mode
|
||||
uint32_t bus_speed; // SPI bus speed
|
||||
uint8_t data_width; // SPI data bits select in unit of byte
|
||||
} SPI_INFO;
|
||||
|
||||
|
||||
// SPI Resources definition
|
||||
typedef struct {
|
||||
SPI_TypeDef *reg; // SPI register pointer
|
||||
SPI_PINS pins; // SPI PINS configuration
|
||||
SPI_DMA *dma; // SPI DMA configuration pointer
|
||||
SPI_IRQ *irq; // SPI IRQ configuration pointer
|
||||
SPI_INFO *info; // Run-Time Information
|
||||
} SPI_RESOURCES;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BSP_SPI_H */
|
||||
@@ -0,0 +1,108 @@
|
||||
#ifndef BSP_USART_H
|
||||
#define BSP_USART_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
|
||||
|
||||
// USART flags
|
||||
#define USART_FLAG_INITIALIZED (1U << 0) // USARTinitialized
|
||||
#define USART_FLAG_POWERED (1U << 1) // USART powered on
|
||||
#define USART_FLAG_CONFIGURED (1U << 2) // USART configured
|
||||
#define USART_FLAG_TX_ENABLED (1U << 3) // USART TX enabled
|
||||
#define USART_FLAG_RX_ENABLED (1U << 4) // USART RX enabled
|
||||
#define USART_FLAG_SEND_ACTIVE (1U << 5) // USART send active
|
||||
|
||||
#define USART_TFE_INT (0x2<<USART_IIR_INT_ID_Pos)
|
||||
#define USART_RDA_INT (0x4<<USART_IIR_INT_ID_Pos)
|
||||
#define USART_RLS_INT (0x6<<USART_IIR_INT_ID_Pos)
|
||||
#define USART_CTI_INT (0xC<<USART_IIR_INT_ID_Pos)
|
||||
#define USART_INT_TYPE_MSK (0xF<<USART_IIR_INT_ID_Pos)
|
||||
|
||||
// USART IRQ
|
||||
typedef const struct _USART_IRQ {
|
||||
IRQn_Type irq_num; // USART IRQ Number
|
||||
IRQ_Callback_t cb_irq;
|
||||
} USART_IRQ;
|
||||
|
||||
// USART TX DMA
|
||||
typedef struct _USART_TX_DMA {
|
||||
DmaInstance_e instance; // DMA instance
|
||||
int8_t channel; // Channel number
|
||||
uint8_t request; // DMA request number
|
||||
void (*callback)(uint32_t event); // Tx callback
|
||||
} USART_TX_DMA;
|
||||
|
||||
// USART RX DMA
|
||||
typedef struct _USART_RX_DMA {
|
||||
DmaInstance_e instance; // DMA instance
|
||||
int8_t channel; // Channel number
|
||||
uint8_t request; // DMA request number
|
||||
DmaDescriptor_t *descriptor; // Rx descriptor
|
||||
void (*callback)(uint32_t event); // Rx callback
|
||||
} USART_RX_DMA;
|
||||
|
||||
// USART PINS
|
||||
typedef const struct _USART_PIN {
|
||||
const PIN *pin_tx; // TX Pin identifier
|
||||
const PIN *pin_rx; // RX Pin identifier
|
||||
const PIN *pin_cts; // CTS Pin identifier
|
||||
const PIN *pin_rts; // RTS Pin identifier
|
||||
} USART_PINS;
|
||||
|
||||
|
||||
typedef struct _USART_TRANSFER_INFO {
|
||||
uint32_t rx_num; // Total number of receive data
|
||||
uint32_t tx_num; // Total number of transmit data
|
||||
uint8_t *rx_buf; // Pointer to in data buffer
|
||||
uint8_t *tx_buf; // Pointer to out data buffer
|
||||
uint32_t rx_cnt; // Number of data received
|
||||
uint32_t tx_cnt; // Number of data sent
|
||||
uint16_t tx_def_val; // Default transmit value
|
||||
uint16_t rx_dump_val; // Receive dump value
|
||||
uint8_t send_active; // Send active flag
|
||||
uint32_t sync_mode; // Synchronous mode flag
|
||||
} USART_TRANSFER_INFO;
|
||||
|
||||
typedef struct _USART_STATUS {
|
||||
uint8_t rx_busy; // Receiver busy flag
|
||||
uint8_t rx_dma_triggered; // Receive DMA transfer triggered (cleared on start of next receive operation)
|
||||
uint8_t rx_overflow; // Receive data overflow detected (cleared on start of next receive operation)
|
||||
uint8_t rx_break; // Break detected on receive (cleared on start of next receive operation)
|
||||
uint8_t rx_framing_error; // Framing error detected on receive (cleared on start of next receive operation)
|
||||
uint8_t rx_parity_error; // Parity error detected on receive (cleared on start of next receive operation)
|
||||
} USART_STATUS;
|
||||
|
||||
typedef struct _USART_INFO {
|
||||
ARM_USART_SignalEvent_t cb_event; // Event Callback
|
||||
USART_STATUS rx_status; // Recieve Status flags
|
||||
USART_TRANSFER_INFO xfer; // USART transfer information
|
||||
uint8_t flags; // Current USART flags
|
||||
uint32_t frame_code; // Current USART frame setting code
|
||||
uint32_t baudrate; // Baudrate
|
||||
} USART_INFO;
|
||||
|
||||
// USART Resources definition
|
||||
typedef const struct {
|
||||
USART_TypeDef *reg; // USART peripheral pointer
|
||||
USART_PINS pins; // USART PINS config
|
||||
USART_TX_DMA *dma_tx; // USART DMA register interface
|
||||
USART_RX_DMA *dma_rx; // USART DMA register interface
|
||||
USART_IRQ *usart_irq; // USART IRQ
|
||||
uint32_t tx_fifo_trig_lvl; // USART TX FIFO trigger level
|
||||
uint32_t rx_fifo_trig_lvl; // USART RX FIFO trigger level
|
||||
USART_INFO *info; // Run-Time Information
|
||||
uint8_t is_unilog_mode; // Act as unilog output
|
||||
} USART_RESOURCES;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BSP_USART_H */
|
||||
@@ -0,0 +1,463 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
|
||||
* File name: adc.c
|
||||
* Description: EC618 adc driver source file
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "adc.h"
|
||||
#include "ic.h"
|
||||
#include "slpman.h"
|
||||
#include "ec618.h"
|
||||
#include "alarm.h"
|
||||
|
||||
#define LDO_AIO_CTRL_REG_ADDR (0x4D020180)
|
||||
|
||||
#define ADC_ENABLE() do \
|
||||
{ \
|
||||
ADC->CTRL |= ADC_CTRL_LDO_EN_Msk; \
|
||||
*(uint32_t*)(LDO_AIO_CTRL_REG_ADDR) = 1; \
|
||||
while((*(uint32_t*)(LDO_AIO_CTRL_REG_ADDR)) == 0); \
|
||||
} while(0)
|
||||
|
||||
#define ADC_DISABLE() do \
|
||||
{ \
|
||||
ADC->CTRL &= ~ADC_CTRL_LDO_EN_Msk; \
|
||||
*(uint32_t*)(LDO_AIO_CTRL_REG_ADDR) = 0; \
|
||||
while((*(uint32_t*)(LDO_AIO_CTRL_REG_ADDR)) == 1); \
|
||||
} while(0)
|
||||
|
||||
#define ADC_CHANNEL_NUMBER (6)
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
#define LOCK_SLEEP() do \
|
||||
{ \
|
||||
slpManDrvVoteSleep(SLP_VOTE_ADC, SLP_ACTIVE_STATE); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define UNLOCK_SLEEP() do \
|
||||
{ \
|
||||
slpManDrvVoteSleep(SLP_VOTE_ADC, SLP_SLP1_STATE); \
|
||||
} \
|
||||
while(0)
|
||||
#endif
|
||||
|
||||
#define ADC_DEFAULT_CLOCK_DIVIDER (ADC_CLOCK_DIV_8)
|
||||
|
||||
#define ADC_CHANNEL_ENABLE_BIT_POSITION (ADC_AIOCFG_THM_EN_Pos)
|
||||
|
||||
/**
|
||||
\brief size of ADC request queue, value shall be integer power of 2 for fast calcualtion of MOD.
|
||||
\note The valid number of requests is (this_macro_value - 1)
|
||||
*/
|
||||
#define ADC_REQUEST_QUEUE_SIZE (8)
|
||||
#define ADC_REQUEST_QUEUE_SIZE_MASK (ADC_REQUEST_QUEUE_SIZE - 1)
|
||||
|
||||
/**
|
||||
\brief ADC conversion request queue typedef
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t requestArray[ADC_REQUEST_QUEUE_SIZE];
|
||||
uint32_t head;
|
||||
uint32_t tail;
|
||||
} AdcReqeustQueue_t;
|
||||
|
||||
static AdcReqeustQueue_t gAdcRequestqueue;
|
||||
|
||||
/**
|
||||
\brief variable for keeping track the index of current request bitmap, see below bitmap layout
|
||||
*/
|
||||
static volatile uint32_t gCurrentRequestIndex;
|
||||
|
||||
/** \brief Internal used data structure */
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t AIOCFG; /**< AIO configuration Register */
|
||||
uint32_t CFG; /**< ADC configuration Register */
|
||||
} configRegisters;
|
||||
|
||||
adcCallback_t eventCallback; /**< Callback function passed in by application */
|
||||
} AdcChannelDatabase_t;
|
||||
|
||||
/**
|
||||
****************************** Bitmap layout *****************************
|
||||
*
|
||||
* 18 17 15 14 12 11 9 8 6 5 3 2 0
|
||||
*+-----------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*| VREF OUT | CH AIO1 | CH AIO2 | CH AIO3 | CH AIO4 | CH Vbat | CH thermal|
|
||||
*+-----------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* / \
|
||||
* / \
|
||||
* / \
|
||||
* |APP | PLAT | PHY|
|
||||
*/
|
||||
#define CHANNEL_ID_TO_INDEX(channel, userID) ((userID & 0x3U) + (channel & 0x7U) * 3U)
|
||||
|
||||
#define ADC_MAX_LOGIC_CHANNELS (ADC_CHANNEL_NUMBER * ADC_USER_MAX)
|
||||
|
||||
/** \brief Internal used data structure */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t channelConfigValidBitMap; /**< Bitmap of channel configuration valid flag */
|
||||
AdcChannelDatabase_t channelDataBase[ADC_MAX_LOGIC_CHANNELS]; /**< Array of channel database, each element represents one configuration */
|
||||
} AdcDatabase_t;
|
||||
|
||||
static AdcDatabase_t g_adcDataBase = {0};
|
||||
void delay_us(uint32_t us);
|
||||
|
||||
static void ADC_requestQueueInit(void)
|
||||
{
|
||||
gAdcRequestqueue.head = 0;
|
||||
gAdcRequestqueue.tail = 0;
|
||||
gCurrentRequestIndex = ADC_MAX_LOGIC_CHANNELS;
|
||||
}
|
||||
|
||||
// no need to perform atomic access since this function is called only in ISR
|
||||
static int32_t ADC_requestQueueRead(uint32_t *request)
|
||||
{
|
||||
if(gAdcRequestqueue.tail == gAdcRequestqueue.head)
|
||||
{
|
||||
// queue is empty
|
||||
return -1;
|
||||
}
|
||||
|
||||
*request = gAdcRequestqueue.requestArray[gAdcRequestqueue.head];
|
||||
gAdcRequestqueue.head = (gAdcRequestqueue.head + 1) & ADC_REQUEST_QUEUE_SIZE_MASK;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int32_t ADC_requestQueueWrite(uint32_t *request)
|
||||
{
|
||||
uint32_t mask;
|
||||
|
||||
mask = SaveAndSetIRQMask();
|
||||
if(((gAdcRequestqueue.tail + 1) & ADC_REQUEST_QUEUE_SIZE_MASK) == gAdcRequestqueue.head)
|
||||
{
|
||||
// queue is full
|
||||
RestoreIRQMask(mask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
gAdcRequestqueue.requestArray[gAdcRequestqueue.tail] = *request;
|
||||
gAdcRequestqueue.tail = (gAdcRequestqueue.tail + 1) & ADC_REQUEST_QUEUE_SIZE_MASK;
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ADC_loadConfigAndStartConversion(uint32_t requestIndex)
|
||||
{
|
||||
uint32_t aiocfg;
|
||||
// clear status first
|
||||
// LDO has been enabled during initialization phase, here we shall keep this bit set
|
||||
ADC->CTRL = ADC_CTRL_LDO_EN_Msk | ADC_CTRL_EN_Msk;
|
||||
|
||||
// Protect VREF2AIO1 control bit, take care not to overwrite!!!
|
||||
aiocfg = (ADC->AIOCFG & ADC_AIOCFG_VREF2AIO1_EN_Msk) | g_adcDataBase.channelDataBase[requestIndex].configRegisters.AIOCFG;
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
// thermmal comparator close when sample thm channel
|
||||
if(aiocfg & ADC_AIOCFG_THM_EN_Msk)
|
||||
{
|
||||
alarmThmDisableInAdc();
|
||||
}
|
||||
#endif
|
||||
// Protect VREF2AIO1 control bit, take care not to overwrite!!!
|
||||
ADC->AIOCFG = aiocfg;
|
||||
ADC->CFG = g_adcDataBase.channelDataBase[requestIndex].configRegisters.CFG;
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
// thermal channel closed
|
||||
if((ADC->AIOCFG & ADC_AIOCFG_THM_EN_Msk) == 0)
|
||||
{
|
||||
if(alarmThmEnableInAdc() == false)
|
||||
{
|
||||
delay_us(10);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
delay_us(10);
|
||||
|
||||
// start conversion
|
||||
ADC->CTRL = (ADC_CTRL_LDO_EN_Msk | ADC_CTRL_EN_Msk | ADC_CTRL_RSTN_Msk);
|
||||
}
|
||||
|
||||
|
||||
static void ADC_interruptHandler(void)
|
||||
{
|
||||
uint32_t requestIndex;
|
||||
|
||||
int32_t ret;
|
||||
|
||||
ADC->AIOCFG &= ~(ADC_AIOCFG_THM_EN_Msk | ADC_AIOCFG_BATSENS_EN_Msk | ADC_AIOCFG_AIO4_EN_Msk |
|
||||
ADC_AIOCFG_AIO3_EN_Msk | ADC_AIOCFG_AIO2_EN_Msk | ADC_AIOCFG_AIO1_EN_Msk |
|
||||
ADC_AIOCFG_AIO4_NO_DIVR_EN_Msk | ADC_AIOCFG_AIO3_NO_DIVR_EN_Msk |
|
||||
ADC_AIOCFG_AIO2_NO_DIVR_EN_Msk | ADC_AIOCFG_AIO1_NO_DIVR_EN_Msk);
|
||||
|
||||
if(g_adcDataBase.channelDataBase[gCurrentRequestIndex].eventCallback != NULL)
|
||||
{
|
||||
g_adcDataBase.channelDataBase[gCurrentRequestIndex].eventCallback(ADC->RESULT);
|
||||
}
|
||||
|
||||
// Shall check config validation here since config could be changed in user callback(Deinit is called)
|
||||
/*
|
||||
R1 R2 R1 (3 request at once) R1 deInit R2 deInit (validBitMap change to 0 and ADC is disabled)
|
||||
APP ------------------------------------\ /--------------\ /------------\
|
||||
| | | | x
|
||||
v | v | x
|
||||
--------- --------- xxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
ADC ISR R1 R2 R1 is still in queue, stuck here(interrupt never occurs)
|
||||
*/
|
||||
|
||||
|
||||
if(g_adcDataBase.channelConfigValidBitMap != 0)
|
||||
{
|
||||
ret = ADC_requestQueueRead(&requestIndex);
|
||||
|
||||
// Start next round conversion
|
||||
if(ret == 0)
|
||||
{
|
||||
// there is pending request
|
||||
gCurrentRequestIndex = requestIndex;
|
||||
|
||||
ADC_loadConfigAndStartConversion(gCurrentRequestIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentRequestIndex = ADC_MAX_LOGIC_CHANNELS;
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
alarmThmEnableInAdc();
|
||||
UNLOCK_SLEEP();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ADC_requestQueueInit();
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
alarmThmEnableInAdc();
|
||||
UNLOCK_SLEEP();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ADC_getDefaultConfig(AdcConfig_t *config)
|
||||
{
|
||||
ASSERT(config);
|
||||
|
||||
config->clockDivider = ADC_DEFAULT_CLOCK_DIVIDER;
|
||||
config->channelConfig.aioResDiv = ADC_AIO_RESDIV_BYPASS;
|
||||
}
|
||||
|
||||
int32_t ADC_channelInit(AdcChannel_e channel, AdcUser_t userID, const AdcConfig_t *config, adcCallback_t callback)
|
||||
{
|
||||
uint32_t mask, configValue, requestIndex;
|
||||
|
||||
configValue = 0;
|
||||
|
||||
requestIndex = CHANNEL_ID_TO_INDEX(channel, userID);
|
||||
|
||||
if(requestIndex >= ADC_MAX_LOGIC_CHANNELS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
mask = SaveAndSetIRQMask();
|
||||
|
||||
// AIO1 conflict check
|
||||
if((channel == ADC_CHANNEL_AIO1) && ((g_adcDataBase.channelConfigValidBitMap & (1 << ADC_MAX_LOGIC_CHANNELS)) != 0))
|
||||
{
|
||||
RestoreIRQMask(mask);
|
||||
return -2;
|
||||
}
|
||||
|
||||
// First Initialization
|
||||
if(g_adcDataBase.channelConfigValidBitMap == 0)
|
||||
{
|
||||
// enable ADC
|
||||
ADC_ENABLE();
|
||||
XIC_SetVector(PXIC1_AUXADC_IRQn, ADC_interruptHandler);
|
||||
XIC_EnableIRQ(PXIC1_AUXADC_IRQn);
|
||||
ADC_requestQueueInit();
|
||||
}
|
||||
g_adcDataBase.channelConfigValidBitMap |= ( 1 << requestIndex);
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
configValue |= ( EIGEN_VAL2FLD(ADC_CFG_WAIT_CTRL, 1) | \
|
||||
EIGEN_VAL2FLD(ADC_CFG_OFFSET_CTRL, 5) | \
|
||||
EIGEN_VAL2FLD(ADC_CFG_SAMPLE_AVG, 0) | \
|
||||
EIGEN_VAL2FLD(ADC_CFG_CLKIN_DIV, config ? config->clockDivider : ADC_DEFAULT_CLOCK_DIVIDER) | \
|
||||
EIGEN_VAL2FLD(ADC_CFG_VREF_BS, 1) | \
|
||||
EIGEN_VAL2FLD(ADC_CFG_VREF_SEL, 4) | \
|
||||
EIGEN_VAL2FLD(ADC_CFG_LDO_SEL, 4) | \
|
||||
EIGEN_VAL2FLD(ADC_CFG_IBIAS_SEL, 1)
|
||||
);
|
||||
g_adcDataBase.channelDataBase[requestIndex].configRegisters.CFG = configValue;
|
||||
|
||||
configValue = 0;
|
||||
|
||||
switch(channel)
|
||||
{
|
||||
case ADC_CHANNEL_THERMAL:
|
||||
configValue = 1 << (channel + ADC_CHANNEL_ENABLE_BIT_POSITION) | EIGEN_VAL2FLD(ADC_AIOCFG_THM_SEL, 2);
|
||||
break;
|
||||
|
||||
case ADC_CHANNEL_VBAT:
|
||||
configValue = (1 << (channel + ADC_CHANNEL_ENABLE_BIT_POSITION)) | EIGEN_VAL2FLD(ADC_AIOCFG_VBATSEN_RDIV, config->channelConfig.vbatResDiv);
|
||||
break;
|
||||
|
||||
case ADC_CHANNEL_AIO1:
|
||||
case ADC_CHANNEL_AIO2:
|
||||
case ADC_CHANNEL_AIO3:
|
||||
case ADC_CHANNEL_AIO4:
|
||||
|
||||
if(config->channelConfig.aioResDiv == ADC_AIO_RESDIV_BYPASS)
|
||||
{
|
||||
configValue = 1 << (channel + ADC_CHANNEL_ENABLE_BIT_POSITION + 4);
|
||||
}
|
||||
else if(config->channelConfig.aioResDiv < ADC_AIO_RESDIV_RATIO_8OVER16)
|
||||
{
|
||||
configValue = (1 << (channel + ADC_CHANNEL_ENABLE_BIT_POSITION)) | ADC_AIOCFG_RDIV_BYP_Msk | EIGEN_VAL2FLD(ADC_AIOCFG_RDIV, config->channelConfig.aioResDiv);
|
||||
}
|
||||
else
|
||||
{
|
||||
configValue = (1 << (channel + ADC_CHANNEL_ENABLE_BIT_POSITION)) | (EIGEN_VAL2FLD(ADC_AIOCFG_RDIV, (config->channelConfig.aioResDiv - ADC_AIO_RESDIV_RATIO_8OVER16)));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_adcDataBase.channelDataBase[requestIndex].configRegisters.AIOCFG = configValue;
|
||||
g_adcDataBase.channelDataBase[requestIndex].eventCallback = callback;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ADC_channelDeInit(AdcChannel_e channel, AdcUser_t userID)
|
||||
{
|
||||
uint32_t mask = SaveAndSetIRQMask();
|
||||
|
||||
g_adcDataBase.channelConfigValidBitMap &= ~(1 << CHANNEL_ID_TO_INDEX(channel, userID));
|
||||
|
||||
if(g_adcDataBase.channelConfigValidBitMap == 0)
|
||||
{
|
||||
// diable ADC
|
||||
ADC->CTRL = ADC->CTRL & ADC_CTRL_LDO_EN_Msk;
|
||||
// disable clock
|
||||
ADC_DISABLE();
|
||||
XIC_DisableIRQ(PXIC1_AUXADC_IRQn);
|
||||
}
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
}
|
||||
|
||||
int32_t ADC_startConversion(AdcChannel_e channel, AdcUser_t userID)
|
||||
{
|
||||
uint32_t mask, requestIndex;
|
||||
int32_t ret;
|
||||
|
||||
requestIndex = CHANNEL_ID_TO_INDEX(channel, userID);
|
||||
|
||||
ASSERT(requestIndex < ADC_MAX_LOGIC_CHANNELS);
|
||||
|
||||
mask = SaveAndSetIRQMask();
|
||||
|
||||
// validation check
|
||||
if((g_adcDataBase.channelConfigValidBitMap & (1 << requestIndex)) == 0)
|
||||
{
|
||||
RestoreIRQMask(mask);
|
||||
return -2;
|
||||
}
|
||||
|
||||
// A conversion is ongoing, pending the request
|
||||
if(gCurrentRequestIndex != ADC_MAX_LOGIC_CHANNELS)
|
||||
{
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
ret = ADC_requestQueueWrite(&requestIndex);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
// request queue is full
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentRequestIndex = requestIndex;
|
||||
ADC_loadConfigAndStartConversion(gCurrentRequestIndex);
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
LOCK_SLEEP();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int32_t ADC_enableVrefOutput(void)
|
||||
{
|
||||
uint32_t mask = SaveAndSetIRQMask();
|
||||
|
||||
// AIO1 conflict check
|
||||
if((g_adcDataBase.channelConfigValidBitMap & (0x7 << (ADC_CHANNEL_AIO1*3U))) != 0)
|
||||
{
|
||||
RestoreIRQMask(mask);
|
||||
return -2;
|
||||
}
|
||||
|
||||
// First Initialization
|
||||
if(g_adcDataBase.channelConfigValidBitMap == 0)
|
||||
{
|
||||
// enable ADC
|
||||
ADC_ENABLE();
|
||||
XIC_SetVector(PXIC1_AUXADC_IRQn, ADC_interruptHandler);
|
||||
XIC_EnableIRQ(PXIC1_AUXADC_IRQn);
|
||||
ADC_requestQueueInit();
|
||||
}
|
||||
ADC->AIOCFG |= ADC_AIOCFG_VREF2AIO1_EN_Msk;
|
||||
g_adcDataBase.channelConfigValidBitMap |= ( 1 << ADC_MAX_LOGIC_CHANNELS);
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ADC_disableVrefOutput(void)
|
||||
{
|
||||
uint32_t mask = SaveAndSetIRQMask();
|
||||
|
||||
g_adcDataBase.channelConfigValidBitMap &= ~(1 << ADC_MAX_LOGIC_CHANNELS);
|
||||
|
||||
ADC->AIOCFG &= ~ADC_AIOCFG_VREF2AIO1_EN_Msk;
|
||||
|
||||
if(g_adcDataBase.channelConfigValidBitMap == 0)
|
||||
{
|
||||
// diable ADC
|
||||
ADC->CTRL = ADC->CTRL & ADC_CTRL_LDO_EN_Msk;
|
||||
// disable clock
|
||||
ADC_DISABLE();
|
||||
XIC_DisableIRQ(PXIC1_AUXADC_IRQn);
|
||||
}
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
#include "ic.h"
|
||||
#include "apmu2Peripheral.h"
|
||||
#ifdef __USER_CODE__
|
||||
#include "RTE_Device.h"
|
||||
#else
|
||||
#include "RTE_Device.h"
|
||||
#endif
|
||||
#include "timer.h"
|
||||
#include "clock.h"
|
||||
#include DEBUG_LOG_HEADER_FILE
|
||||
#if (RTE_USB_EN == 1)
|
||||
void usblpw_enter_start_proc(bool force_cfg_pwr_down);
|
||||
void usblpw_enter_abort_proc(bool force_cfg_pwr_down);
|
||||
void usblpw_susp2vbustbl_guard_dlychk(uint32_t cur_tick);
|
||||
void usblpw_susp2hib_guard_dlychk(uint32_t cur_tick);
|
||||
void usblpw_retwkup_sleep1_later_recovery(void);
|
||||
void usblpw_retwkup_sleep1_pre_recovery(void);
|
||||
#endif
|
||||
|
||||
#if (RTE_LPUART_EN == 1)
|
||||
#include "bsp_lpusart.h"
|
||||
#endif
|
||||
|
||||
// to wakeup in paging wfi for hib timer, should only use in paging.(timer4 can use in app)
|
||||
#define AP_NEARHIBTIME_INSTANCE (4)
|
||||
#define AP_NEARHIBTIME_IRQ (PXIC0_TIMER4_IRQn)
|
||||
#define AP_NEARHIBTIME_MAXIMUM (4294967) // 0xffffffff/1000 ms
|
||||
|
||||
// do not use timer5 in app
|
||||
#define CP_STARTTIME_INSTANCE (5)
|
||||
#define CP_STARTTIME_IRQ (PXIC0_TIMER5_IRQn)
|
||||
#define CP_STARTTIME_MAXIMUM (4294967) // 0xffffffff/1000 ms
|
||||
|
||||
void apmuPeriUsbEnterStartProc(bool forceCfgPwrDown)
|
||||
{
|
||||
#if (RTE_USB_EN == 1)
|
||||
usblpw_enter_start_proc(forceCfgPwrDown);
|
||||
#endif
|
||||
}
|
||||
|
||||
void apmuPeriUsbEnterAbortProc(bool forceCfgPwrDown)
|
||||
{
|
||||
#if (RTE_USB_EN == 1)
|
||||
usblpw_enter_abort_proc(forceCfgPwrDown);
|
||||
#endif
|
||||
}
|
||||
|
||||
void apmuPeriUsbSusp2VbusTblGuardDlyChk(uint32_t cur_tick)
|
||||
{
|
||||
#if (RTE_USB_EN == 1)
|
||||
usblpw_susp2vbustbl_guard_dlychk(cur_tick);
|
||||
#endif
|
||||
}
|
||||
|
||||
void apmuPeriUsbSusp2HibGuardDlyChk(uint32_t cur_tick)
|
||||
{
|
||||
#if (RTE_USB_EN == 1)
|
||||
usblpw_susp2hib_guard_dlychk(cur_tick);
|
||||
#endif
|
||||
}
|
||||
|
||||
void apmuPeriUsbSleep1LateRecoverFlow(bool sleepSuccess)
|
||||
{
|
||||
#if (RTE_USB_EN == 1)
|
||||
if(sleepSuccess)
|
||||
{
|
||||
usblpw_retwkup_sleep1_later_recovery();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void apmuPeriUsbSleep1PreRecoverFlow(bool sleepSuccess)
|
||||
{
|
||||
#if (RTE_USB_EN == 1)
|
||||
if(sleepSuccess)
|
||||
{
|
||||
usblpw_retwkup_sleep1_pre_recovery();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool apmuPeriLpuartPreSleepProcess(void)
|
||||
{
|
||||
#ifdef __USER_CODE__
|
||||
extern int soc_uart_sleep_check(uint8_t *result);
|
||||
uint8_t result;
|
||||
if (!soc_uart_sleep_check(&result))
|
||||
{
|
||||
return result?true:false;
|
||||
}
|
||||
#endif
|
||||
#if (RTE_LPUART_EN == 1)
|
||||
LPUSART_SetStopFlag();
|
||||
if(LPUSART_IsRxActive())
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, apmuPeriLpuartPreSleepProcess_1, P_WARNING, "lpuart status, iir: 0x%x, fcsr: 0x%x, tcr: 0x%x, tsr: 0x%x", LPUSART_CORE->IIR, LPUSART_CORE->FCSR, LPUSART_CORE->TCR, LPUSART_CORE->TSR);
|
||||
LPUSART_ClearStopFlag();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
extern void AonRegSetWakeupEdge(uint8_t index, bool posEnable, bool negEnable);
|
||||
AonRegSetWakeupEdge(6, false, true);
|
||||
NVIC_EnableIRQ(LpuartWakeup_IRQn);
|
||||
}
|
||||
LPUSART_ClearStopFlag();
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool apmuPeriLpuartIsRxActive(void)
|
||||
{
|
||||
#ifdef __USER_CODE__
|
||||
extern int soc_uart_rx_check(uint8_t *result);
|
||||
uint8_t result;
|
||||
if (!soc_uart_rx_check(&result))
|
||||
{
|
||||
return result?true:false;
|
||||
}
|
||||
#endif
|
||||
#if (RTE_LPUART_EN == 1)
|
||||
return LPUSART_IsRxActive();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void apmuPeriWFITimerExp(void)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PMU, apmu2PeriWFITimerExp_0, P_VALUE, "apmu2PeriWFITimerExp Enter");
|
||||
if (TIMER_getInterruptFlags(CP_STARTTIME_INSTANCE) & TIMER_MATCH0_INTERRUPT_FLAG)
|
||||
{
|
||||
TIMER_clearInterruptFlags(CP_STARTTIME_INSTANCE, TIMER_MATCH0_INTERRUPT_FLAG);
|
||||
}
|
||||
TIMER_stop(AP_NEARHIBTIME_INSTANCE);
|
||||
TIMER_deInit(AP_NEARHIBTIME_INSTANCE);
|
||||
}
|
||||
|
||||
|
||||
void apmuPeriStartWFITimer(uint32_t ms)
|
||||
{
|
||||
int32_t clkRet1,clkRet2;
|
||||
if(ms<10)
|
||||
return;
|
||||
|
||||
CLOCK_clockReset(FCLK_TIMER4); // to protect setClock error
|
||||
|
||||
// TIMER config
|
||||
// Config TIMER clock, source from 26MHz and divide by 1
|
||||
clkRet1 = CLOCK_setClockSrc(FCLK_TIMER4, FCLK_TIMER4_SEL_26M);
|
||||
clkRet2 = CLOCK_setClockDiv(FCLK_TIMER4, 26);
|
||||
|
||||
if((clkRet1 != 0) || (clkRet2 != 0))
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PMU, apmuPeriStartWFITimer_0, P_ERROR, "clkRet1=%d, clkRet2=%d, CLKFREQ=0x%x", clkRet1, clkRet2, CLOCK_getClockFreq(FCLK_TIMER4));
|
||||
EC_ASSERT(0, clkRet1, clkRet2, CLOCK_getClockFreq(FCLK_TIMER4));
|
||||
}
|
||||
|
||||
TimerConfig_t timerConfig;
|
||||
TIMER_getDefaultConfig(&timerConfig);
|
||||
timerConfig.reloadOption = TIMER_RELOAD_ON_MATCH0;
|
||||
|
||||
if(ms > AP_NEARHIBTIME_MAXIMUM)
|
||||
{
|
||||
ms = AP_NEARHIBTIME_MAXIMUM;
|
||||
}
|
||||
timerConfig.match0 = (ms-5)*1000;
|
||||
|
||||
ECPLAT_PRINTF(UNILOG_PMU, apmuPeriStartWFITimer_1, P_VALUE, "apmuPeriStartWFITimer set to %u ms", (ms-5));
|
||||
|
||||
TIMER_init(AP_NEARHIBTIME_INSTANCE, &timerConfig);
|
||||
|
||||
TIMER_interruptConfig(AP_NEARHIBTIME_INSTANCE, TIMER_MATCH0_SELECT, TIMER_INTERRUPT_LEVEL);
|
||||
TIMER_interruptConfig(AP_NEARHIBTIME_INSTANCE, TIMER_MATCH1_SELECT, TIMER_INTERRUPT_DISABLED);
|
||||
TIMER_interruptConfig(AP_NEARHIBTIME_INSTANCE, TIMER_MATCH2_SELECT, TIMER_INTERRUPT_DISABLED);
|
||||
|
||||
// Enable TIMER IRQ
|
||||
XIC_SetVector(AP_NEARHIBTIME_IRQ, apmuPeriWFITimerExp);
|
||||
XIC_EnableIRQ(AP_NEARHIBTIME_IRQ);
|
||||
|
||||
TIMER_start(AP_NEARHIBTIME_INSTANCE);
|
||||
}
|
||||
|
||||
void apmuPeriDeleteWFITimer(void)
|
||||
{
|
||||
TIMER_stop(AP_NEARHIBTIME_INSTANCE);
|
||||
TIMER_deInit(AP_NEARHIBTIME_INSTANCE);
|
||||
}
|
||||
|
||||
void apmuPeriDeleteCPTimer(void)
|
||||
{
|
||||
TIMER_stop(CP_STARTTIME_INSTANCE);
|
||||
TIMER_deInit(CP_STARTTIME_INSTANCE);
|
||||
}
|
||||
|
||||
void apmuPeriClearCPTimerInterrupt(void)
|
||||
{
|
||||
if (TIMER_getInterruptFlags(CP_STARTTIME_INSTANCE) & TIMER_MATCH0_INTERRUPT_FLAG)
|
||||
{
|
||||
TIMER_clearInterruptFlags(CP_STARTTIME_INSTANCE, TIMER_MATCH0_INTERRUPT_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
void apmuPeriStartCPTimer(uint32_t cpStartTime, void* expFunc)
|
||||
{
|
||||
int32_t clkRet1,clkRet2;
|
||||
|
||||
CLOCK_clockReset(FCLK_TIMER5); // to protect setClock error, can not reproduce easily
|
||||
|
||||
// TIMER config
|
||||
// Config TIMER clock, source from 26MHz and divide by 1
|
||||
clkRet1 = CLOCK_setClockSrc(FCLK_TIMER5, FCLK_TIMER5_SEL_26M);
|
||||
clkRet2 = CLOCK_setClockDiv(FCLK_TIMER5, 26);
|
||||
|
||||
if((clkRet1 != 0) || (clkRet2 != 0))
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PMU, apmuPeriStartCPTimer_0, P_ERROR, "clkRet1=%d, clkRet2=%d, CLKFREQ=0x%x", clkRet1, clkRet2, CLOCK_getClockFreq(FCLK_TIMER5));
|
||||
EC_ASSERT(0, clkRet1, clkRet2, CLOCK_getClockFreq(FCLK_TIMER5));
|
||||
}
|
||||
TimerConfig_t timerConfig;
|
||||
TIMER_getDefaultConfig(&timerConfig);
|
||||
timerConfig.reloadOption = TIMER_RELOAD_ON_MATCH0;
|
||||
|
||||
if(cpStartTime > CP_STARTTIME_MAXIMUM)
|
||||
{
|
||||
cpStartTime = CP_STARTTIME_MAXIMUM;
|
||||
}
|
||||
timerConfig.match0 = (cpStartTime-1)*1000;
|
||||
|
||||
ECPLAT_PRINTF(UNILOG_PMU, apmuPeriStartCPTimer_1, P_VALUE, "apmuCreateModemStartTimer set to %u ms", (cpStartTime-1));
|
||||
|
||||
TIMER_init(CP_STARTTIME_INSTANCE, &timerConfig);
|
||||
|
||||
TIMER_interruptConfig(CP_STARTTIME_INSTANCE, TIMER_MATCH0_SELECT, TIMER_INTERRUPT_LEVEL);
|
||||
TIMER_interruptConfig(CP_STARTTIME_INSTANCE, TIMER_MATCH1_SELECT, TIMER_INTERRUPT_DISABLED);
|
||||
TIMER_interruptConfig(CP_STARTTIME_INSTANCE, TIMER_MATCH2_SELECT, TIMER_INTERRUPT_DISABLED);
|
||||
|
||||
// Enable TIMER IRQ
|
||||
XIC_SetVector(CP_STARTTIME_IRQ, expFunc);
|
||||
XIC_EnableIRQ(CP_STARTTIME_IRQ);
|
||||
TIMER_start(CP_STARTTIME_INSTANCE);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,469 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
|
||||
* File name: clock.c
|
||||
* Description: EC618 clock driver source file
|
||||
* History: Rev1.0 2019-02-20
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "clock.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "Driver_Common.h"
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
#include DEBUG_LOG_HEADER_FILE
|
||||
#endif
|
||||
|
||||
extern bool GPR_clockEnableCheck(ClockId_e id);
|
||||
extern ClockId_e CLOCK_checkClkID(void);
|
||||
|
||||
|
||||
/** \brief support clock driver full feature or not */
|
||||
#define ENABLE_CLK_TREE_PARENT
|
||||
|
||||
/** \brief definition of clk tree element for clock management */
|
||||
typedef struct _clk_tree_element
|
||||
{
|
||||
uint32_t enableCount : 8; /**< counter of each clk has been enabled */
|
||||
uint32_t parentId : 17; /**< id of this clock's parent clk */
|
||||
uint32_t hasExtraDependency : 1; /**< whether or not this clock has extra dependent clock */
|
||||
uint32_t canChangeSrcForcely : 1; /**< whether or not the source of this clock can be changed in enabled state */
|
||||
} ClkTreeElement_t;
|
||||
|
||||
/** \brief clock tree Array */
|
||||
static ClkTreeElement_t g_clkTreeArray[] =
|
||||
{
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_CC)] = {1, CLK_MF, 0, 1},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_APB_MP)] = {1, CLK_MF, 0, 1},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_APB_XP)] = {1, CLK_MF, 0, 1},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_SMP)] = {1, INVALID_CLK, 0, 1},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_SYSTICK)] = {1, CLK_32K, 0, 1},
|
||||
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_UART0)] = {0, CLK_MF_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_UART1)] = {0, CLK_MF_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_UART2)] = {0, CLK_MF_GATED, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_SPI0)] = {0, CLK_MF_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_SPI1)] = {0, CLK_MF_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_I2S0)] = {0, CLK_MF_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_I2S1)] = {0, CLK_MF_GATED, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_WDG)] = {0, CLK_32K_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER0)] = {0, CLK_32K_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER1)] = {0, CLK_32K_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER2)] = {0, CLK_32K_GATED, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER3)] = {0, CLK_32K_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER4)] = {0, CLK_32K_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_TIMER5)] = {0, CLK_32K_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_I2C0)] = {0, CLK_MF_GATED, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_I2C1)] = {0, CLK_MF_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_USIM0)] = {0, CLK_MF_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_USIM1)] = {0, CLK_MF_GATED, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FCLK_KPC)] = {0, CLK_32K_GATED, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_FLASH)] = {1, CLK_MF, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_PSRAM)] = {0, CLK_MF, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_MF)] = {1, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_32K)] = {1, INVALID_CLK, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_HF408M)] = {1, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_HF204M)] = {1, CLK_HF408M, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_HF102M)] = {0, CLK_HF204M, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_HF51M)] = {0, CLK_HF102M, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_32K_GATED)] = {1, CLK_32K, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_MF_GATED)] = {1, CLK_MF, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_CC_MP)] = {1, CLK_CC, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_CC_AP)] = {1, CLK_CC, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_CC_CP)] = {1, CLK_CC, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_AON)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_SMP_MP)] = {0, CLK_SMP, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(MFAB_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(AFBBR_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(MSMB_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FLASH_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(PSRAM_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(ULOG_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(UTFC_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(ULDP_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(USBC_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(USBC_PMU_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(USBC_REF_CLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(USBP_REF_CLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(USBC_UTMI_CLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_DAP_AP)] = {1, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_TRACE_AP)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_SYSTICK_AP)] = {0, CLK_SYSTICK, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_APB_AP)] = {1, CLK_APB_XP, 1, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_SMP_AP)] = {1, CLK_SMP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CLK_CLKCAL)] = {0, CLK_MF, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_SIPC)] = {0, CLK_APB_MP, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_AON)] = {1, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_CPMU)] = {1, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_PMDIG)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_RFDIG)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_PAD)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_GPIO)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_FUSE)] = {1, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_TRNG)] = {0, CLK_APB_MP, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_USBP)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_LPUC)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_UART0)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_UART1)] = {0, CLK_APB_MP, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_UART2)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_SPI0)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_SPI1)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_I2S0)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_I2S1)] = {0, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_WDG)] = {0, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_TIMER0)] = {0, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_TIMER1)] = {0, CLK_APB_AP, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_TIMER2)] = {0, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_TIMER3)] = {0, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_TIMER4)] = {0, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_TIMER5)] = {0, CLK_APB_AP, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_IPC)] = {1, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_I2C0)] = {0, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_I2C1)] = {0, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_USIM0)] = {0, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_USIM1)] = {0, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_KPC)] = {0, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(PCLK_ONEW)] = {0, CLK_APB_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(TOP_PBRG_HCLK)] = {1, CLK_CC_MP, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(TOP_PBRG_PCLK)] = {1, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(TOP_GPR_PCLK)] = {1, CLK_APB_MP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(TRACE_CLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(ETM_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(ROMTABLE_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(TPIU_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(CACHE_HCLK)] = {1, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(FABSUB_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(SBU_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(PBRG_HCLK)] = {1, CLK_CC_AP, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(SPIS_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(XIC_RMI_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(ULOG_RMI_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(TMU_RMI_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(SCT_RMI_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(UTFC_RMI_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
[GET_INDEX_FROM_CLOCK_ID(ULDP_RMI_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
|
||||
[GET_INDEX_FROM_CLOCK_ID(SCT_HCLK)] = {0, INVALID_CLK, 0, 0},
|
||||
|
||||
};
|
||||
|
||||
|
||||
PLAT_PA_RAMCODE void CLOCK_Trace(ClockId_e id, bool isEnable, void *func)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
ClockId_e checkId = CLOCK_checkClkID();
|
||||
uint32_t indexFromId = GET_INDEX_FROM_CLOCK_ID(id);
|
||||
|
||||
if(id == checkId)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, CLOCK_Trace_1, P_WARNING, "Clock Trace, id=0x%x isEnable=%d counter=%d, funcPtr=%x", id, isEnable, g_clkTreeArray[indexFromId].enableCount, func);
|
||||
}
|
||||
|
||||
if (g_clkTreeArray[indexFromId].enableCount > 128)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, CLOCK_Trace_2, P_WARNING, "Clock Trace, id=0x%x counter=%d may overflow, funcPtr=%x", id, g_clkTreeArray[indexFromId].enableCount, func);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CLOCK_AssertChkBeforeSlp(void)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
if(CLOCK_checkClkID() == INVALID_CLK)
|
||||
return;
|
||||
uint32_t indexFromId = GET_INDEX_FROM_CLOCK_ID(CLOCK_checkClkID());
|
||||
if(g_clkTreeArray[indexFromId].enableCount != 0)
|
||||
EC_ASSERT(0, g_clkTreeArray[indexFromId].enableCount, indexFromId, 0);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
PLAT_PA_RAMCODE int32_t CLOCK_clockEnable(ClockId_e id)
|
||||
{
|
||||
|
||||
#if defined(ENABLE_CLK_TREE_PARENT)
|
||||
int32_t ret;
|
||||
#endif
|
||||
|
||||
uint32_t mask, indexFromId = GET_INDEX_FROM_CLOCK_ID(id);
|
||||
|
||||
if(indexFromId > GET_INDEX_FROM_CLOCK_ID(INVALID_CLK))
|
||||
return ARM_DRIVER_ERROR_PARAMETER;
|
||||
else if(indexFromId == GET_INDEX_FROM_CLOCK_ID(INVALID_CLK))
|
||||
return ARM_DRIVER_OK;
|
||||
|
||||
mask = SaveAndSetIRQMask();
|
||||
|
||||
CLOCK_Trace(id, true, __GET_RETURN_ADDRESS());
|
||||
|
||||
if(g_clkTreeArray[indexFromId].enableCount++ == 0)
|
||||
{
|
||||
GPR_clockEnable(id);
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
#if defined(ENABLE_CLK_TREE_PARENT)
|
||||
if(g_clkTreeArray[indexFromId].hasExtraDependency)
|
||||
{
|
||||
ret = CLOCK_clockEnable(PBRG_HCLK);
|
||||
ASSERT(ret == ARM_DRIVER_OK);
|
||||
}
|
||||
|
||||
ret = CLOCK_clockEnable((ClockId_e)g_clkTreeArray[indexFromId].parentId);
|
||||
ASSERT(ret == ARM_DRIVER_OK);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GPR_clockEnableCheck(id) == false)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, CLOCK_clockEnable_1, P_WARNING, "Clock Enable Failed, id=0x%x counter=%d", id, g_clkTreeArray[indexFromId].enableCount);
|
||||
#endif
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
}
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
PLAT_PA_RAMCODE void CLOCK_clockDisable(ClockId_e id)
|
||||
{
|
||||
uint32_t mask, indexFromId = GET_INDEX_FROM_CLOCK_ID(id);
|
||||
|
||||
if(indexFromId >= GET_INDEX_FROM_CLOCK_ID(INVALID_CLK))
|
||||
return;
|
||||
|
||||
mask = SaveAndSetIRQMask();
|
||||
|
||||
CLOCK_Trace(id, false, __GET_RETURN_ADDRESS());
|
||||
|
||||
if(g_clkTreeArray[indexFromId].enableCount == 0)
|
||||
{
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, CLOCK_clockDisable_0, P_WARNING, "Clock Disable check failed, id=0x%x", id);
|
||||
#endif
|
||||
ASSERT(0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(--g_clkTreeArray[indexFromId].enableCount))
|
||||
{
|
||||
GPR_clockDisable(id);
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
#if defined(ENABLE_CLK_TREE_PARENT)
|
||||
if(g_clkTreeArray[indexFromId].hasExtraDependency)
|
||||
{
|
||||
CLOCK_clockDisable(PBRG_HCLK);
|
||||
}
|
||||
CLOCK_clockDisable((ClockId_e)g_clkTreeArray[indexFromId].parentId);
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreIRQMask(mask);
|
||||
}
|
||||
}
|
||||
|
||||
PLAT_PA_RAMCODE void CLOCK_clockReset(ClockId_e id)
|
||||
{
|
||||
uint32_t mask, indexFromId = GET_INDEX_FROM_CLOCK_ID(id);
|
||||
uint8_t count = 0;
|
||||
if(indexFromId >= GET_INDEX_FROM_CLOCK_ID(INVALID_CLK))
|
||||
return;
|
||||
|
||||
mask = SaveAndSetIRQMask();
|
||||
|
||||
count = g_clkTreeArray[indexFromId].enableCount;
|
||||
|
||||
g_clkTreeArray[indexFromId].enableCount = 0;
|
||||
|
||||
GPR_clockDisable(id);
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
/* here, maybe not right */
|
||||
#if defined(ENABLE_CLK_TREE_PARENT)
|
||||
if(count > 0)
|
||||
{
|
||||
CLOCK_clockDisable((ClockId_e)g_clkTreeArray[indexFromId].parentId);
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t CLOCK_setClockSrc(ClockId_e id, ClockSelect_e select)
|
||||
{
|
||||
int32_t ret, mask, indexFromId = GET_INDEX_FROM_CLOCK_ID(id);
|
||||
|
||||
if(indexFromId >= GET_INDEX_FROM_CLOCK_ID(INVALID_CLK))
|
||||
return ARM_DRIVER_ERROR_PARAMETER;
|
||||
|
||||
mask = SaveAndSetIRQMask();
|
||||
|
||||
if((g_clkTreeArray[indexFromId].enableCount == 0) || (g_clkTreeArray[indexFromId].canChangeSrcForcely == 1))
|
||||
{
|
||||
ret = GPR_setClockSrc(id, select);
|
||||
if(ret == ARM_DRIVER_OK)
|
||||
{
|
||||
g_clkTreeArray[indexFromId].parentId = (ClockId_e)(GET_PARENTCLOCKID_FROM_CLOCK_SEL_VALUE(select));
|
||||
}
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
return ARM_DRIVER_ERROR;
|
||||
}
|
||||
|
||||
int32_t CLOCK_setClockDiv(ClockId_e id, uint32_t div)
|
||||
{
|
||||
int32_t mask, indexFromId = GET_INDEX_FROM_CLOCK_ID(id);
|
||||
|
||||
if(indexFromId >= GET_INDEX_FROM_CLOCK_ID(INVALID_CLK))
|
||||
return ARM_DRIVER_ERROR_PARAMETER;
|
||||
|
||||
mask = SaveAndSetIRQMask();
|
||||
|
||||
if(g_clkTreeArray[indexFromId].enableCount == 0)
|
||||
{
|
||||
RestoreIRQMask(mask);
|
||||
return GPR_setClockDiv(id, div);
|
||||
}
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
return ARM_DRIVER_ERROR;
|
||||
|
||||
}
|
||||
|
||||
uint32_t CLOCK_getClockFreq(ClockId_e id)
|
||||
{
|
||||
return GPR_getClockFreq(id);
|
||||
}
|
||||
|
||||
int32_t CLOCK_setFracDivConfig(FracDivConfig_t * config)
|
||||
{
|
||||
if(config == NULL)
|
||||
{
|
||||
return ARM_DRIVER_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((config->fracDiv0DivRatioInteger == 256) && (config->fracDiv0DivRatioFrac != 0))
|
||||
{
|
||||
return ARM_DRIVER_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
if((config->fracDiv1DivRatioInteger == 256) && (config->fracDiv1DivRatioFrac != 0))
|
||||
{
|
||||
return ARM_DRIVER_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
GPR_setFracDivConfig(config);
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CLOCK_bclkEnable(BclkId_e id)
|
||||
{
|
||||
GPR_BclkEnable(id);
|
||||
}
|
||||
|
||||
|
||||
void CLOCK_fracDivOutCLkEnable(FracDivOutClkId_e id)
|
||||
{
|
||||
GPR_fracDivOutCLkEnable(id);
|
||||
}
|
||||
|
||||
void CLOCK_fracDivOutClkDisable(FracDivOutClkId_e id)
|
||||
{
|
||||
GPR_fracDivOutClkDisable(id);
|
||||
}
|
||||
|
||||
void CLOCK_setFracDivOutClkDiv(FracDivOutClkId_e id, uint8_t div)
|
||||
{
|
||||
GPR_setFracDivOutClkDiv(id, div);
|
||||
}
|
||||
|
||||
void CLOCK_setBclkSrc(BclkId_e id, BclkSrc_e src)
|
||||
{
|
||||
GPR_setBclkSrc(id, src);
|
||||
}
|
||||
|
||||
void CLOCK_setBclkDiv(BclkId_e id, uint8_t div)
|
||||
{
|
||||
GPR_setBclkDiv(id, div);
|
||||
}
|
||||
|
||||
void CLOCK_setMclkSrc(MclkId_e id, MclkSrc_e src)
|
||||
{
|
||||
GPR_setMclkSrc(id, src);
|
||||
}
|
||||
|
||||
void CLOCK_mclkEnable(MclkId_e id)
|
||||
{
|
||||
GPR_mclkEnable(id);
|
||||
}
|
||||
|
||||
void CLOCK_mclkDisable(MclkId_e id)
|
||||
{
|
||||
GPR_mclkDisable(id);
|
||||
}
|
||||
|
||||
void CLOCK_setMclkDiv(MclkId_e id, uint8_t div)
|
||||
{
|
||||
GPR_setMclkDiv(id, div);
|
||||
}
|
||||
|
||||
void CLOCK_updateClockTreeElement(ClockId_e id, ClockId_e parentId, uint8_t enableCount)
|
||||
{
|
||||
int32_t mask, indexFromId = GET_INDEX_FROM_CLOCK_ID(id);
|
||||
|
||||
if(indexFromId >= GET_INDEX_FROM_CLOCK_ID(INVALID_CLK))
|
||||
return;
|
||||
|
||||
mask = SaveAndSetIRQMask();
|
||||
|
||||
g_clkTreeArray[indexFromId].parentId = parentId;
|
||||
g_clkTreeArray[indexFromId].enableCount = enableCount;
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,878 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
|
||||
* File name: cspi.c
|
||||
* Description: Dedicated spi for camera use in EC618. The interface is similar with CMSIS Driver API V2.0.
|
||||
* History: Rev1.0 2021-03-18
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "cspi.h"
|
||||
#include "slpman.h"
|
||||
#include "cameraDrv.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSPI Setting field Start
|
||||
// All the CSPI's parameters that need user to set are all put here
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static DmaTransferConfig_t g_dmaRxConfig =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
DMA_FLOW_CONTROL_SOURCE,
|
||||
DMA_ADDRESS_INCREMENT_TARGET,
|
||||
DMA_DATA_WIDTH_FOUR_BYTES,
|
||||
DMA_BURST_32_BYTES,
|
||||
0
|
||||
};
|
||||
|
||||
#if (RTE_CSPI0)
|
||||
static PIN cspi0PinMCLK = {RTE_CSPI0_MCLK_PAD_ADDR, RTE_CSPI0_MCLK_FUNC};
|
||||
static PIN cspi0PinPCLK = {RTE_CSPI0_PCLK_PAD_ADDR, RTE_CSPI0_PCLK_FUNC};
|
||||
static PIN cspi0PinCS = {RTE_CSPI0_CS_PAD_ADDR, RTE_CSPI0_CS_FUNC};
|
||||
static PIN cspi0PinSdo0 = {RTE_CSPI0_SDO0_PAD_ADDR, RTE_CSPI0_SDO0_FUNC};
|
||||
static PIN cspi0PinSdo1 = {RTE_CSPI0_SDO1_PAD_ADDR, RTE_CSPI0_SDO1_FUNC};
|
||||
|
||||
#elif (RTE_CSPI1)
|
||||
static PIN cspi1PinMCLK = {RTE_CSPI1_MCLK_PAD_ADDR, RTE_CSPI1_MCLK_FUNC};
|
||||
static PIN cspi1PinPCLK = {RTE_CSPI1_PCLK_PAD_ADDR, RTE_CSPI1_PCLK_FUNC};
|
||||
static PIN cspi1PinCS = {RTE_CSPI1_CS_PAD_ADDR, RTE_CSPI1_CS_FUNC};
|
||||
static PIN cspi1PinSdo0 = {RTE_CSPI1_SDO0_PAD_ADDR, RTE_CSPI1_SDO0_FUNC};
|
||||
static PIN cspi1PinSdo1 = {RTE_CSPI1_SDO1_PAD_ADDR, RTE_CSPI1_SDO1_FUNC};
|
||||
#endif
|
||||
|
||||
// Data Format
|
||||
cspiDataFmt_t cspiDataFmt =
|
||||
{
|
||||
.slaveModeEn = 1,
|
||||
.slotSize = 7,
|
||||
.wordSize = 7,
|
||||
.alignMode = 0,
|
||||
.endianMode = 0, // 0:LSB 1: MSB.
|
||||
.dataDly = 0,
|
||||
.txPad = 0,
|
||||
.rxSignExt = 0,
|
||||
.txPack = 0,
|
||||
.rxPack = 2,
|
||||
.txFifoEndianMode = 0,
|
||||
.rxFifoEndianMode = 0
|
||||
};
|
||||
|
||||
// Frame Info0
|
||||
cspiFrameInfo0_t cspiFrameInfo0 =
|
||||
{
|
||||
.cspiBusTimeOutCycle = 0x1000,
|
||||
.dataId = 0, // readOnly
|
||||
};
|
||||
|
||||
// RX Fifo timeout Cycle
|
||||
cspiTimeOutCycle_t cspiRxTimeOutCycle =
|
||||
{
|
||||
.rxTimeOutCycle = 20,
|
||||
};
|
||||
|
||||
// INT Control
|
||||
cspiIntCtrl_t cspiIntCtrl =
|
||||
{
|
||||
.txUnderRunIntEn = 0,
|
||||
.txDmaErrIntEn = 0,
|
||||
.txDatIntEn = 0,
|
||||
.rxOverFlowIntEn = 0,
|
||||
.rxDmaErrIntEn = 0,
|
||||
.rxDatIntEn = 0,
|
||||
.rxTimeOutIntEn = 0,
|
||||
.fsErrIntEn = 0,
|
||||
.frameStartIntEn = 0,
|
||||
.frameEndIntEn = 0,
|
||||
.cspiBusTimeOutIntEn = 0,
|
||||
.txIntThreshHold = 8,
|
||||
.rxIntThreshHold = 8,
|
||||
};
|
||||
|
||||
|
||||
// DMA Control
|
||||
cspiDmaCtrl_t cspiDmaCtrl =
|
||||
{
|
||||
.rxDmaReqEn = 1,
|
||||
.txDmaReqEn = 0,
|
||||
.rxDmaTimeOutEn = 0,
|
||||
.dmaWorkWaitCycle = 31,
|
||||
.rxDmaBurstSizeSub1 = 7,
|
||||
.txDmaBurstSizeSub1 = 7,
|
||||
.rxDmaThreadHold = 7,
|
||||
.txDmaThreadHold = 8,
|
||||
.rxFifoFlush = 0,
|
||||
.txFifoFlush = 0
|
||||
};
|
||||
|
||||
cspiCtrl_t cspiCtrl =
|
||||
{
|
||||
.enable = 0,
|
||||
.csEn = 0,
|
||||
.rxWid = 1, // 0: 1bit; 1: 2bit
|
||||
.rxdSeq = 1, // gc032a 0, sp0a39 1
|
||||
.cpol = 0,
|
||||
.cpha = 1,
|
||||
.frameProcEn = 1,
|
||||
.fillYonly = 1,
|
||||
.hwInitEn = 1,
|
||||
.lsCheckEn = 1,
|
||||
.dpCheckEn = 1,
|
||||
.frameProcInitEn = 0,
|
||||
.rowScaleRatio = 0,
|
||||
.colScaleRatio = 0,
|
||||
.scaleBytes = 0,
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSPI Setting field End
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
static CSPI_TypeDef* const cspiInstance[CSPI_INSTANCE_NUM] = {CSPI0, CSPI1};
|
||||
|
||||
static ClockId_e cspiClk[CSPI_INSTANCE_NUM * 2] =
|
||||
{
|
||||
PCLK_I2S0,
|
||||
FCLK_I2S0,
|
||||
PCLK_I2S1,
|
||||
FCLK_I2S1
|
||||
};
|
||||
|
||||
static ClockResetId_e cspiRstClk[CSPI_INSTANCE_NUM * 2] =
|
||||
{
|
||||
RST_PCLK_I2S0,
|
||||
RST_FCLK_I2S0,
|
||||
RST_PCLK_I2S1,
|
||||
RST_FCLK_I2S1
|
||||
};
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
/**
|
||||
\brief spi initialization counter, for lower power callback register/de-register
|
||||
*/
|
||||
static uint32_t cspiInitCnt = 0;
|
||||
|
||||
/**
|
||||
\brief Bitmap of CSPI working status, each instance is assigned 2 bits representing tx and rx status,
|
||||
when all CSPI instances are not working, we can vote to enter to low power state.
|
||||
*/
|
||||
static uint32_t cspiWorkingStats = 0;
|
||||
|
||||
/** \brief Internal used data structure */
|
||||
typedef struct
|
||||
{
|
||||
bool isInited; /**< Whether spi has been initialized */
|
||||
struct
|
||||
{
|
||||
__IO uint32_t DFMT; /**< Data Format Register, offset: 0x0 */
|
||||
__IO uint32_t SLOTCTL; /**< Slot Control Register, offset: 0x4 */
|
||||
__IO uint32_t CLKCTL; /**< Clock Control Register, offset: 0x8 */
|
||||
__IO uint32_t DMACTL; /**< DMA Control Register, offset: 0xC */
|
||||
__IO uint32_t INTCTL; /**< Interrupt Control Register, offset: 0x10 */
|
||||
__IO uint32_t TIMEOUTCTL; /**< Timeout Control Register, offset: 0x14 */
|
||||
__IO uint32_t STAS; /**< Status Register, offset: 0x18 */
|
||||
__IO uint32_t RFIFO; /**< Rx Buffer Register, offset: 0x1c */
|
||||
__IO uint32_t TFIFO; /**< Tx Buffer Register, offset: 0x20 */
|
||||
__IO uint32_t CSPICTL; /**< Camera SPI Control Register, offset: 0x28 */
|
||||
__IO uint32_t CCTL; /**< Auto Cg Control Register, offset: 0x2c */
|
||||
__IO uint32_t CSPIINFO0; /**< Cspi Frame info0 Register, offset: 0x30 */
|
||||
__IO uint32_t CSPIINFO1; /**< Cspi Frame info1 Register, offset: 0x34 */
|
||||
__IO uint32_t CSPIDBG; /**< Cspi Debug Register, offset: 0x38 */
|
||||
__IO uint32_t CSPINIT; /**< Cspi Init Register, offset: 0x3c */
|
||||
__IO uint32_t CLSP; /**< Cspi Line Start Register, offset: 0x40 */
|
||||
__IO uint32_t CDATP; /**< Cspi Data Packet Register, offset: 0x44 */
|
||||
__IO uint32_t CLINFO; /**< Cspi Line Info Register, offset: 0x48 */
|
||||
}regsBackup;
|
||||
} cspiDataBase_t;
|
||||
|
||||
static cspiDataBase_t cspiDataBase[CSPI_INSTANCE_NUM] = {0};
|
||||
|
||||
/**
|
||||
\fn static void cspiEnterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
\brief Perform necessary preparations before sleep.
|
||||
After recovering from SLPMAN_SLEEP1_STATE, CSPI hareware is repowered, we backup
|
||||
some registers here first so that we can restore user's configurations after exit.
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
static void cspiEnterLpStatePrepare(void* pdata, slpManLpState state)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
for(i = 0; i < CSPI_INSTANCE_NUM; i++)
|
||||
{
|
||||
if(cspiDataBase[i].isInited == true)
|
||||
{
|
||||
cspiDataBase[i].regsBackup.DFMT = cspiInstance[i]->DFMT;
|
||||
cspiDataBase[i].regsBackup.SLOTCTL = cspiInstance[i]->SLOTCTL;
|
||||
cspiDataBase[i].regsBackup.CLKCTL = cspiInstance[i]->CLKCTL;
|
||||
cspiDataBase[i].regsBackup.DMACTL = cspiInstance[i]->DMACTL;
|
||||
cspiDataBase[i].regsBackup.INTCTL = cspiInstance[i]->INTCTL;
|
||||
cspiDataBase[i].regsBackup.TIMEOUTCTL = cspiInstance[i]->TIMEOUTCTL;
|
||||
cspiDataBase[i].regsBackup.STAS = cspiInstance[i]->STAS;
|
||||
cspiDataBase[i].regsBackup.CSPICTL = cspiInstance[i]->CSPICTL;
|
||||
cspiDataBase[i].regsBackup.CCTL = cspiInstance[i]->CCTL;
|
||||
cspiDataBase[i].regsBackup.CSPIINFO0 = cspiInstance[i]->CSPIINFO0;
|
||||
cspiDataBase[i].regsBackup.CSPIINFO1 = cspiInstance[i]->CSPIINFO1;
|
||||
cspiDataBase[i].regsBackup.CSPIDBG = cspiInstance[i]->CSPIDBG;
|
||||
cspiDataBase[i].regsBackup.CSPINIT = cspiInstance[i]->CSPINIT;
|
||||
cspiDataBase[i].regsBackup.CLSP = cspiInstance[i]->CLSP;
|
||||
cspiDataBase[i].regsBackup.CDATP = cspiInstance[i]->CDATP;
|
||||
cspiDataBase[i].regsBackup.CLINFO = cspiInstance[i]->CLINFO;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\fn static void cspiExitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
\brief Restore after exit from sleep.
|
||||
After recovering from SLPMAN_SLEEP1_STATE, CSPI hareware is repowered, we restore user's configurations
|
||||
by aidding of the stored registers.
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
static void cspiExitLpStateRestore(void* pdata, slpManLpState state)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
for(i = 0; i < CSPI_INSTANCE_NUM; i++)
|
||||
{
|
||||
if(cspiDataBase[i].isInited == true)
|
||||
{
|
||||
GPR_clockEnable(cspiClk[2*i]);
|
||||
GPR_clockEnable(cspiClk[2*i+1]);
|
||||
|
||||
cspiInstance[i]->DFMT = cspiDataBase[i].regsBackup.DFMT;
|
||||
cspiInstance[i]->SLOTCTL = cspiDataBase[i].regsBackup.SLOTCTL;
|
||||
cspiInstance[i]->CLKCTL = cspiDataBase[i].regsBackup.CLKCTL;
|
||||
cspiInstance[i]->DMACTL = cspiDataBase[i].regsBackup.DMACTL;
|
||||
cspiInstance[i]->INTCTL = cspiDataBase[i].regsBackup.INTCTL;
|
||||
cspiInstance[i]->TIMEOUTCTL = cspiDataBase[i].regsBackup.TIMEOUTCTL;
|
||||
cspiInstance[i]->STAS = cspiDataBase[i].regsBackup.STAS;
|
||||
cspiInstance[i]->CSPICTL = cspiDataBase[i].regsBackup.CSPICTL;
|
||||
cspiInstance[i]->CCTL = cspiDataBase[i].regsBackup.CCTL;
|
||||
cspiInstance[i]->CSPIINFO0 = cspiDataBase[i].regsBackup.CSPIINFO0;
|
||||
cspiInstance[i]->CSPIINFO1 = cspiDataBase[i].regsBackup.CSPIINFO1;
|
||||
cspiInstance[i]->CSPIDBG = cspiDataBase[i].regsBackup.CSPIDBG;
|
||||
cspiInstance[i]->CSPINIT = cspiDataBase[i].regsBackup.CSPINIT;
|
||||
cspiInstance[i]->CLSP = cspiDataBase[i].regsBackup.CLSP;
|
||||
cspiInstance[i]->CDATP = cspiDataBase[i].regsBackup.CDATP;
|
||||
cspiInstance[i]->CLINFO = cspiDataBase[i].regsBackup.CLINFO;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define LOCK_SLEEP(instance) \
|
||||
do \
|
||||
{ \
|
||||
cspiWorkingStats |= (1U << instance); \
|
||||
slpManDrvVoteSleep(SLP_VOTE_I2S, SLP_ACTIVE_STATE); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define CHECK_TO_UNLOCK_SLEEP(instance) \
|
||||
do \
|
||||
{ \
|
||||
cspiWorkingStats &= ~(1U << instance); \
|
||||
if(cspiWorkingStats == 0) \
|
||||
slpManDrvVoteSleep(SLP_VOTE_I2S, SLP_SLP1_STATE); \
|
||||
} \
|
||||
while(0)
|
||||
#endif
|
||||
|
||||
#if (RTE_CSPI0)
|
||||
static cspiInfo_t cspi0Info = {0};
|
||||
void cspi0DmaRxEvent(uint32_t event);
|
||||
static DmaDescriptor_t __ALIGNED(16) cspi0DmaRxDesc[CAM_CHAIN_COUNT];
|
||||
static cspiDma_t cspi0Dma =
|
||||
{
|
||||
DMA_INSTANCE_MP,
|
||||
-1,
|
||||
RTE_CSPI0_DMA_RX_REQID,
|
||||
cspi0DmaRxEvent,
|
||||
cspi0DmaRxDesc
|
||||
};
|
||||
|
||||
static cspiRes_t cspi0Res = {
|
||||
CSPI0,
|
||||
{
|
||||
&cspi0PinMCLK,
|
||||
&cspi0PinPCLK,
|
||||
&cspi0PinCS,
|
||||
&cspi0PinSdo0,
|
||||
&cspi0PinSdo1,
|
||||
},
|
||||
&cspi0Dma,
|
||||
&cspi0Info
|
||||
};
|
||||
#endif
|
||||
|
||||
#if (RTE_CSPI1)
|
||||
static cspiInfo_t cspi1Info = {0};
|
||||
void cspi1DmaRxEvent(uint32_t event);
|
||||
static DmaDescriptor_t __ALIGNED(16) cspi1DmaRxDesc[CAM_CHAIN_COUNT];
|
||||
static cspiDma_t cspi1Dma =
|
||||
{
|
||||
DMA_INSTANCE_MP,
|
||||
-1,
|
||||
RTE_CSPI1_DMA_RX_REQID,
|
||||
cspi1DmaRxEvent,
|
||||
cspi1DmaRxDesc
|
||||
};
|
||||
|
||||
static cspiRes_t cspi1Res = {
|
||||
CSPI1,
|
||||
{
|
||||
&cspi1PinMCLK,
|
||||
&cspi1PinPCLK,
|
||||
&cspi1PinCS,
|
||||
&cspi1PinSdo0,
|
||||
&cspi1PinSdo1,
|
||||
},
|
||||
&cspi1Dma,
|
||||
&cspi1Info
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
\fn static uint32_t cspiGetInstanceNum(cspiRes_t *cspi)
|
||||
\brief Get instance number
|
||||
\param[in] spi Pointer to CSPI resources
|
||||
\returns instance number
|
||||
*/
|
||||
static uint32_t cspiGetInstanceNum(cspiRes_t *cspi)
|
||||
{
|
||||
return ((uint32_t)cspi->reg - (uint32_t)CSPI0) >> 12U;
|
||||
}
|
||||
|
||||
/**
|
||||
\fn static int32_t cspiSetBusSpeed(uint32_t bps, cspiRes_t *cspi)
|
||||
\brief Set bus speed
|
||||
\param[in] bps bus speed to set
|
||||
\param[in] spi Pointer to SPI resources
|
||||
\return \ref execution_status
|
||||
*/
|
||||
static int32_t cspiSetBusSpeed(camFrequence_e freq, cspiRes_t *cspi)
|
||||
{
|
||||
uint32_t instance = cspiGetInstanceNum(cspi);
|
||||
uint32_t freqDivInteger = 0;
|
||||
uint32_t freqDivRatio = 0;
|
||||
|
||||
switch(freq)
|
||||
{
|
||||
case CAM_6_5_M:
|
||||
freqDivInteger = 0x40;
|
||||
freqDivRatio = 0;
|
||||
break;
|
||||
|
||||
case CAM_13_M:
|
||||
freqDivInteger = 0x20;
|
||||
freqDivRatio = 0;
|
||||
break;
|
||||
|
||||
case CAM_25_5_M:
|
||||
freqDivInteger = 0x10;
|
||||
freqDivRatio = 0;
|
||||
break;
|
||||
|
||||
case CAM_24_M:
|
||||
freqDivInteger = 0x11;
|
||||
freqDivRatio = 0;
|
||||
break;
|
||||
|
||||
case CAM_20_M:
|
||||
freqDivInteger = 0x14;
|
||||
freqDivRatio = 0x666666;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (instance == 0) // i2s0
|
||||
{
|
||||
GPR_clockEnable(FCLK_I2S0);
|
||||
|
||||
GPR_fracDivOutCLkEnable(FRACDIV0_OUT0); // Fracdiv1_en
|
||||
GPR_setFracDivOutClkDiv(FRACDIV0_OUT0, 1); // 4 div, from 408M -> 102M
|
||||
#if 1
|
||||
GPR_setMclkSrc(MCLK0, MCLK_SRC_FRACDIV0_OUT0); // Bmclk_sel1
|
||||
GPR_mclkEnable(MCLK0); // Mclk_oe1
|
||||
#else
|
||||
GPR_setMclkSrc(MCLK2, MCLK_SRC_FRACDIV1_OUT0); // Bmclk_sel1
|
||||
GPR_mclkEnable(MCLK2);
|
||||
#endif
|
||||
GPR_setClockSrc(CLK_CC, CLK_CC_SEL_204M); // 0x4d000020 = 0x201
|
||||
|
||||
// Fracdiv clk selects 408M and set frac and integer clk
|
||||
FracDivConfig_t fracdivCfg;
|
||||
fracdivCfg.source = FRACDIC_ROOT_CLK_408M;
|
||||
fracdivCfg.fracDiv0DivRatioInteger = freqDivInteger;//0x10;//51M 0x10; // 25.5M
|
||||
fracdivCfg.fracDiv0DivRatioFrac = freqDivRatio;
|
||||
GPR_setFracDivConfig(&fracdivCfg);
|
||||
}
|
||||
else // i2s1
|
||||
{
|
||||
GPR_clockEnable(FCLK_I2S1);
|
||||
GPR_fracDivOutCLkEnable(FRACDIV1_OUT0); // Fracdiv1_en
|
||||
GPR_setFracDivOutClkDiv(FRACDIV1_OUT0, 1); // 4 div, from 408M -> 102M
|
||||
#if 1
|
||||
GPR_setMclkSrc(MCLK1, MCLK_SRC_FRACDIV1_OUT0); // Bmclk_sel1
|
||||
GPR_mclkEnable(MCLK1); // Mclk_oe1
|
||||
#else
|
||||
GPR_setMclkSrc(MCLK2, MCLK_SRC_FRACDIV1_OUT0); // Bmclk_sel1
|
||||
GPR_mclkEnable(MCLK2);
|
||||
#endif
|
||||
GPR_setClockSrc(CLK_CC, CLK_CC_SEL_204M); // 0x4d000020 = 0x201
|
||||
|
||||
// Fracdiv clk selects 408M and set frac and integer clk
|
||||
FracDivConfig_t fracdivCfg;
|
||||
fracdivCfg.source = FRACDIC_ROOT_CLK_408M;
|
||||
fracdivCfg.fracDiv1DivRatioInteger = freqDivInteger;//0x10;//51M 0x10; // 25.5M
|
||||
fracdivCfg.fracDiv1DivRatioFrac = freqDivRatio;
|
||||
GPR_setFracDivConfig(&fracdivCfg);
|
||||
}
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
\fn int32_t cspiInit(cspiCbEvent_fn cbEvent, cspiRes_t *cspi)
|
||||
\brief Initialize SPI Interface.
|
||||
\param[in] cbEvent Pointer to \ref cspiCbEvent_fn
|
||||
\param[in] spi Pointer to CSPI resources
|
||||
\return \ref execution_status
|
||||
*/
|
||||
int32_t cspiInit(cspiCbEvent_fn cbEvent, cspiRes_t *cspi)
|
||||
{
|
||||
int32_t returnCode;
|
||||
PadConfig_t config;
|
||||
uint32_t instance = cspiGetInstanceNum(cspi);
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
cspiDataBase[instance].isInited = true;
|
||||
#endif
|
||||
|
||||
// Initialize CSPI PINS
|
||||
PAD_getDefaultConfig(&config);
|
||||
#if 1 // I2S1
|
||||
config.mux = cspi->pins.mclk->funcNum;
|
||||
PAD_setPinConfig(cspi->pins.mclk->pinNum, &config);
|
||||
#else // MCLK2
|
||||
config.mux = PAD_MUX_ALT1;
|
||||
PAD_setPinConfig(14, &config);
|
||||
#endif
|
||||
config.mux = cspi->pins.pclk->funcNum;
|
||||
PAD_setPinConfig(cspi->pins.pclk->pinNum, &config);
|
||||
config.mux = cspi->pins.cs->funcNum;
|
||||
PAD_setPinConfig(cspi->pins.cs->pinNum, &config);
|
||||
config.mux = cspi->pins.sdo0->funcNum;
|
||||
PAD_setPinConfig(cspi->pins.sdo0->pinNum, &config);
|
||||
config.mux = cspi->pins.sdo1->funcNum;
|
||||
PAD_setPinConfig(cspi->pins.sdo1->pinNum, &config);
|
||||
|
||||
// Initialize SPI run-time resources
|
||||
cspi->info->cbEvent = cbEvent;
|
||||
|
||||
// Configure DMA if necessary
|
||||
if (cspi->dma)
|
||||
{
|
||||
DMA_init(cspi->dma->rxInstance);
|
||||
returnCode = DMA_openChannel(cspi->dma->rxInstance);
|
||||
|
||||
if (returnCode == ARM_DMA_ERROR_CHANNEL_ALLOC)
|
||||
return ARM_DRIVER_ERROR;
|
||||
else
|
||||
cspi->dma->rxCh = returnCode;
|
||||
|
||||
DMA_setChannelRequestSource(cspi->dma->rxInstance, cspi->dma->rxCh, (DmaRequestSource_e)cspi->dma->rxReq);
|
||||
DMA_rigisterChannelCallback(cspi->dma->rxInstance, cspi->dma->rxCh, cspi->dma->rxCb);
|
||||
|
||||
// Configure rx DMA and start it
|
||||
g_dmaRxConfig.sourceAddress = (void *)&(cspiInstance[instance]->RFIFO);
|
||||
g_dmaRxConfig.totalLength = CSPI_TRANSFER_TRUNK_SIZE;
|
||||
|
||||
DMA_enableChannelInterrupts(cspi->dma->rxInstance, cspi->dma->rxCh, DMA_END_INTERRUPT_ENABLE);
|
||||
DMA_startChannel(cspi->dma->rxInstance, cspi->dma->rxCh);
|
||||
}
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
cspiInitCnt++;
|
||||
|
||||
if(cspiInitCnt == 1U)
|
||||
{
|
||||
cspiWorkingStats = 0;
|
||||
slpManRegisterPredefinedBackupCb(SLP_CALLBACK_I2S_MODULE, cspiEnterLpStatePrepare, NULL);
|
||||
slpManRegisterPredefinedRestoreCb(SLP_CALLBACK_I2S_MODULE, cspiExitLpStateRestore, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\fn int32_t cspiDeInit(cspiRes_t *cspi)
|
||||
\brief De-initialize CSPI Interface.
|
||||
\param[in] spi Pointer to CSPI resources
|
||||
\return \ref execution_status
|
||||
*/
|
||||
int32_t cspiDeInit(cspiRes_t *cspi)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
uint32_t instance;
|
||||
|
||||
instance = cspiGetInstanceNum(cspi);
|
||||
|
||||
cspiDataBase[instance].isInited = false;
|
||||
|
||||
cspiInitCnt--;
|
||||
|
||||
if(cspiInitCnt == 0)
|
||||
{
|
||||
cspiWorkingStats = 0;
|
||||
slpManUnregisterPredefinedBackupCb(SLP_CALLBACK_I2S_MODULE);
|
||||
slpManUnregisterPredefinedRestoreCb(SLP_CALLBACK_I2S_MODULE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\fn int32_t cspiPowerControl(cspiPowerState_e state, cspiRes_t *cspi)
|
||||
\brief Control CSPI Interface Power.
|
||||
\param[in] state Power state
|
||||
\param[in] cspi Pointer to CSPI resources
|
||||
\return \ref execution_status
|
||||
*/
|
||||
int32_t cspiPowerCtrl(cspiPowerState_e state, cspiRes_t *cspi)
|
||||
{
|
||||
uint32_t instance = cspiGetInstanceNum(cspi);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case CSPI_POWER_OFF:
|
||||
// DMA disable
|
||||
if(cspi->dma)
|
||||
{
|
||||
DMA_stopChannel(cspi->dma->rxInstance, cspi->dma->rxCh, true);
|
||||
}
|
||||
|
||||
// Reset register values
|
||||
if (instance == 0)
|
||||
{
|
||||
CLOCK_setClockSrc(FCLK_I2S0, FCLK_I2S0_SEL_26M);
|
||||
GPR_swReset(RST_PCLK_I2S0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLOCK_setClockSrc(FCLK_I2S1, FCLK_I2S1_SEL_26M);
|
||||
GPR_swReset(RST_PCLK_I2S1);
|
||||
}
|
||||
|
||||
|
||||
// Disable CSPI clock
|
||||
GPR_clockDisable(cspiClk[instance*2]);
|
||||
GPR_clockDisable(cspiClk[instance*2+1]);
|
||||
|
||||
cspi->info->flags &= ~CSPI_FLAG_POWERED;
|
||||
break;
|
||||
|
||||
case CSPI_POWER_FULL:
|
||||
//if ((cspi->info->flags & CSPI_FLAG_INITIALIZED) == 0)
|
||||
//return ARM_DRIVER_ERROR;
|
||||
|
||||
if (cspi->info->flags & CSPI_FLAG_POWERED)
|
||||
return ARM_DRIVER_OK;
|
||||
|
||||
// Enable CSPI clock
|
||||
GPR_clockEnable(cspiClk[instance*2]);
|
||||
GPR_clockEnable(cspiClk[instance*2+1]);
|
||||
|
||||
GPR_swReset(cspiRstClk[instance*2]);
|
||||
GPR_swReset(cspiRstClk[instance*2+1]);
|
||||
|
||||
// Set power flag
|
||||
cspi->info->flags |= CSPI_FLAG_POWERED;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARM_DRIVER_ERROR_UNSUPPORTED;
|
||||
}
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
\fn int32_t cspiReceive(void *data, uint32_t num, cspiRes_t *cspi)
|
||||
\brief Start receiving data from SPI receiver.
|
||||
\param[out] dataIn Pointer to buffer for data to receive from CSPI receiver
|
||||
\param[in] num Number of data items to receive
|
||||
\param[in] cspi Pointer to CSPI resources
|
||||
\return \ref execution_status
|
||||
*/
|
||||
int32_t cspiRecv(cspiRes_t *cspi)
|
||||
{
|
||||
DMA_buildDescriptorChain(cspi->dma->descriptor, &g_dmaRxConfig, cspi->info->resolution, true);
|
||||
DMA_loadChannelDescriptorAndRun(cspi->dma->rxInstance, cspi->dma->rxCh, cspi->dma->descriptor);
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
\fn int32_t cspiControl(uint32_t control, uint32_t arg, cspiRes_t *cspi)
|
||||
\brief Control CSPI Interface.
|
||||
\param[in] control Operation
|
||||
\param[in] arg Argument of operation (optional)
|
||||
\param[in] cspi Pointer to CSPI resources
|
||||
\return common \ref execution_status and driver specific \ref spi_execution_status
|
||||
*/
|
||||
int32_t cspiControl(uint32_t control, uint32_t arg, cspiRes_t *cspi)
|
||||
{
|
||||
uint32_t instance = cspiGetInstanceNum(cspi);
|
||||
|
||||
switch(control & 0xFFFFFFFF)
|
||||
{
|
||||
// Set transport abort
|
||||
case CSPI_CTRL_TRANSABORT:
|
||||
{
|
||||
// If DMA mode, disable DMA channel
|
||||
if(cspi->dma)
|
||||
{
|
||||
DMA_stopChannel(cspi->dma->rxInstance, cspi->dma->rxCh, true);
|
||||
}
|
||||
|
||||
// clear SPI run-time resources
|
||||
cspi->reg->CSPICTL &= ~CSPI_ENABLE_Msk;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Set Bus Speed in bps; arg = value
|
||||
case CSPI_CTRL_BUS_SPEED:
|
||||
{
|
||||
if(cspiSetBusSpeed((camFrequence_e)arg, cspi) != ARM_DRIVER_OK)
|
||||
{
|
||||
return ARM_DRIVER_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Set Data Format
|
||||
case CSPI_CTRL_DATA_FORMAT:
|
||||
{
|
||||
memcpy((void*)&(cspiInstance[instance]->DFMT), &cspiDataFmt, sizeof(cspiDataFmt_t));
|
||||
break;
|
||||
}
|
||||
|
||||
// Flush rx fifo
|
||||
case CSPI_CTRL_FLUSH_RX_FIFO:
|
||||
{
|
||||
cspiInstance[instance]->DMACTL |= 0x1000000;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Set Int En
|
||||
case CSPI_CTRL_INT_CTRL:
|
||||
{
|
||||
memcpy((void*)&(cspiInstance[instance]->INTCTL), &cspiIntCtrl, sizeof(cspiIntCtrl_t));
|
||||
break;
|
||||
}
|
||||
|
||||
// Set recv mem addr
|
||||
case CSPI_CTRL_MEM_ADDR:
|
||||
{
|
||||
g_dmaRxConfig.targetAddress = (void*)arg; // dma gloval val. After this need call "CSPI_CTRL_DMA_CTRL"
|
||||
break;
|
||||
}
|
||||
|
||||
// Set Rx Timeout Cycle
|
||||
case CSPI_CTRL_RXTOR:
|
||||
{
|
||||
memcpy((void*)&(cspiInstance[instance]->TIMEOUTCTL), &cspiRxTimeOutCycle, sizeof(cspiTimeOutCycle_t));
|
||||
break;
|
||||
}
|
||||
|
||||
// Set DMA Control
|
||||
case CSPI_CTRL_DMA_CTRL:
|
||||
{
|
||||
//dmaInit(cspi);
|
||||
memcpy((void*)&(cspiInstance[instance]->DMACTL), &cspiDmaCtrl, sizeof(cspiDmaCtrl_t));
|
||||
break;
|
||||
}
|
||||
|
||||
// Set CSPI Control
|
||||
case CSPI_CTRL_CSPICTL:
|
||||
{
|
||||
memcpy((void*)&(cspiInstance[instance]->CSPICTL), &cspiCtrl, sizeof(cspiCtrl_t));
|
||||
break;
|
||||
}
|
||||
|
||||
// Enable or disable cspi
|
||||
case CSPI_CTRL_START_STOP:
|
||||
{
|
||||
if (arg > 0)
|
||||
{
|
||||
cspiInstance[instance]->CSPICTL |= CSPI_ENABLE_Msk;
|
||||
}
|
||||
else
|
||||
{
|
||||
cspiInstance[instance]->CSPICTL &= ~CSPI_ENABLE_Msk;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Set Frame Info0
|
||||
case CSPI_CTRL_FRAME_INFO0:
|
||||
{
|
||||
memcpy((void*)&(cspiInstance[instance]->CSPIINFO0), &cspiFrameInfo0, sizeof(cspiFrameInfo0_t));
|
||||
break;
|
||||
}
|
||||
|
||||
// Camera resolution set
|
||||
case CSPI_CTRL_RESOLUTION_SET:
|
||||
{
|
||||
cspi->info->resolution = (camResolution_e)arg; // this will interface the dma descriptor chain count
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return ARM_DRIVER_ERROR_UNSUPPORTED;
|
||||
}
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\fn void cspiDmaRxEvent(uint32_t event, cspiRes_t *cspi)
|
||||
\brief CSPI DMA Rx Event handler.
|
||||
\param[in] event DMA Rx Event
|
||||
\param[in] spi Pointer to CSPI resources
|
||||
*/
|
||||
void cspiDmaRxEvent(uint32_t event, cspiRes_t *cspi)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
uint32_t instance = cspiGetInstanceNum(cspi);
|
||||
#endif
|
||||
|
||||
switch(event)
|
||||
{
|
||||
case DMA_EVENT_END:
|
||||
//cspi->reg->CSPICTL &= ~CSPI_ENABLE_Msk; // must close cspi here
|
||||
|
||||
if(cspi->info->cbEvent)
|
||||
{
|
||||
cspi->info->cbEvent(ARM_SPI_EVENT_TRANSFER_COMPLETE);
|
||||
}
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
CHECK_TO_UNLOCK_SLEEP(instance);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if (RTE_CSPI0)
|
||||
|
||||
static int32_t cspi0Init(cspiCbEvent_fn cbEvent)
|
||||
{
|
||||
return cspiInit(cbEvent, &cspi0Res);
|
||||
}
|
||||
static int32_t cspi0Deinit(void)
|
||||
{
|
||||
return cspiDeInit(&cspi0Res);
|
||||
}
|
||||
static int32_t cspi0PowerCtrl(cspiPowerState_e state)
|
||||
{
|
||||
return cspiPowerCtrl(state, &cspi0Res);
|
||||
}
|
||||
|
||||
static int32_t cspi0Recv(void)
|
||||
{
|
||||
return cspiRecv(&cspi0Res);
|
||||
}
|
||||
|
||||
static int32_t cspi0Ctrl(uint32_t control, uint32_t arg)
|
||||
{
|
||||
return cspiControl(control, arg, &cspi0Res);
|
||||
}
|
||||
|
||||
void cspi0DmaRxEvent(uint32_t event)
|
||||
{
|
||||
cspiDmaRxEvent(event, &cspi0Res);
|
||||
}
|
||||
|
||||
// CSPI0 Driver Control Block
|
||||
cspiDrvInterface_t cspiDrvInterface0 = {
|
||||
cspi0Init,
|
||||
cspi0Deinit,
|
||||
cspi0PowerCtrl,
|
||||
cspi0Recv,
|
||||
cspi0Ctrl,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if (RTE_CSPI1)
|
||||
static int32_t cspi1Init(cspiCbEvent_fn cbEvent)
|
||||
{
|
||||
return cspiInit(cbEvent, &cspi1Res);
|
||||
}
|
||||
static int32_t cspi1Deinit(void)
|
||||
{
|
||||
return cspiDeInit(&cspi1Res);
|
||||
}
|
||||
static int32_t cspi1PowerCtrl(cspiPowerState_e state)
|
||||
{
|
||||
return cspiPowerCtrl(state, &cspi1Res);
|
||||
}
|
||||
|
||||
static int32_t cspi1Recv(void)
|
||||
{
|
||||
return cspiRecv(&cspi1Res);
|
||||
}
|
||||
|
||||
static int32_t cspi1Ctrl(uint32_t control, uint32_t arg)
|
||||
{
|
||||
return cspiControl(control, arg, &cspi1Res);
|
||||
}
|
||||
|
||||
void cspi1DmaRxEvent(uint32_t event)
|
||||
{
|
||||
cspiDmaRxEvent(event, &cspi1Res);
|
||||
}
|
||||
|
||||
// CSPI1 Driver Control Block
|
||||
cspiDrvInterface_t cspiDrvInterface1 = {
|
||||
cspi1Init,
|
||||
cspi1Deinit,
|
||||
cspi1PowerCtrl,
|
||||
cspi1Recv,
|
||||
cspi1Ctrl,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2017-, Copyrigths of AirM2M Ltd.
|
||||
* File name: gpio.c
|
||||
* Description: EC618 gpio driver source file
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "gpio.h"
|
||||
#include "clock.h"
|
||||
#include "slpman.h"
|
||||
|
||||
#define EIGEN_GPIO(n) ((GPIO_TypeDef *) (MP_GPIO_BASE_ADDR + 0x1000*n))
|
||||
|
||||
/**
|
||||
\brief GPIO stutas flag
|
||||
*/
|
||||
static uint32_t gGpioStatus = 0;
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
/**
|
||||
\fn void GPIO_enterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
\brief Backup gpio configurations before sleep.
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
void GPIO_enterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
\fn void GPIO_exitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
\brief Restore gpio configurations after exit from sleep.
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
void GPIO_exitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
{
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
if(gGpioStatus & 0x1U)
|
||||
{
|
||||
GPR_clockEnable(PCLK_GPIO);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void GPIO_driverInit(void)
|
||||
{
|
||||
if((gGpioStatus & 0x1U) == 0)
|
||||
{
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
slpManRegisterPredefinedBackupCb(SLP_CALLBACK_GPIO_MODULE, GPIO_enterLowPowerStatePrepare, NULL);
|
||||
slpManRegisterPredefinedRestoreCb(SLP_CALLBACK_GPIO_MODULE, GPIO_exitLowPowerStateRestore, NULL);
|
||||
#endif
|
||||
CLOCK_clockEnable(PCLK_GPIO);
|
||||
|
||||
gGpioStatus = 0x1U;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GPIO_driverDeInit(void)
|
||||
{
|
||||
gGpioStatus = 0;
|
||||
|
||||
// disable clock
|
||||
CLOCK_clockDisable(PCLK_GPIO);
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
slpManUnregisterPredefinedBackupCb(SLP_CALLBACK_GPIO_MODULE);
|
||||
slpManUnregisterPredefinedRestoreCb(SLP_CALLBACK_GPIO_MODULE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void GPIO_pinConfig(uint32_t port, uint16_t pin, const GpioPinConfig_t *config)
|
||||
{
|
||||
ASSERT(port < GPIO_INSTANCE_NUM);
|
||||
|
||||
uint16_t pinMask = 0x1U << pin;
|
||||
GPIO_TypeDef *base = EIGEN_GPIO(port);
|
||||
|
||||
GPIO_driverInit();
|
||||
|
||||
switch(config->pinDirection)
|
||||
{
|
||||
case GPIO_DIRECTION_INPUT:
|
||||
|
||||
base->OUTENCLR = pinMask;
|
||||
|
||||
GPIO_interruptConfig(port, pin, config->misc.interruptConfig);
|
||||
|
||||
break;
|
||||
case GPIO_DIRECTION_OUTPUT:
|
||||
|
||||
GPIO_pinWrite(port, pinMask, ((uint16_t)config->misc.initOutput) << pin);
|
||||
|
||||
base->OUTENSET = pinMask;
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GPIO_interruptConfig(uint32_t port, uint16_t pin, GpioInterruptConfig_e config)
|
||||
{
|
||||
uint16_t pinMask = 0x1U << pin;
|
||||
GPIO_TypeDef *base = EIGEN_GPIO(port);
|
||||
|
||||
switch(config)
|
||||
{
|
||||
case GPIO_INTERRUPT_DISABLED:
|
||||
|
||||
base->INTENCLR = pinMask;
|
||||
|
||||
break;
|
||||
case GPIO_INTERRUPT_LOW_LEVEL:
|
||||
|
||||
base->INTPOLCLR = pinMask;
|
||||
base->INTTYPECLR = pinMask;
|
||||
base->INTENSET = pinMask;
|
||||
|
||||
break;
|
||||
case GPIO_INTERRUPT_HIGH_LEVEL:
|
||||
|
||||
base->INTPOLSET = pinMask;
|
||||
base->INTTYPECLR = pinMask;
|
||||
base->INTENSET = pinMask;
|
||||
|
||||
break;
|
||||
case GPIO_INTERRUPT_FALLING_EDGE:
|
||||
|
||||
base->INTPOLCLR = pinMask;
|
||||
base->INTTYPESET = pinMask;
|
||||
base->INTENSET = pinMask;
|
||||
|
||||
break;
|
||||
case GPIO_INTERRUPT_RISING_EDGE:
|
||||
|
||||
base->INTPOLSET = pinMask;
|
||||
base->INTTYPESET = pinMask;
|
||||
base->INTENSET = pinMask;
|
||||
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GPIO_pinWrite(uint32_t port, uint16_t pinMask, uint16_t output)
|
||||
{
|
||||
EIGEN_GPIO(port)->MASKLOWBYTE[pinMask & 0xFFU] = output;
|
||||
EIGEN_GPIO(port)->MASKHIGHBYTE[pinMask >> 8U] = output;
|
||||
}
|
||||
|
||||
uint32_t GPIO_pinRead(uint32_t port, uint16_t pin)
|
||||
{
|
||||
return (((EIGEN_GPIO(port)->DATA) >> pin) & 0x01U);
|
||||
}
|
||||
|
||||
uint16_t GPIO_getInterruptFlags(uint32_t port)
|
||||
{
|
||||
return EIGEN_GPIO(port)->INTSTATUS;
|
||||
}
|
||||
|
||||
void GPIO_clearInterruptFlags(uint32_t port, uint16_t mask)
|
||||
{
|
||||
EIGEN_GPIO(port)->INTSTATUS = mask;
|
||||
}
|
||||
|
||||
uint16_t GPIO_saveAndSetIrqMask(uint32_t port)
|
||||
{
|
||||
uint16_t mask = EIGEN_GPIO(port)->INTENSET;
|
||||
EIGEN_GPIO(port)->INTENCLR = 0xFFFFU;
|
||||
return mask;
|
||||
}
|
||||
|
||||
void GPIO_restoreIrqMask(uint32_t port, uint16_t mask)
|
||||
{
|
||||
EIGEN_GPIO(port)->INTENSET = mask;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,962 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
|
||||
* File name: i2s.c
|
||||
* Description: Audio use in EC618. The interface is similar with CMSIS Driver API V2.0.
|
||||
* History: Rev1.0 2021-06-23
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "i2s.h"
|
||||
#include "slpman.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// I2S Setting field Start
|
||||
// All the I2S's parameters that need user to set are all put here
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static DmaTransferConfig_t g_dmaTxConfig =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
DMA_FLOW_CONTROL_TARGET,
|
||||
DMA_ADDRESS_INCREMENT_SOURCE,
|
||||
DMA_DATA_WIDTH_FOUR_BYTES,
|
||||
DMA_BURST_64_BYTES,
|
||||
0
|
||||
};
|
||||
|
||||
static DmaTransferConfig_t g_dmaRxConfig =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
DMA_FLOW_CONTROL_SOURCE,
|
||||
DMA_ADDRESS_INCREMENT_TARGET,
|
||||
DMA_DATA_WIDTH_TWO_BYTES,
|
||||
DMA_BURST_8_BYTES,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
#if (RTE_I2S0)
|
||||
static PIN i2s0PinMCLK = {RTE_I2S0_MCLK_PAD_ADDR, RTE_I2S0_MCLK_FUNC};
|
||||
static PIN i2s0PinBCLK = {RTE_I2S0_BCLK_PAD_ADDR, RTE_I2S0_BCLK_FUNC};
|
||||
static PIN i2s0PinLRCK = {RTE_I2S0_LRCK_PAD_ADDR, RTE_I2S0_LRCK_FUNC};
|
||||
static PIN i2s0PinDin = {RTE_I2S0_DIN_PAD_ADDR, RTE_I2S0_DIN_FUNC};
|
||||
static PIN i2s0PinDout = {RTE_I2S0_DOUT_PAD_ADDR, RTE_I2S0_DOUT_FUNC};
|
||||
#elif (RTE_I2S1)
|
||||
static PIN i2s1PinMCLK = {RTE_I2S1_MCLK_PAD_ADDR, RTE_I2S1_MCLK_FUNC};
|
||||
static PIN i2s1PinBCLK = {RTE_I2S1_BCLK_PAD_ADDR, RTE_I2S1_BCLK_FUNC};
|
||||
static PIN i2s1PinLRCK = {RTE_I2S1_LRCK_PAD_ADDR, RTE_I2S1_LRCK_FUNC};
|
||||
static PIN i2s1PinDin = {RTE_I2S1_DIN_PAD_ADDR, RTE_I2S1_DIN_FUNC};
|
||||
static PIN i2s1PinDout = {RTE_I2S1_DOUT_PAD_ADDR, RTE_I2S1_DOUT_FUNC};
|
||||
#endif
|
||||
|
||||
|
||||
// Sample rate, fs, fracdiv part, integer part. Generate MClk accoding to the sample rate.
|
||||
const uint32_t i2sSampleRateTbl[][4] =
|
||||
{
|
||||
{SAMPLE_RATE_8K, 256, 0xCE0000, 0x31}, // 256fs, 8k
|
||||
{SAMPLE_RATE_16K, 256, 0xE70000, 0x18}, // 256fs, 16k
|
||||
{SAMPLE_RATE_32K, 256, 0x738000, 0x0C}, // 256fs, 32k
|
||||
{SAMPLE_RATE_22_05K,256, 0x11D9B0, 0x12}, // 256fs, 22.05k
|
||||
{SAMPLE_RATE_44_1K, 256, 0x08ECD8, 0x09}, // 256fs, 44.1k
|
||||
{SAMPLE_RATE_48K, 256, 0x4D0000, 0x08}, // 256fs, 48k
|
||||
{SAMPLE_RATE_96K, 256, 0x268000, 0x04}, // 256fs, 96k
|
||||
};
|
||||
|
||||
|
||||
// Data Format
|
||||
i2sDataFmt_t i2sDataFmt =
|
||||
{
|
||||
.slaveModeEn = 0x1, // 0:Master; 1:Slave mode
|
||||
.slotSize = 0xf, // Slot size
|
||||
.wordSize = 0xf, // Real word size
|
||||
.alignMode = 0, // 1: Right alignment; 0: Left alignment
|
||||
.endianMode = 0x1, // 1: MSB; 0: LSB
|
||||
.dataDly = 0, // Used by I2S format
|
||||
.txPad = 0, // Tx padding
|
||||
.rxSignExt = 0, // Rx sign external
|
||||
.txPack = 1, // 0: not compress; 1: 1word; 2: 2word
|
||||
.rxPack = 0, // 0: not compress; 1: 1word; 2: 2word
|
||||
.txFifoEndianMode = 0, // I2s use or cspi use?
|
||||
.rxFifoEndianMode = 0, // I2s use or cspi use?
|
||||
};
|
||||
|
||||
// Slot Control
|
||||
i2sSlotCtrl_t i2sSlotCtrl =
|
||||
{
|
||||
.slotEn = 0x1, // Total 8 channels
|
||||
.slotNum = 0x1 // For I2S, this value should be 1; For PCM, it can change
|
||||
};
|
||||
|
||||
// BclkFs Control
|
||||
i2sBclkFsCtrl_t i2sBclkFsCtrl =
|
||||
{
|
||||
.bclkPolarity = 1, // 0: Rising edge send, falling edge sample; 1: falling edge send, rising edge sample
|
||||
.fsPolarity = 0, // 0: rising edge start; 1: falling edge start
|
||||
.fsWidth = 0xf // fsWidth = slotNum * slotSize
|
||||
};
|
||||
|
||||
// I2S Control
|
||||
i2sCtrl_t i2sCtrl =
|
||||
{
|
||||
.i2sMode = 1, // 0: disable; 1: Only send; 2: Only receive; 3: Send and Receive
|
||||
};
|
||||
|
||||
// DMA Control
|
||||
i2sDmaCtrl_t i2sDmaCtrl =
|
||||
{
|
||||
.rxDmaReqEn = 0, // rx dma enable
|
||||
.txDmaReqEn = 1, // tx dma enable
|
||||
.rxDmaTimeOutEn = 0, // rx dma timeout enable
|
||||
.dmaWorkWaitCycle = 31, // dma wait cycle number
|
||||
.rxDmaBurstSizeSub1 = 7, // rx dma burst size -1
|
||||
.txDmaBurstSizeSub1 = 15, // tx dma burst size -1
|
||||
.rxDmaThreadHold = 8, // rx dma threshold
|
||||
.txDmaThreadHold = 15, // tx dma threshold
|
||||
.rxFifoFlush = 0, // flush rx fifo
|
||||
.txFifoFlush = 0 // flush tx fifo
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// I2S Setting field End
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if (RTE_I2S0)
|
||||
static i2sInfo_t i2s0Info = {0};
|
||||
void i2s0DmaRxEvent(uint32_t event);
|
||||
void i2s0DmaTxEvent(uint32_t event);
|
||||
DmaDescriptor_t __ALIGNED(16) i2s0DmaTxDesc[I2S_DMA_TX_DESCRIPTOR_CHAIN_NUM];
|
||||
DmaDescriptor_t __ALIGNED(16) i2s0DmaRxDesc[I2S_DMA_RX_DESCRIPTOR_CHAIN_NUM];
|
||||
|
||||
#if (RTE_I2S0_IO_MODE == DMA_MODE)
|
||||
static i2sDma_t i2s0Dma =
|
||||
{
|
||||
DMA_INSTANCE_MP,
|
||||
-1,
|
||||
RTE_I2S0_DMA_TX_REQID,
|
||||
i2s0DmaTxEvent,
|
||||
i2s0DmaTxDesc,
|
||||
|
||||
DMA_INSTANCE_MP,
|
||||
-1,
|
||||
RTE_I2S0_DMA_RX_REQID,
|
||||
i2s0DmaRxEvent,
|
||||
i2s0DmaRxDesc
|
||||
};
|
||||
#endif
|
||||
|
||||
static i2sResources_t i2s0Res = {
|
||||
I2S0,
|
||||
{
|
||||
&i2s0PinMCLK,
|
||||
&i2s0PinBCLK,
|
||||
&i2s0PinLRCK,
|
||||
&i2s0PinDin,
|
||||
&i2s0PinDout,
|
||||
},
|
||||
#if (RTE_I2S0_IO_MODE == DMA_MODE)
|
||||
&i2s0Dma,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
NULL,
|
||||
&i2s0Info
|
||||
};
|
||||
#endif
|
||||
|
||||
#if (RTE_I2S1)
|
||||
|
||||
static i2sInfo_t i2s1Info = {0};
|
||||
void i2s1DmaRxEvent(uint32_t event);
|
||||
void i2s1DmaTxEvent(uint32_t event);
|
||||
static DmaDescriptor_t __ALIGNED(16) i2s1DmaTxDesc[I2S_DMA_TX_DESCRIPTOR_CHAIN_NUM];
|
||||
static DmaDescriptor_t __ALIGNED(16) i2s1DmaRxDesc[I2S_DMA_RX_DESCRIPTOR_CHAIN_NUM];
|
||||
|
||||
static i2sDma_t i2s1Dma =
|
||||
{
|
||||
DMA_INSTANCE_MP,
|
||||
-1,
|
||||
RTE_I2S1_DMA_TX_REQID,
|
||||
i2s1DmaTxEvent,
|
||||
i2s1DmaTxDesc,
|
||||
|
||||
DMA_INSTANCE_MP,
|
||||
-1,
|
||||
RTE_I2S1_DMA_RX_REQID,
|
||||
i2s1DmaRxEvent,
|
||||
i2s1DmaRxDesc
|
||||
};
|
||||
|
||||
static i2sResources_t i2s1Res = {
|
||||
I2S1,
|
||||
{
|
||||
&i2s1PinMCLK,
|
||||
&i2s1PinBCLK,
|
||||
&i2s1PinLRCK,
|
||||
&i2s1PinDin,
|
||||
&i2s1PinDout,
|
||||
},
|
||||
#if (RTE_I2S1_IO_MODE == DMA_MODE)
|
||||
&i2s1Dma,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
NULL,
|
||||
&i2s1Info
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static I2S_TypeDef* const i2sInstance[I2S_INSTANCE_NUM] = {I2S0, I2S1};
|
||||
|
||||
static ClockId_e i2sClk[I2S_INSTANCE_NUM * 2] =
|
||||
{
|
||||
PCLK_I2S0,
|
||||
FCLK_I2S0,
|
||||
PCLK_I2S1,
|
||||
FCLK_I2S1
|
||||
};
|
||||
|
||||
static ClockId_e i2sMClk[I2S_INSTANCE_NUM] =
|
||||
{
|
||||
MCLK0,
|
||||
MCLK1,
|
||||
};
|
||||
|
||||
static ClockResetId_e i2sRstClk[I2S_INSTANCE_NUM * 2] =
|
||||
{
|
||||
RST_PCLK_I2S0,
|
||||
RST_FCLK_I2S0,
|
||||
RST_PCLK_I2S1,
|
||||
RST_FCLK_I2S1
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
|
||||
/** \brief Internal used data structure */
|
||||
typedef struct
|
||||
{
|
||||
bool isInited; /**< Whether spi has been initialized */
|
||||
bool mclkHasBeenClosed; /**< 1: mclk has been closed; 0: mclk hasn't been closed */
|
||||
struct
|
||||
{
|
||||
__IO uint32_t DFMT; /**< Data Format Register, offset: 0x0 */
|
||||
__IO uint32_t SLOTCTL; /**< Slot Control Register, offset: 0x4 */
|
||||
__IO uint32_t CLKCTL; /**< Clock Control Register, offset: 0x8 */
|
||||
__IO uint32_t DMACTL; /**< DMA Control Register, offset: 0xC */
|
||||
__IO uint32_t INTCTL; /**< Interrupt Control Register, offset: 0x10 */
|
||||
__IO uint32_t TIMEOUTCTL; /**< Timeout Control Register, offset: 0x14 */
|
||||
__IO uint32_t STAS; /**< Status Register, offset: 0x18 */
|
||||
__IO uint32_t RFIFO; /**< Rx Buffer Register, offset: 0x1c */
|
||||
__IO uint32_t TFIFO; /**< Tx Buffer Register, offset: 0x20 */
|
||||
__IO uint32_t I2SCTL; /**< I2S Control Register, offset: 0x28 */
|
||||
}regsBackup;
|
||||
} i2sDataBase_t;
|
||||
|
||||
static i2sDataBase_t i2sDataBase[I2S_INSTANCE_NUM] = {0};
|
||||
/**
|
||||
\brief i2s initialization counter, for lower power callback register/de-register
|
||||
*/
|
||||
static uint32_t i2sInitCnt = 0;
|
||||
|
||||
/**
|
||||
\brief Bitmap of I2S working status, each instance is assigned 2 bits representing tx and rx status,
|
||||
when all I2S instances are not working, we can vote to enter to low power state.
|
||||
*/
|
||||
|
||||
volatile uint32_t i2sWorkingStats = 0;
|
||||
|
||||
|
||||
/**
|
||||
\fn static void i2sEnterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
\brief Perform necessary preparations before sleep.
|
||||
After recovering from SLPMAN_SLEEP1_STATE, I2S hareware is repowered, we backup
|
||||
some registers here first so that we can restore user's configurations after exit.
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
static void i2sEnterLpStatePrepare(void* pdata, slpManLpState state)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
for(i = 0; i < I2S_INSTANCE_NUM; i++)
|
||||
{
|
||||
if(i2sDataBase[i].isInited == true)
|
||||
{
|
||||
GPR_mclkDisable(i2sMClk[i]); // before sleep, disable MCLK
|
||||
i2sDataBase[i].mclkHasBeenClosed = true;
|
||||
|
||||
i2sDataBase[i].regsBackup.DFMT = i2sInstance[i]->DFMT;
|
||||
i2sDataBase[i].regsBackup.SLOTCTL = i2sInstance[i]->SLOTCTL;
|
||||
i2sDataBase[i].regsBackup.CLKCTL = i2sInstance[i]->CLKCTL;
|
||||
i2sDataBase[i].regsBackup.DMACTL = i2sInstance[i]->DMACTL;
|
||||
i2sDataBase[i].regsBackup.INTCTL = i2sInstance[i]->INTCTL;
|
||||
i2sDataBase[i].regsBackup.TIMEOUTCTL = i2sInstance[i]->TIMEOUTCTL;
|
||||
i2sDataBase[i].regsBackup.STAS = i2sInstance[i]->STAS;
|
||||
i2sDataBase[i].regsBackup.I2SCTL = i2sInstance[i]->I2SCTL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\fn static void i2sExitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
\brief Restore after exit from sleep.
|
||||
After recovering from SLPMAN_SLEEP1_STATE, I2S hareware is repowered, we restore user's configurations
|
||||
by aidding of the stored registers.
|
||||
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
static void i2sExitLpStateRestore(void* pdata, slpManLpState state)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
for(i = 0; i < I2S_INSTANCE_NUM; i++)
|
||||
{
|
||||
if(i2sDataBase[i].isInited == true)
|
||||
{
|
||||
GPR_clockEnable(i2sClk[i*2]);
|
||||
GPR_clockEnable(i2sClk[i*2 + 1]);
|
||||
|
||||
i2sInstance[i]->DFMT = i2sDataBase[i].regsBackup.DFMT;
|
||||
i2sInstance[i]->SLOTCTL = i2sDataBase[i].regsBackup.SLOTCTL;
|
||||
i2sInstance[i]->CLKCTL = i2sDataBase[i].regsBackup.CLKCTL;
|
||||
i2sInstance[i]->DMACTL = i2sDataBase[i].regsBackup.DMACTL;
|
||||
i2sInstance[i]->INTCTL = i2sDataBase[i].regsBackup.INTCTL;
|
||||
i2sInstance[i]->TIMEOUTCTL = i2sDataBase[i].regsBackup.TIMEOUTCTL;
|
||||
i2sInstance[i]->STAS = i2sDataBase[i].regsBackup.STAS;
|
||||
i2sInstance[i]->I2SCTL = i2sDataBase[i].regsBackup.I2SCTL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define LOCK_SLEEP(instance) \
|
||||
do \
|
||||
{ \
|
||||
i2sWorkingStats |= (1U << instance); \
|
||||
slpManDrvVoteSleep(SLP_VOTE_I2S, SLP_ACTIVE_STATE); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define CHECK_TO_UNLOCK_SLEEP(instance) \
|
||||
do \
|
||||
{ \
|
||||
i2sWorkingStats &= ~(1U << instance); \
|
||||
if(i2sWorkingStats == 0) \
|
||||
slpManDrvVoteSleep(SLP_VOTE_I2S, SLP_SLP1_STATE); \
|
||||
} \
|
||||
while(0)
|
||||
#endif
|
||||
|
||||
static uint32_t i2sGetInstanceNum(i2sResources_t *i2s)
|
||||
{
|
||||
return ((uint32_t)i2s->reg - (uint32_t)I2S0) >> 12U;
|
||||
}
|
||||
|
||||
int32_t i2sInit(i2sCbEvent_fn txCbEvent, i2sCbEvent_fn rxCbEvent, i2sResources_t *i2s)
|
||||
{
|
||||
int32_t returnCode;
|
||||
PadConfig_t config;
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
uint32_t instance = i2sGetInstanceNum(i2s);
|
||||
i2sDataBase[instance].isInited = true;
|
||||
#endif
|
||||
|
||||
// Initialize I2S PINS
|
||||
PAD_getDefaultConfig(&config);
|
||||
config.mux = i2s->pins.mclk->funcNum;
|
||||
PAD_setPinConfig(i2s->pins.mclk->pinNum, &config);
|
||||
config.mux = i2s->pins.bclk->funcNum;
|
||||
PAD_setPinConfig(i2s->pins.bclk->pinNum, &config);
|
||||
config.mux = i2s->pins.lrck->funcNum;
|
||||
PAD_setPinConfig(i2s->pins.lrck->pinNum, &config);
|
||||
config.mux = i2s->pins.din->funcNum;
|
||||
PAD_setPinConfig(i2s->pins.din->pinNum, &config);
|
||||
config.mux = i2s->pins.dout->funcNum;
|
||||
PAD_setPinConfig(i2s->pins.dout->pinNum, &config);
|
||||
|
||||
// Initialize I2S run-time resources
|
||||
i2s->info->txCbEvent = txCbEvent;
|
||||
i2s->info->rxCbEvent = rxCbEvent;
|
||||
|
||||
// Configure DMA if necessary
|
||||
if (i2s->dma)
|
||||
{
|
||||
// Tx config
|
||||
DMA_init(i2s->dma->txInstance);
|
||||
returnCode = DMA_openChannel(i2s->dma->txInstance);
|
||||
|
||||
if (returnCode == ARM_DMA_ERROR_CHANNEL_ALLOC)
|
||||
return ARM_DRIVER_ERROR;
|
||||
else
|
||||
i2s->dma->txCh = returnCode;
|
||||
|
||||
DMA_setChannelRequestSource(i2s->dma->txInstance, i2s->dma->txCh, (DmaRequestSource_e)i2s->dma->txReq);
|
||||
DMA_rigisterChannelCallback(i2s->dma->txInstance, i2s->dma->txCh, i2s->dma->txCb);
|
||||
|
||||
// Rx config
|
||||
DMA_init(i2s->dma->rxInstance);
|
||||
returnCode = DMA_openChannel(i2s->dma->rxInstance);
|
||||
|
||||
if (returnCode == ARM_DMA_ERROR_CHANNEL_ALLOC)
|
||||
return ARM_DRIVER_ERROR;
|
||||
else
|
||||
i2s->dma->rxCh = returnCode;
|
||||
|
||||
DMA_setChannelRequestSource(i2s->dma->rxInstance, i2s->dma->rxCh, (DmaRequestSource_e)i2s->dma->rxReq);
|
||||
DMA_rigisterChannelCallback(i2s->dma->rxInstance, i2s->dma->rxCh, i2s->dma->rxCb);
|
||||
}
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
i2sInitCnt++;
|
||||
|
||||
if(i2sInitCnt == 1U)
|
||||
{
|
||||
i2sWorkingStats = 0;
|
||||
slpManRegisterPredefinedBackupCb(SLP_CALLBACK_I2S_MODULE, i2sEnterLpStatePrepare, NULL);
|
||||
slpManRegisterPredefinedRestoreCb(SLP_CALLBACK_I2S_MODULE, i2sExitLpStateRestore, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
|
||||
int32_t i2sDeInit(i2sResources_t *i2s)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
uint32_t instance = i2sGetInstanceNum(i2s);
|
||||
i2sDataBase[instance].isInited = false;
|
||||
|
||||
i2sInitCnt--;
|
||||
|
||||
if(i2sInitCnt == 0)
|
||||
{
|
||||
i2sWorkingStats = 0;
|
||||
slpManUnregisterPredefinedBackupCb(SLP_CALLBACK_I2S_MODULE);
|
||||
slpManUnregisterPredefinedRestoreCb(SLP_CALLBACK_I2S_MODULE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
int32_t i2sPowerCtrl(i2sPowerState_e state, i2sResources_t *i2s)
|
||||
{
|
||||
uint32_t instance = i2sGetInstanceNum(i2s);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
// when need to enter sleep, do not call this api. PMU will manage all the clocks by default.
|
||||
case I2S_POWER_OFF:
|
||||
if(i2s->dma)
|
||||
{
|
||||
DMA_stopChannel(i2s->dma->txInstance, i2s->dma->txCh, false);
|
||||
}
|
||||
|
||||
// Reset register values
|
||||
if (instance == 0)
|
||||
{
|
||||
CLOCK_setClockSrc(FCLK_I2S0, FCLK_I2S0_SEL_26M);
|
||||
GPR_swReset(RST_PCLK_I2S0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLOCK_setClockSrc(FCLK_I2S1, FCLK_I2S1_SEL_26M);
|
||||
GPR_swReset(RST_PCLK_I2S1);
|
||||
}
|
||||
|
||||
// Disable I2S clock
|
||||
CLOCK_clockDisable(i2sClk[instance*2]);
|
||||
CLOCK_clockDisable(i2sClk[instance*2+1]);
|
||||
|
||||
break;
|
||||
|
||||
case I2S_POWER_FULL:
|
||||
|
||||
// Enable I2S clock
|
||||
CLOCK_clockEnable(i2sClk[instance*2]); // pclk
|
||||
CLOCK_clockEnable(i2sClk[instance*2+1]); // fclk
|
||||
|
||||
GPR_swReset(i2sRstClk[instance*2]); // pclk
|
||||
GPR_swReset(i2sRstClk[instance*2+1]); // fclk
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARM_DRIVER_ERROR_UNSUPPORTED;
|
||||
}
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
int32_t i2sSend(const void *data, uint32_t chunkNum, i2sResources_t *i2s)
|
||||
{
|
||||
uint32_t instance = i2sGetInstanceNum(i2s);
|
||||
|
||||
if ((data == NULL) || (chunkNum == 0))
|
||||
return ARM_DRIVER_ERROR_PARAMETER;
|
||||
|
||||
// dma mode
|
||||
if(i2s->dma)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
LOCK_SLEEP(instance);
|
||||
#endif
|
||||
|
||||
// Configure tx DMA and start it
|
||||
g_dmaTxConfig.sourceAddress = (void *)data;
|
||||
g_dmaTxConfig.targetAddress = (void *)&(i2sInstance[instance]->TFIFO);
|
||||
g_dmaTxConfig.totalLength = chunkNum;
|
||||
DMA_buildDescriptorChain(i2s->dma->txDescriptor, &g_dmaTxConfig, I2S_DMA_TX_DESCRIPTOR_CHAIN_NUM, true);
|
||||
DMA_loadChannelDescriptorAndRun(i2s->dma->txInstance, i2s->dma->txCh, i2s->dma->txDescriptor);
|
||||
}
|
||||
// polling mode
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < chunkNum; i++)
|
||||
{
|
||||
// Flow control. Make sure TX have empty fifo
|
||||
while (((16 - (i2s->reg->STAS & I2S_STATS_CTRL_TX_FIFO_LEVEL_Msk))
|
||||
>> I2S_STATS_CTRL_TX_FIFO_LEVEL_Pos) == 0){};
|
||||
|
||||
i2s->reg->TFIFO = *(uint32_t*)data;
|
||||
}
|
||||
}
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
|
||||
int32_t i2sRecv(void *data, uint32_t chunkNum, i2sResources_t *i2s)
|
||||
{
|
||||
uint32_t instance = i2sGetInstanceNum(i2s);;
|
||||
|
||||
if ((data == NULL) || (chunkNum == 0))
|
||||
return ARM_DRIVER_ERROR_PARAMETER;
|
||||
|
||||
// dma mode
|
||||
if(i2s->dma)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
LOCK_SLEEP(instance);
|
||||
#endif
|
||||
|
||||
// Configure rx DMA and start it
|
||||
g_dmaRxConfig.sourceAddress = (void *)&(i2sInstance[instance]->RFIFO);
|
||||
g_dmaRxConfig.targetAddress = (void *)data;
|
||||
g_dmaRxConfig.totalLength = chunkNum;
|
||||
DMA_buildDescriptorChain(i2s->dma->rxDescriptor, &g_dmaRxConfig, I2S_DMA_RX_DESCRIPTOR_CHAIN_NUM, true);
|
||||
DMA_loadChannelDescriptorAndRun(i2s->dma->rxInstance, i2s->dma->rxCh, i2s->dma->rxDescriptor);
|
||||
}
|
||||
// polling mode
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < chunkNum; i++)
|
||||
{
|
||||
while (((i2s->reg->STAS >> I2S_STATS_CTRL_RX_DAT_RDY_Pos) & 0x1) == 0); // Wait until RxFifo have data
|
||||
*((uint32_t*)data + i) = i2s->reg->RFIFO;
|
||||
}
|
||||
}
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\fn static int32_t i2sSetBusSpeed(uint32_t bps, i2sResources_t *i2s)
|
||||
\brief Set bus speed
|
||||
\param[in] bps bus speed to set
|
||||
\param[in] spi Pointer to SPI resources
|
||||
\return \ref execution_status
|
||||
*/
|
||||
static int32_t i2sSetSampleRate(uint32_t bps, i2sResources_t *i2s, i2sRole_e i2sRole)
|
||||
{
|
||||
uint32_t instance = i2sGetInstanceNum(i2s);
|
||||
|
||||
if (instance == 0) // i2s0
|
||||
{
|
||||
CLOCK_clockEnable(FCLK_I2S0);
|
||||
}
|
||||
else // i2s1
|
||||
{
|
||||
CLOCK_clockEnable(FCLK_I2S1);
|
||||
}
|
||||
|
||||
CLOCK_setClockSrc(CLK_CC, CLK_CC_SEL_204M); // Core clk selects 204M
|
||||
|
||||
if (instance == 0) // i2s0
|
||||
{
|
||||
CLOCK_fracDivOutCLkEnable(FRACDIV0_OUT0); // Fracdiv0 out0 enable
|
||||
CLOCK_setMclkSrc(MCLK0, MCLK_SRC_FRACDIV0_OUT0); // Choose Fracdiv0 out0 as MClk source
|
||||
CLOCK_mclkEnable(MCLK0); // Mclk enable
|
||||
CLOCK_setFracDivOutClkDiv(FRACDIV0_OUT0, 4); // First step to generate MClk clock. 4 div, from 408M -> 102M
|
||||
|
||||
// need to add gpr api for fracdiv
|
||||
int sampleRateIdx;
|
||||
for (sampleRateIdx = 0; sampleRateIdx < sizeof(i2sSampleRateTbl) / sizeof(i2sSampleRateTbl[0]); sampleRateIdx++)
|
||||
{
|
||||
if (bps == i2sSampleRateTbl[sampleRateIdx][0])
|
||||
{
|
||||
// Fracdiv clk selects 408M and set frac and integer clk
|
||||
FracDivConfig_t fracdivCfg;
|
||||
memset(&fracdivCfg, 0, sizeof(FracDivConfig_t));
|
||||
fracdivCfg.source = FRACDIC_ROOT_CLK_408M;
|
||||
fracdivCfg.fracDiv0DivRatioInteger = i2sSampleRateTbl[sampleRateIdx][3];
|
||||
fracdivCfg.fracDiv0DivRatioFrac = i2sSampleRateTbl[sampleRateIdx][2];
|
||||
CLOCK_setFracDivConfig(&fracdivCfg); // Second step to generate MClk
|
||||
}
|
||||
}
|
||||
}
|
||||
else // i2s1
|
||||
{
|
||||
CLOCK_fracDivOutCLkEnable(FRACDIV1_OUT0); // Fracdiv1 out0 enable
|
||||
CLOCK_setMclkSrc(MCLK1, MCLK_SRC_FRACDIV1_OUT0); // Choose Fracdiv1 out0 as MClk source
|
||||
CLOCK_mclkEnable(MCLK1); // Mclk enable
|
||||
CLOCK_setFracDivOutClkDiv(FRACDIV1_OUT0, 4); // First step to generate MClk clock. 4 div, from 408M -> 102M
|
||||
|
||||
// need to add gpr api for fracdiv
|
||||
int sampleRateIdx;
|
||||
for (sampleRateIdx = 0; sampleRateIdx < sizeof(i2sSampleRateTbl) / sizeof(i2sSampleRateTbl[0]); sampleRateIdx++)
|
||||
{
|
||||
if (bps == i2sSampleRateTbl[sampleRateIdx][0])
|
||||
{
|
||||
// Fracdiv clk selects 408M and set frac and integer clk
|
||||
FracDivConfig_t fracdivCfg;
|
||||
memset(&fracdivCfg, 0, sizeof(FracDivConfig_t));
|
||||
fracdivCfg.source = FRACDIC_ROOT_CLK_408M;
|
||||
fracdivCfg.fracDiv1DivRatioInteger = i2sSampleRateTbl[sampleRateIdx][3];
|
||||
fracdivCfg.fracDiv1DivRatioFrac = i2sSampleRateTbl[sampleRateIdx][2];
|
||||
CLOCK_setFracDivConfig(&fracdivCfg); // Second step to generate MClk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (instance == 0)
|
||||
{
|
||||
// I2S master mode need to genetate LRCLK by MCU
|
||||
if (i2sRole == CODEC_SLAVE_MODE) // I2S controller act as master, codec is slave
|
||||
{
|
||||
CLOCK_fracDivOutCLkEnable(FRACDIV0_OUT1); // Enable fracdiv0 out1
|
||||
CLOCK_setBclkSrc(BCLK0, BCLK_SRC_FRACDIV0_OUT1); // Use fracdiv0 out1 to generate bclk
|
||||
CLOCK_setFracDivOutClkDiv(FRACDIV0_OUT1, 8); // First step to generate BClk clock. 8 div, from 408M->51M
|
||||
CLOCK_setBclkDiv(BCLK0, 4); // Second step to generate BClk clock. Bclk enable and divide by 4(256fs)
|
||||
CLOCK_bclkEnable(BCLK0); // Enable bclk
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// I2S master mode need to genetate LRCLK by MCU
|
||||
if (i2sRole == CODEC_SLAVE_MODE) // I2S controller act as master, codec is slave
|
||||
{
|
||||
CLOCK_fracDivOutCLkEnable(FRACDIV1_OUT1); // Enable fracdiv1 out1
|
||||
CLOCK_setBclkSrc(BCLK1, BCLK_SRC_FRACDIV1_OUT1); // Use fracdiv1 out1 to generate bclk
|
||||
CLOCK_setFracDivOutClkDiv(FRACDIV1_OUT1, 8); // First step to generate BClk clock. 8 div, from 408M->51M
|
||||
CLOCK_setBclkDiv(BCLK1, 4); // Second step to generate BClk clock. Bclk enable and divide by 4(256fs)
|
||||
CLOCK_bclkEnable(BCLK1); // Enable bclk
|
||||
}
|
||||
}
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\fn int32_t i2sControl(uint32_t control, uint32_t arg, i2sRes_t *i2s)
|
||||
\brief Control I2S Interface.
|
||||
\param[in] control Operation
|
||||
\param[in] arg Argument of operation (optional)
|
||||
\param[in] i2s Pointer to I2S resources
|
||||
\return common \ref execution_status and driver specific \ref spi_execution_status
|
||||
*/
|
||||
int32_t i2sControl(uint32_t control, uint32_t arg, i2sResources_t *i2s)
|
||||
{
|
||||
uint32_t instance = i2sGetInstanceNum(i2s);
|
||||
|
||||
switch(control & 0xFFFF)
|
||||
{
|
||||
// Set transport abort
|
||||
case I2S_CTRL_TRANSABORT:
|
||||
{
|
||||
// If DMA mode, disable DMA channel
|
||||
if(i2s->dma)
|
||||
{
|
||||
DMA_stopChannel(i2s->dma->txInstance, i2s->dma->txCh, true);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case I2S_CTRL_SET_TOTAL_NUM:
|
||||
{
|
||||
i2s->info->totalNum = arg;
|
||||
}
|
||||
|
||||
// Set Bus Speed in bps; arg = value
|
||||
case I2S_CTRL_SAMPLE_RATE_SLAVE:
|
||||
{
|
||||
if(i2sSetSampleRate(arg, i2s, CODEC_MASTER_MODE) != ARM_DRIVER_OK)
|
||||
{
|
||||
return ARM_DRIVER_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case I2S_CTRL_SAMPLE_RATE_MASTER:
|
||||
{
|
||||
if(i2sSetSampleRate(arg, i2s, CODEC_SLAVE_MODE) != ARM_DRIVER_OK)
|
||||
{
|
||||
return ARM_DRIVER_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Set Data Format
|
||||
case I2S_CTRL_DATA_FORMAT:
|
||||
{
|
||||
memcpy((void*)&(i2sInstance[instance]->DFMT), &i2sDataFmt, sizeof(i2sDataFmt_t));
|
||||
break;
|
||||
}
|
||||
|
||||
// Set Slot
|
||||
case I2S_CTRL_SLOT_CTRL:
|
||||
{
|
||||
memcpy((void*)&(i2sInstance[instance]->SLOTCTL), &i2sSlotCtrl, sizeof(i2sSlotCtrl_t));
|
||||
break;
|
||||
}
|
||||
|
||||
// Set DMA Control
|
||||
case I2S_CTRL_DMA_CTRL:
|
||||
{
|
||||
memcpy((void*)&(i2sInstance[instance]->DMACTL), &i2sDmaCtrl, sizeof(i2sDmaCtrl_t));
|
||||
break;
|
||||
}
|
||||
|
||||
// Set I2S Control
|
||||
case I2S_CTRL_I2SCTL:
|
||||
{
|
||||
memcpy((void*)&(i2sInstance[instance]->I2SCTL), &i2sCtrl, sizeof(i2sCtrl_t));
|
||||
break;
|
||||
}
|
||||
|
||||
// Set Frame Info0
|
||||
case I2S_CTRL_BCLK_FS_CTRL:
|
||||
{
|
||||
memcpy((void*)&(i2sInstance[instance]->CLKCTL), &i2sBclkFsCtrl, sizeof(i2sBclkFsCtrl_t));
|
||||
break;
|
||||
}
|
||||
|
||||
// Start or stop audio play
|
||||
case I2S_CTRL_START_STOP:
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
if (i2sDataBase[instance].mclkHasBeenClosed == true)
|
||||
{
|
||||
GPR_mclkEnable(i2sMClk[instance]);
|
||||
i2sDataBase[instance].mclkHasBeenClosed = false; // already opened MCLK now
|
||||
}
|
||||
#endif
|
||||
i2sInstance[instance]->I2SCTL = arg; // 0: disable i2s; 1: enable send; 2: enable recv; 3: enable send/recv
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return ARM_DRIVER_ERROR_UNSUPPORTED;
|
||||
}
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
void i2sDmaRxEvent(uint32_t event, i2sResources_t *i2s)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
uint32_t instance = i2sGetInstanceNum(i2s);
|
||||
#endif
|
||||
|
||||
switch(event)
|
||||
{
|
||||
case DMA_EVENT_END:
|
||||
//DMA_stopChannel(i2s->dma->rxInstance, i2s->dma->rxCh, true);
|
||||
//i2s->reg->I2SCTL &= ~I2S_CTL_MODE_Msk;
|
||||
|
||||
if(i2s->info->rxCbEvent)
|
||||
{
|
||||
i2s->info->rxCbEvent(I2S_EVENT_TRANSFER_COMPLETE, 0);
|
||||
}
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
CHECK_TO_UNLOCK_SLEEP(instance);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void i2sDmaTxEvent(uint32_t event, i2sResources_t *i2s)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
uint32_t instance = i2sGetInstanceNum(i2s);
|
||||
#endif
|
||||
|
||||
switch(event)
|
||||
{
|
||||
case DMA_EVENT_END:
|
||||
#if 0 // If you want to loop the audio, don't stop DMA here
|
||||
DMA_stopChannel(i2s->dma->txInstance, i2s->dma->txCh, true);
|
||||
i2s->info->status.busy = 0;
|
||||
i2s->reg->I2SCTL &= ~I2S_CTL_MODE_Msk;
|
||||
#endif
|
||||
if(i2s->info->txCbEvent)
|
||||
{
|
||||
i2s->info->txCbEvent(I2S_EVENT_TRANSFER_COMPLETE, i2s->info->totalNum);
|
||||
}
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
CHECK_TO_UNLOCK_SLEEP(instance);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t i2sGetTotalCnt(i2sResources_t *i2s)
|
||||
{
|
||||
return i2s->info->totalNum;
|
||||
}
|
||||
|
||||
|
||||
#if (RTE_I2S0)
|
||||
|
||||
static int32_t i2s0Init(i2sCbEvent_fn txCbEvent, i2sCbEvent_fn rxCbEvent)
|
||||
{
|
||||
return i2sInit(txCbEvent, rxCbEvent, &i2s0Res);
|
||||
}
|
||||
static int32_t i2s0Deinit(void)
|
||||
{
|
||||
return i2sDeInit(&i2s0Res);
|
||||
}
|
||||
static int32_t i2s0PowerCtrl(i2sPowerState_e state)
|
||||
{
|
||||
return i2sPowerCtrl(state, &i2s0Res);
|
||||
}
|
||||
|
||||
static int32_t i2s0Send(void *data, uint32_t num)
|
||||
{
|
||||
return i2sSend(data, num, &i2s0Res);
|
||||
}
|
||||
|
||||
static int32_t i2s0Recv(void *data, uint32_t num)
|
||||
{
|
||||
return i2sRecv(data, num, &i2s0Res);
|
||||
}
|
||||
|
||||
static int32_t i2s0Ctrl(uint32_t control, uint32_t arg)
|
||||
{
|
||||
return i2sControl(control, arg, &i2s0Res);
|
||||
}
|
||||
|
||||
void i2s0DmaTxEvent(uint32_t event)
|
||||
{
|
||||
i2sDmaTxEvent(event, &i2s0Res);
|
||||
}
|
||||
|
||||
void i2s0DmaRxEvent(uint32_t event)
|
||||
{
|
||||
i2sDmaRxEvent(event, &i2s0Res);
|
||||
}
|
||||
|
||||
uint32_t i2s0GetTotalCnt(void)
|
||||
{
|
||||
return i2sGetTotalCnt(&i2s0Res);
|
||||
}
|
||||
|
||||
// I2S0 Driver Control Block
|
||||
i2sDrvInterface_t i2sDrvInterface0 =
|
||||
{
|
||||
i2s0Init,
|
||||
i2s0Deinit,
|
||||
i2s0PowerCtrl,
|
||||
i2s0Send,
|
||||
i2s0Recv,
|
||||
i2s0Ctrl,
|
||||
i2s0GetTotalCnt,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if (RTE_I2S1)
|
||||
static int32_t i2s1Init(i2sCbEvent_fn txCbEvent, i2sCbEvent_fn rxCbEvent)
|
||||
{
|
||||
return i2sInit(txCbEvent, rxCbEvent, &i2s1Res);
|
||||
}
|
||||
static int32_t i2s1Deinit(void)
|
||||
{
|
||||
return i2sDeInit(&i2s1Res);
|
||||
}
|
||||
static int32_t i2s1PowerCtrl(i2sPowerState_e state)
|
||||
{
|
||||
return i2sPowerCtrl(state, &i2s1Res);
|
||||
}
|
||||
|
||||
static int32_t i2s1Send(void *data, uint32_t num)
|
||||
{
|
||||
return i2sSend(data, num, &i2s1Res);
|
||||
}
|
||||
|
||||
static int32_t i2s1Recv(void *data, uint32_t num)
|
||||
{
|
||||
return i2sRecv(data, num, &i2s1Res);
|
||||
}
|
||||
|
||||
static int32_t i2s1Ctrl(uint32_t control, uint32_t arg)
|
||||
{
|
||||
return i2sControl(control, arg, &i2s1Res);
|
||||
}
|
||||
|
||||
uint32_t i2s1GetTotalCnt(void)
|
||||
{
|
||||
return i2sGetTotalCnt(&i2s1Res);
|
||||
}
|
||||
|
||||
void i2s1DmaRxEvent(uint32_t event)
|
||||
{
|
||||
i2sDmaRxEvent(event, &i2s1Res);
|
||||
}
|
||||
|
||||
void i2s1DmaTxEvent(uint32_t event)
|
||||
{
|
||||
i2sDmaTxEvent(event, &i2s1Res);
|
||||
}
|
||||
|
||||
// I2S1 Driver Control Block
|
||||
i2sDrvInterface_t i2sDrvInterface1 =
|
||||
{
|
||||
i2s1Init,
|
||||
i2s1Deinit,
|
||||
i2s1PowerCtrl,
|
||||
i2s1Send,
|
||||
i2s1Recv,
|
||||
i2s1Ctrl,
|
||||
i2s1GetTotalCnt,
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,414 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2020-, Copyrigths of AirM2M Ltd.
|
||||
* File name: kpc_ec616.c
|
||||
* Description: EC618 kpc driver source file
|
||||
* History: Rev1.0 2021-07-23
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "kpc.h"
|
||||
#include "ic.h"
|
||||
#include "clock.h"
|
||||
#include "slpman.h"
|
||||
|
||||
//#define KPC_DEBUG
|
||||
|
||||
/** \brief Internal used data structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t isInited; /**< flag indicating intialized or not */
|
||||
|
||||
uint8_t scanState; /**< For key release detect */
|
||||
|
||||
uint8_t enableAutoRepeat; /**< autorepeat feature is enabled */
|
||||
|
||||
uint8_t padding0;
|
||||
|
||||
uint32_t keyEnableMask; /**< Bitmap of enabled keys */
|
||||
uint32_t keyState; /**< Bitmap of key state, 0-release, 1-press */
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t repeatCount; /**< counter for autorepeat */
|
||||
uint8_t delay; /**< autorepeat event delay */
|
||||
uint8_t period; /**< autorepeat event period */
|
||||
uint16_t padding1;
|
||||
} autoRepeat;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t DEBCTL; /**< Debounce Control Register */
|
||||
uint32_t KPCTL; /**< Keypad Control Register */
|
||||
uint32_t DICTL; /**< Direct Input Control Register */
|
||||
uint32_t KPENCTL; /**< Keypad Enable Register */
|
||||
uint32_t DIENCTL; /**< Direct Input Enable Register */
|
||||
} configRegisters;
|
||||
|
||||
kpc_callback_t eventCallback; /**< Callback function passed in by application */
|
||||
} KpcDataBase_t;
|
||||
|
||||
static KpcDataBase_t gKpcDataBase = {0};
|
||||
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
/**
|
||||
\fn void KPC_enterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
\brief Backup KPC configurations before sleep.
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
void KPC_enterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
if(gKpcDataBase.isInited == 1)
|
||||
{
|
||||
gKpcDataBase.configRegisters.DEBCTL = KPC->DEBCTL;
|
||||
gKpcDataBase.configRegisters.KPCTL = KPC->KPCTL;
|
||||
gKpcDataBase.configRegisters.DICTL = KPC->DICTL;
|
||||
gKpcDataBase.configRegisters.KPENCTL = KPC->KPENCTL;
|
||||
gKpcDataBase.configRegisters.DIENCTL = KPC->DIENCTL;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
\fn void KPC_exitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
\brief Restore KPC configurations after exit from sleep.
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
void KPC_exitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
if(gKpcDataBase.isInited == 1)
|
||||
{
|
||||
KPC->DEBCTL = gKpcDataBase.configRegisters.DEBCTL;
|
||||
KPC->KPCTL = gKpcDataBase.configRegisters.KPCTL;
|
||||
KPC->DICTL = gKpcDataBase.configRegisters.DICTL;
|
||||
KPC->KPENCTL = gKpcDataBase.configRegisters.KPENCTL;
|
||||
KPC->DIENCTL = gKpcDataBase.configRegisters.DIENCTL;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static __FORCEINLINE uint32_t KPC_findFirstSet(uint32_t value)
|
||||
{
|
||||
return __CLZ(__RBIT(value));
|
||||
}
|
||||
|
||||
/**
|
||||
construct key enable bitmap
|
||||
|
||||
24 20 19 15 14 10 9 5 4 0
|
||||
+------------------+------------------+------------------+------------------+------------------+
|
||||
| row 4, col[4:0] | row 3, col[4:0] | row 2, col[4:0] | row 1,col[4:0] | row 0, col[4:0] |
|
||||
+------------------+------------------+------------------+------------------+------------------+
|
||||
|
||||
*/
|
||||
static void KPC_setKeyMask(uint32_t rowMask, uint32_t colMask, uint32_t* keyEnableMask, uint32_t* rowMsb, uint32_t* rowCounts)
|
||||
{
|
||||
uint32_t keyMask = 0;
|
||||
uint32_t rowIndex = 0;
|
||||
uint32_t cnt = 0;
|
||||
|
||||
// Max 5x5 matrix keypad
|
||||
rowMask &= 0x1f;
|
||||
colMask &= 0x1f;
|
||||
|
||||
while(rowMask)
|
||||
{
|
||||
rowIndex = KPC_findFirstSet(rowMask);
|
||||
keyMask |= (colMask << (rowIndex * 5));
|
||||
rowMask &= (rowMask - 1);
|
||||
cnt++;
|
||||
}
|
||||
|
||||
*keyEnableMask = keyMask;
|
||||
*rowMsb = rowIndex;
|
||||
*rowCounts = cnt;
|
||||
}
|
||||
|
||||
static void KPC_eventReport(void)
|
||||
{
|
||||
uint32_t lsb, keyScanResult, keyScanResultBackup, changed, report = 0;
|
||||
|
||||
KpcReportEvent_t event;
|
||||
|
||||
// Get current key scan result
|
||||
keyScanResult = KPC->KPSTAT & gKpcDataBase.keyEnableMask;
|
||||
|
||||
keyScanResultBackup = keyScanResult;
|
||||
|
||||
// Find out changed key
|
||||
changed = keyScanResult ^ gKpcDataBase.keyState;
|
||||
|
||||
#ifdef KPC_DEBUG
|
||||
printf("report: [%x]-[%x]-[%x]\r\n", keyScanResult, gKpcDataBase.keyState, changed);
|
||||
#endif
|
||||
|
||||
// First to handle key release
|
||||
if(changed)
|
||||
{
|
||||
lsb = KPC_findFirstSet(changed);
|
||||
|
||||
// Check key released during two consecutive rounds of scan
|
||||
if((keyScanResultBackup & ( 1 << lsb)) == 0)
|
||||
{
|
||||
event.row = lsb / 5;
|
||||
event.column = lsb % 5;
|
||||
event.value = KPC_REPORT_KEY_RELEASE;
|
||||
|
||||
gKpcDataBase.autoRepeat.repeatCount = 0;
|
||||
|
||||
if(gKpcDataBase.eventCallback)
|
||||
{
|
||||
gKpcDataBase.eventCallback(event);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Check key press
|
||||
if(keyScanResult)
|
||||
{
|
||||
lsb = KPC_findFirstSet(keyScanResult);
|
||||
|
||||
// repeat key?
|
||||
if((gKpcDataBase.keyState & (1 << lsb)) && (gKpcDataBase.enableAutoRepeat == 1))
|
||||
{
|
||||
gKpcDataBase.autoRepeat.repeatCount++;
|
||||
|
||||
if((gKpcDataBase.autoRepeat.repeatCount >= gKpcDataBase.autoRepeat.delay) && ((gKpcDataBase.autoRepeat.repeatCount - gKpcDataBase.autoRepeat.delay) % gKpcDataBase.autoRepeat.period == 0))
|
||||
{
|
||||
event.row = lsb / 5;
|
||||
event.column = lsb % 5;
|
||||
event.value = KPC_REPORT_KEY_REPEAT;
|
||||
report = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
event.row = lsb / 5;
|
||||
event.column = lsb % 5;
|
||||
event.value = KPC_REPORT_KEY_PRESS;
|
||||
gKpcDataBase.autoRepeat.repeatCount = 0;
|
||||
report = 1;
|
||||
}
|
||||
|
||||
if(gKpcDataBase.eventCallback && report)
|
||||
{
|
||||
gKpcDataBase.eventCallback(event);
|
||||
}
|
||||
}
|
||||
|
||||
// save current result
|
||||
gKpcDataBase.keyState = keyScanResultBackup;
|
||||
}
|
||||
|
||||
static void KPC_keyPadModeIsr(void)
|
||||
{
|
||||
KPC_eventReport();
|
||||
|
||||
// If any key is pressed, enable direct input interrupt which works as a periodic timer for key release detect purpose
|
||||
KPC->DIENCTL = KPC_DIENCTL_ENABLE_Msk;
|
||||
KPC->KPENCTL = KPC_KPENCTL_ENABLE_Msk;
|
||||
|
||||
gKpcDataBase.scanState = 1; // Indicating at least one key is pressed
|
||||
|
||||
}
|
||||
|
||||
// Enter at the end of one round of scan period
|
||||
static void KPC_directInputModeIsr(void)
|
||||
{
|
||||
KPC->CLRCTL = KPC_CLRCTL_INPUT_INT_CLR_Msk;
|
||||
|
||||
// Check if all keys are released
|
||||
if((KPC->KPSTAT == 0) && (gKpcDataBase.scanState == 2))
|
||||
{
|
||||
KPC->DIENCTL = 0;
|
||||
gKpcDataBase.scanState = 0;
|
||||
|
||||
#ifdef KPC_DEBUG
|
||||
printf("release,%x\r\n", KPC->DISTAT);
|
||||
#endif
|
||||
KPC_eventReport();
|
||||
}
|
||||
|
||||
gKpcDataBase.scanState = 2;
|
||||
|
||||
}
|
||||
|
||||
void KPC_getDefaultConfig(KpcConfig_t *config)
|
||||
{
|
||||
ASSERT(config);
|
||||
|
||||
config->debounceConfig.debounceClkDivRatio = KPC_DEBOUNCE_CLK_DIV_RATIO_16384;
|
||||
config->debounceConfig.debounceWidth = KPC_DEBOUNCE_WIDTH_7_CYCLES;
|
||||
|
||||
config->validRowMask = KPC_ROW_ALL;
|
||||
config->validColumnMask = KPC_COLUMN_ALL;
|
||||
|
||||
config->scanPolarity = KPC_SCAN_POLARITY_0;
|
||||
config->scanDivRatio = KPC_SCAN_DIV_RATIO_16;
|
||||
|
||||
config->autoRepeat.enable = 1;
|
||||
config->autoRepeat.delay = 10;
|
||||
config->autoRepeat.period = 1;
|
||||
}
|
||||
|
||||
int32_t KPC_init(const KpcConfig_t *config, kpc_callback_t callback)
|
||||
{
|
||||
ASSERT(config);
|
||||
|
||||
uint32_t mask, validRowCounts, msbOfValidRows;
|
||||
|
||||
mask = SaveAndSetIRQMask();
|
||||
|
||||
// Initialization
|
||||
if(gKpcDataBase.isInited == 0)
|
||||
{
|
||||
CLOCK_setClockSrc(FCLK_KPC, FCLK_KPC_SEL_26M);
|
||||
|
||||
CLOCK_clockEnable(FCLK_KPC);
|
||||
CLOCK_clockEnable(PCLK_KPC);
|
||||
|
||||
GPR_swResetModule(RESET_VECTOR_PTR(KPC_RESET_VECTOR));
|
||||
|
||||
// enable KPC IRQ
|
||||
XIC_SetVector(PXIC0_KPC_DIRECT_IRQn, KPC_directInputModeIsr);
|
||||
XIC_EnableIRQ(PXIC0_KPC_DIRECT_IRQn);
|
||||
|
||||
XIC_SetVector(PXIC0_KPC_KEYPAD_IRQn, KPC_keyPadModeIsr);
|
||||
XIC_EnableIRQ(PXIC0_KPC_KEYPAD_IRQn);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreIRQMask(mask);
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
KPC_setKeyMask(config->validRowMask, config->validColumnMask, &gKpcDataBase.keyEnableMask, &msbOfValidRows, &validRowCounts);
|
||||
|
||||
if(validRowCounts < 2)
|
||||
{
|
||||
return ARM_DRIVER_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
KPC->DEBCTL = EIGEN_VAL2FLD(KPC_DEBCTL_DEBOUNCER_DEPTH, config->debounceConfig.debounceWidth) | \
|
||||
EIGEN_VAL2FLD(KPC_DEBCTL_DEBOUNCER_TO0_THRD, config->debounceConfig.debounceWidth) | \
|
||||
EIGEN_VAL2FLD(KPC_DEBCTL_DEBOUNCER_TO1_THRD, config->debounceConfig.debounceWidth) | \
|
||||
EIGEN_VAL2FLD(KPC_DEBCTL_DEBOUNCER_TO_MCLK_RATIO, config->debounceConfig.debounceClkDivRatio);
|
||||
|
||||
KPC->KPCTL = EIGEN_VAL2FLD(KPC_KPCTL_POLARITY, config->scanPolarity) | \
|
||||
EIGEN_VAL2FLD(KPC_KPCTL_ROW_VLD_BITMAP, config->validRowMask & 0x1FU) | \
|
||||
EIGEN_VAL2FLD(KPC_KPCTL_COL_VLD_BITMAP, config->validColumnMask & 0x1FU) | \
|
||||
EIGEN_VAL2FLD(KPC_KPCTL_SCAN_TO_DEBOUNCE_RATIO, config->scanDivRatio);
|
||||
|
||||
// Enable rising/falling edge interrupt of ending row for key release detect
|
||||
if(config->scanPolarity == KPC_SCAN_POLARITY_0)
|
||||
{
|
||||
KPC->DICTL = EIGEN_VAL2FLD(KPC_DICTL_INT_EN, 1 << (msbOfValidRows + 5)) | EIGEN_VAL2FLD(KPC_DICTL_INT_MODE, 0x1);
|
||||
}
|
||||
else
|
||||
{
|
||||
KPC->DICTL = EIGEN_VAL2FLD(KPC_DICTL_INT_EN, 1 << (msbOfValidRows + 5)) | EIGEN_VAL2FLD(KPC_DICTL_INT_MODE, 0x2);
|
||||
}
|
||||
|
||||
KPC->AUTOCG = KPC_AUTOCG_ENABLE_Msk;
|
||||
|
||||
gKpcDataBase.eventCallback = callback;
|
||||
|
||||
gKpcDataBase.enableAutoRepeat = config->autoRepeat.enable;
|
||||
gKpcDataBase.autoRepeat.delay = config->autoRepeat.delay;
|
||||
gKpcDataBase.autoRepeat.period = config->autoRepeat.period;
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
slpManRegisterPredefinedBackupCb(SLP_CALLBACK_KPC_MODULE, KPC_enterLowPowerStatePrepare, NULL);
|
||||
slpManRegisterPredefinedRestoreCb(SLP_CALLBACK_KPC_MODULE, KPC_exitLowPowerStateRestore, NULL);
|
||||
#endif
|
||||
|
||||
gKpcDataBase.isInited = 1;
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
}
|
||||
|
||||
void KPC_deInit(void)
|
||||
{
|
||||
uint32_t mask = SaveAndSetIRQMask();
|
||||
|
||||
if(gKpcDataBase.isInited == 1)
|
||||
{
|
||||
KPC_stopScan();
|
||||
|
||||
// disable clock
|
||||
CLOCK_clockDisable(FCLK_KPC);
|
||||
CLOCK_clockDisable(PCLK_KPC);
|
||||
|
||||
XIC_DisableIRQ(PXIC0_KPC_DIRECT_IRQn);
|
||||
XIC_DisableIRQ(PXIC0_KPC_KEYPAD_IRQn);
|
||||
XIC_ClearPendingIRQ(PXIC0_KPC_DIRECT_IRQn);
|
||||
XIC_ClearPendingIRQ(PXIC0_KPC_KEYPAD_IRQn);
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
slpManUnregisterPredefinedBackupCb(SLP_CALLBACK_KPC_MODULE);
|
||||
slpManUnregisterPredefinedRestoreCb(SLP_CALLBACK_KPC_MODULE);
|
||||
#endif
|
||||
|
||||
gKpcDataBase.isInited = 0;
|
||||
}
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
}
|
||||
|
||||
void KPC_startScan(void)
|
||||
{
|
||||
uint32_t mask = SaveAndSetIRQMask();
|
||||
|
||||
if(gKpcDataBase.isInited == 1)
|
||||
{
|
||||
KPC->KPENCTL = KPC_KPENCTL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
}
|
||||
|
||||
void KPC_stopScan(void)
|
||||
{
|
||||
uint32_t mask = SaveAndSetIRQMask();
|
||||
|
||||
if(gKpcDataBase.isInited == 1)
|
||||
{
|
||||
KPC->DIENCTL = 0;
|
||||
KPC->CLRCTL = KPC_CLRCTL_INPUT_INT_CLR_Msk;
|
||||
KPC->DICTL = 0;
|
||||
}
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,420 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2020-, Copyrigths of AirM2M Ltd.
|
||||
* File name: oneWire.c
|
||||
* Description: EC618 one wire bus driver source file
|
||||
* History: Rev1.0 2020-12-17
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "ec618.h"
|
||||
#include "bsp.h"
|
||||
#include "oneWire.h"
|
||||
#include "hal_misc.h"
|
||||
|
||||
extern void delay_us(uint32_t us);
|
||||
|
||||
|
||||
#if OW_DEBUG_EN
|
||||
#define OW_DEBUG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define OW_DEBUG(...)
|
||||
#endif
|
||||
|
||||
#define OW_IRQ_MODE 1
|
||||
|
||||
static volatile OwStats_e owStats = OW_IDLE;
|
||||
|
||||
#define OW_PAD_ADDR (17) //(19)->gpio4 (17)->gpio2 (48)->gpio28 (22)->gpio7
|
||||
#define OW_PAD_FUNC PAD_MUX_ALT4 //PAD_MUX_ALT3 PAD_MUX_ALT4 PAD_MUX_ALT4 PAD_MUX_ALT4
|
||||
|
||||
|
||||
uint8_t *readBuf = NULL;
|
||||
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
void owIrqHandler(void);
|
||||
#else
|
||||
int A, B, C, D, E, F, G, H, I, J;
|
||||
#endif
|
||||
|
||||
void owSetMode(OwModeSel_e mode)
|
||||
{
|
||||
if (mode == STANDARD)
|
||||
{
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
#if 0
|
||||
OW->RTCR = EIGEN_VAL2FLD(OW_RTCR_RESET_SEND_DIV10, 50);
|
||||
OW->RTCR = EIGEN_VAL2FLD(OW_RTCR_RESET_WAIT_DIV10, 50);
|
||||
OW->RTCR = EIGEN_VAL2FLD(OW_RTCR_RESET_RDDLY_MIN, 15);
|
||||
OW->RTCR = EIGEN_VAL2FLD(OW_RTCR_RESET_RDDLY_MAX_DIV10, 10);
|
||||
|
||||
OW->ATCR = EIGEN_VAL2FLD(OW_ATCR_WRRD_RECO, 2);
|
||||
OW->ATCR = EIGEN_VAL2FLD(OW_ATCR_WRRD_SLOT_DIV10, 7);
|
||||
OW->ATCR = EIGEN_VAL2FLD(OW_ATCR_WRRD_START, 1);
|
||||
OW->ATCR = EIGEN_VAL2FLD(OW_ATCR_WRRD_WRDLY, 14);
|
||||
OW->ATCR = EIGEN_VAL2FLD(OW_ATCR_WRRD_RDDLY, 11);
|
||||
#endif
|
||||
#else
|
||||
OW->ECR |= OW_ECR_RXD_MJR_Msk;
|
||||
|
||||
A = 2; // 6us
|
||||
B = 12; // 64us
|
||||
C = 16; // 60us
|
||||
D = 1; // 10us
|
||||
E = 5; // 9us
|
||||
F = 28; // 55us
|
||||
G = 0;
|
||||
H = 120;// 480us
|
||||
I = 35; // 70us
|
||||
J = 150;// 410us
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
OW->RTCR = EIGEN_VAL2FLD(OW_RTCR_RESET_SEND_DIV10, 50);
|
||||
OW->RTCR = EIGEN_VAL2FLD(OW_RTCR_RESET_WAIT_DIV10, 50);
|
||||
OW->RTCR = EIGEN_VAL2FLD(OW_RTCR_RESET_RDDLY_MIN, 15);
|
||||
OW->RTCR = EIGEN_VAL2FLD(OW_RTCR_RESET_RDDLY_MAX_DIV10, 10);
|
||||
|
||||
OW->ATCR = EIGEN_VAL2FLD(OW_ATCR_WRRD_RECO, 2);
|
||||
OW->ATCR = EIGEN_VAL2FLD(OW_ATCR_WRRD_SLOT_DIV10, 7);
|
||||
OW->ATCR = EIGEN_VAL2FLD(OW_ATCR_WRRD_START, 1);
|
||||
OW->ATCR = EIGEN_VAL2FLD(OW_ATCR_WRRD_WRDLY, 14);
|
||||
OW->ATCR = EIGEN_VAL2FLD(OW_ATCR_WRRD_RDDLY, 11);
|
||||
#else
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if (OW_IRQ_MODE != 1)
|
||||
void write(uint8_t val)
|
||||
{
|
||||
if (val == 1)
|
||||
{
|
||||
OW->IOR |= OW_IOR_IO_SWOEN_Msk;
|
||||
OW->IOR |= OW_IOR_IO_SWOUT_Msk;
|
||||
}
|
||||
else
|
||||
{
|
||||
OW->IOR |= OW_IOR_IO_SWOEN_Msk;
|
||||
OW->IOR &= ~OW_IOR_IO_SWOUT_Msk;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t read()
|
||||
{
|
||||
uint8_t retData, rmjData;
|
||||
|
||||
OW->IOR &= ~OW_IOR_IO_SWOEN_Msk;
|
||||
rmjData = EIGEN_FLD2VAL(OW_ECR_RXD_MJR, OW->ECR);
|
||||
|
||||
if (rmjData > 0)
|
||||
{
|
||||
retData = EIGEN_FLD2VAL(OW_IOR_IO_SWIN_SYNC, OW->IOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
retData = EIGEN_FLD2VAL(OW_IOR_IO_SWIN, OW->IOR);
|
||||
}
|
||||
|
||||
return retData;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void owInit()
|
||||
{
|
||||
GPR_clockEnable(PCLK_ONEW);
|
||||
|
||||
// configure onew pins
|
||||
PadConfig_t padConfig;
|
||||
PAD_getDefaultConfig(&padConfig);
|
||||
padConfig.mux = OW_PAD_FUNC;
|
||||
PAD_setPinConfig(OW_PAD_ADDR, &padConfig);
|
||||
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
OW->IOR &= ~OW_IOR_IO_SWMODE_Msk;
|
||||
XIC_SetVector(PXIC0_ONEW_IRQn, owIrqHandler);
|
||||
XIC_EnableIRQ(PXIC0_ONEW_IRQn);
|
||||
#else
|
||||
OW->IOR |= OW_IOR_IO_SWMODE_Msk;
|
||||
#endif
|
||||
|
||||
OW->ECR |= OW_ECR_ENABLE_Msk; // enable onewire
|
||||
}
|
||||
|
||||
void owDeInit()
|
||||
{
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
XIC_DisableIRQ(PXIC0_ONEW_IRQn);
|
||||
#endif
|
||||
|
||||
GPR_clockDisable(PCLK_ONEW);
|
||||
}
|
||||
|
||||
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
volatile uint32_t irqNo;
|
||||
volatile uint16_t count = 0;
|
||||
void owIrqHandler()
|
||||
{
|
||||
++count;
|
||||
irqNo = OW->IIR;
|
||||
|
||||
// Disable ONEW IRQ
|
||||
XIC_DisableIRQ(PXIC0_ONEW_IRQn);
|
||||
|
||||
// Clear pending ONEW interrupts
|
||||
XIC_ClearPendingIRQ(PXIC0_ONEW_IRQn);
|
||||
|
||||
if ((OW->IIR & OW_IIR_INT_RESET_PD_Msk) && ((OW->IIR & OW_IIR_INT_RESET_Msk)!=OW_IIR_INT_RESET_Msk))
|
||||
{
|
||||
OW->IER &= ~OW_IER_INTEN_RESET_PD_Msk;
|
||||
|
||||
owStats |= OW_RESET_SUCCESS;
|
||||
|
||||
OW->IIR |= OW_IIR_INT_CLR_Msk;
|
||||
}
|
||||
else if ((OW->IIR & OW_IIR_INT_RESET_Msk) && (OW->IIR & OW_IIR_INT_RESET_PD_Msk))
|
||||
{
|
||||
if (OW->IIR & OW_IIR_RESET_PD_RES_Msk)
|
||||
{
|
||||
owStats |= OW_RESETPD_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
owStats &= ~OW_RESETPD_SUCCESS;
|
||||
}
|
||||
|
||||
OW->IIR |= OW_IIR_INT_CLR_Msk;
|
||||
OW->IER &= ~OW_IER_INTEN_RESET_PD_Msk;
|
||||
}
|
||||
else if (OW->IIR & OW_IIR_INT_WRITE_Msk)
|
||||
{
|
||||
if (OW->IIR & OW_IIR_INT_WRITE_Msk)
|
||||
{
|
||||
owStats |= OW_WRITE_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
owStats &= ~OW_WRITE_SUCCESS;
|
||||
}
|
||||
|
||||
OW->IIR |= OW_IIR_INT_CLR_Msk;
|
||||
OW->IER &= ~OW_IER_INTEN_WRITE_Msk;
|
||||
}
|
||||
else if (OW->IIR & OW_IIR_INT_READ_Msk)
|
||||
{
|
||||
*readBuf = OW->RBR;
|
||||
|
||||
if (OW->IIR & OW_IIR_INT_READ_Msk)
|
||||
{
|
||||
owStats |= OW_READ_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
owStats &= ~OW_READ_SUCCESS;
|
||||
}
|
||||
|
||||
OW->IIR |= OW_IIR_INT_CLR_Msk;
|
||||
OW->IER &= ~OW_IER_INTEN_READ_Msk;
|
||||
}
|
||||
|
||||
OW->OCR |= OW_OCR_CMD_FLUSH_Msk;
|
||||
|
||||
XIC_EnableIRQ(PXIC0_ONEW_IRQn);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int32_t owReset()
|
||||
{
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
OW->IER |= OW_IER_INTEN_RESET_PD_Msk;
|
||||
OW->IER |= OW_IER_INTEN_RESET_Msk;
|
||||
OW->OCR |= OW_OCR_CMD_RESET_Msk;
|
||||
while ((owStats & OW_RESET_SUCCESS) != OW_RESET_SUCCESS);
|
||||
|
||||
owStats &= ~OW_RESET_SUCCESS;
|
||||
|
||||
#else
|
||||
|
||||
#endif
|
||||
return OWDRV_OK;
|
||||
}
|
||||
int32_t owResetPd()
|
||||
{
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
OW->IER |= OW_IER_INTEN_RESET_Msk;
|
||||
delay_us(20); // wait until former irq finish
|
||||
OW->OCR |= OW_OCR_CMD_RESET_Msk;
|
||||
|
||||
while ((owStats & OW_RESETPD_SUCCESS) != OW_RESETPD_SUCCESS);
|
||||
owStats &= ~OW_RESETPD_SUCCESS;
|
||||
|
||||
return OWDRV_OK;
|
||||
#else
|
||||
delay_us(50);
|
||||
//owDelay(G);
|
||||
write(0);
|
||||
delay_us(H);
|
||||
write(1);
|
||||
delay_us(I);
|
||||
int ret = read();
|
||||
delay_us(J);
|
||||
if (ret == 1)
|
||||
{
|
||||
owStats |= OW_RESETPD_SUCCESS;
|
||||
return OWDRV_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
owStats &= ~OW_RESETPD_SUCCESS;
|
||||
return OWDRV_RESETPD_ERR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t owWriteBit(uint8_t data)
|
||||
{
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
OW->DFR &= ~OW_DFR_MODE_BYTE_Msk;
|
||||
OW->TBR = data;
|
||||
OW->IER |= OW_IER_INTEN_WRITE_Msk;
|
||||
OW->OCR |= OW_OCR_CMD_WRITE_Msk;
|
||||
|
||||
while ((owStats & OW_WRITE_SUCCESS) != OW_WRITE_SUCCESS);
|
||||
owStats &= ~OW_WRITE_SUCCESS;
|
||||
#else
|
||||
if (data == 1)
|
||||
{
|
||||
write(0);
|
||||
delay_us(A);
|
||||
write(1);
|
||||
delay_us(B);
|
||||
}
|
||||
else
|
||||
{
|
||||
write(0);
|
||||
delay_us(C);
|
||||
write(1);
|
||||
delay_us(D);
|
||||
}
|
||||
#endif
|
||||
|
||||
return OWDRV_OK;
|
||||
}
|
||||
|
||||
int32_t owReadBit(uint8_t * dataRead)
|
||||
{
|
||||
if (dataRead != NULL)
|
||||
{
|
||||
readBuf = dataRead;
|
||||
}
|
||||
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
OW->DFR &= ~OW_DFR_MODE_BYTE_Msk;
|
||||
OW->IER |= OW_IER_INTEN_READ_Msk;
|
||||
OW->OCR |= OW_OCR_CMD_READ_Msk;
|
||||
|
||||
while ((owStats & OW_READ_SUCCESS) != OW_READ_SUCCESS);
|
||||
owStats &= ~OW_READ_SUCCESS;
|
||||
#else
|
||||
write(0);
|
||||
delay_us(1);
|
||||
write(1);
|
||||
delay_us(2);
|
||||
*dataRead = read();
|
||||
delay_us(14);
|
||||
#endif
|
||||
|
||||
return OWDRV_OK;
|
||||
}
|
||||
|
||||
int32_t owWriteByte(uint8_t data)
|
||||
{
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
OW->DFR |= OW_DFR_MODE_BYTE_Msk;
|
||||
OW->TBR = data;
|
||||
OW->IER |= OW_IER_INTEN_WRITE_Msk;
|
||||
OW->OCR |= OW_OCR_CMD_WRITE_Msk;
|
||||
|
||||
while ((owStats & OW_WRITE_SUCCESS) != OW_WRITE_SUCCESS);
|
||||
owStats &= ~OW_WRITE_SUCCESS;
|
||||
#else
|
||||
for (int i=0; i<8; i++)
|
||||
{
|
||||
owWriteBit(data & 0x01);
|
||||
data >>= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return OWDRV_OK;
|
||||
}
|
||||
|
||||
int32_t owReadByte(uint8_t * dataRead)
|
||||
{
|
||||
if (dataRead != NULL)
|
||||
{
|
||||
readBuf = dataRead;
|
||||
}
|
||||
|
||||
#if (OW_IRQ_MODE == 1)
|
||||
OW->DFR |= OW_DFR_MODE_BYTE_Msk;
|
||||
|
||||
OW->IER |= OW_IER_INTEN_READ_Msk;
|
||||
OW->OCR |= OW_OCR_CMD_READ_Msk;
|
||||
|
||||
while ((owStats & OW_READ_SUCCESS) != OW_READ_SUCCESS);
|
||||
|
||||
owStats &= ~OW_READ_SUCCESS;
|
||||
#else
|
||||
uint8_t result=0;
|
||||
uint8_t readBitVal[8];
|
||||
memset(readBitVal, 0, 8);
|
||||
|
||||
for (int i=0; i<8; i++)
|
||||
{
|
||||
result >>= 1;
|
||||
owReadBit(readBitVal+i);
|
||||
|
||||
if (readBitVal[i] == 1)
|
||||
{
|
||||
result |= 0x80;
|
||||
}
|
||||
}
|
||||
*dataRead = result;
|
||||
#endif
|
||||
|
||||
return OWDRV_OK;
|
||||
}
|
||||
|
||||
int32_t owTouchByte(uint8_t data)
|
||||
{
|
||||
int32_t result = 0;
|
||||
|
||||
for (uint8_t i=0; i<8; i++)
|
||||
{
|
||||
result >>= 1;
|
||||
|
||||
// if sending a '1' then read a bit, else write a '0'
|
||||
if (data & 0x01)
|
||||
{
|
||||
if (owReadBit(NULL))
|
||||
{
|
||||
result |= 0x80;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
owWriteBit(0);
|
||||
}
|
||||
|
||||
data >>= 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2017-, Copyrigths of AirM2M Ltd.
|
||||
* File name: pad.c
|
||||
* Description: EC618 pad driver source file
|
||||
* History: Rev1.0 2018-11-14
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "pad.h"
|
||||
#include "clock.h"
|
||||
#include "slpman.h"
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
|
||||
static uint32_t gPadBackupRegs[PAD_ADDR_MAX_NUM] = {0};
|
||||
|
||||
/**
|
||||
\fn void PAD_enterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
\brief Backup pad configurations before sleep.
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
void PAD_enterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
GPR_clockEnable(PCLK_PAD);
|
||||
|
||||
for(i = 0; i < PAD_ADDR_MAX_NUM; i++)
|
||||
{
|
||||
gPadBackupRegs[i] = PAD->PCR[i];
|
||||
}
|
||||
|
||||
GPR_clockDisable(PCLK_PAD);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
\fn void PAD_exitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
\brief Restore PAD configurations after exit from sleep.
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
void PAD_exitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
GPR_clockEnable(PCLK_PAD);
|
||||
|
||||
for(i = 0; i < PAD_ADDR_MAX_NUM; i++)
|
||||
{
|
||||
PAD->PCR[i] = gPadBackupRegs[i];
|
||||
}
|
||||
|
||||
GPR_clockDisable(PCLK_PAD);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void PAD_driverInit(void)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
slpManRegisterPredefinedBackupCb(SLP_CALLBACK_PAD_MODULE, PAD_enterLowPowerStatePrepare, NULL);
|
||||
slpManRegisterPredefinedRestoreCb(SLP_CALLBACK_PAD_MODULE, PAD_exitLowPowerStateRestore, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PAD_driverDeInit(void)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
slpManUnregisterPredefinedBackupCb(SLP_CALLBACK_PAD_MODULE);
|
||||
slpManUnregisterPredefinedRestoreCb(SLP_CALLBACK_PAD_MODULE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PAD_getDefaultConfig(PadConfig_t *config)
|
||||
{
|
||||
ASSERT(config);
|
||||
|
||||
config->mux = PAD_MUX_ALT0;
|
||||
config->inputBufferEnable = PAD_INPUT_BUFFER_DISABLE;
|
||||
config->pullSelect = PAD_PULL_AUTO;
|
||||
config->pullUpEnable = PAD_PULL_UP_DISABLE;
|
||||
config->pullDownEnable = PAD_PULL_DOWN_DISABLE;
|
||||
}
|
||||
|
||||
void PAD_setPinConfig(uint32_t paddr, const PadConfig_t *config)
|
||||
{
|
||||
ASSERT(config);
|
||||
ASSERT(paddr < PAD_ADDR_MAX_NUM);
|
||||
|
||||
CLOCK_clockEnable(PCLK_PAD);
|
||||
PAD->PCR[paddr] = *((const uint32_t *)config);
|
||||
CLOCK_clockDisable(PCLK_PAD);
|
||||
}
|
||||
|
||||
void PAD_setPinMux(uint32_t paddr, PadMux_e mux)
|
||||
{
|
||||
ASSERT(paddr < PAD_ADDR_MAX_NUM);
|
||||
|
||||
CLOCK_clockEnable(PCLK_PAD);
|
||||
PAD->PCR[paddr] = (PAD->PCR[paddr] & ~PAD_PCR_MUX_Msk) | EIGEN_VAL2FLD(PAD_PCR_MUX, mux);
|
||||
CLOCK_clockDisable(PCLK_PAD);
|
||||
|
||||
}
|
||||
|
||||
void PAD_enablePinInputBuffer(uint32_t paddr, bool enable)
|
||||
{
|
||||
ASSERT(paddr < PAD_ADDR_MAX_NUM);
|
||||
|
||||
CLOCK_clockEnable(PCLK_PAD);
|
||||
|
||||
if (enable == true)
|
||||
{
|
||||
PAD->PCR[paddr] |= PAD_PCR_INPUT_BUFFER_ENABLE_Msk;
|
||||
}
|
||||
else
|
||||
{
|
||||
PAD->PCR[paddr] &= ~PAD_PCR_INPUT_BUFFER_ENABLE_Msk;
|
||||
}
|
||||
|
||||
CLOCK_clockDisable(PCLK_PAD);
|
||||
}
|
||||
|
||||
void PAD_setPinPullConfig(uint32_t paddr, PadPullConfig_e config)
|
||||
{
|
||||
ASSERT(paddr < PAD_ADDR_MAX_NUM);
|
||||
|
||||
CLOCK_clockEnable(PCLK_PAD);
|
||||
|
||||
switch(config)
|
||||
{
|
||||
case PAD_INTERNAL_PULL_UP:
|
||||
PAD->PCR[paddr] = (PAD->PCR[paddr] & ~PAD_PCR_PULL_DOWN_ENABLE_Msk) | PAD_PCR_PULL_UP_ENABLE_Msk | PAD_PCR_PULL_SELECT_Msk;
|
||||
break;
|
||||
case PAD_INTERNAL_PULL_DOWN:
|
||||
PAD->PCR[paddr] = (PAD->PCR[paddr] & ~PAD_PCR_PULL_UP_ENABLE_Msk) | PAD_PCR_PULL_DOWN_ENABLE_Msk | PAD_PCR_PULL_SELECT_Msk;
|
||||
break;
|
||||
case PAD_AUTO_PULL:
|
||||
PAD->PCR[paddr] = (PAD->PCR[paddr] & ~PAD_PCR_PULL_SELECT_Msk);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CLOCK_clockDisable(PCLK_PAD);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,509 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2017-, Copyrigths of AirM2M Ltd.
|
||||
* File name: timer.c
|
||||
* Description: EC618 timer driver source file
|
||||
* History: Rev1.0 2018-07-18
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "timer.h"
|
||||
#include "clock.h"
|
||||
#include "slpman.h"
|
||||
#include DEBUG_LOG_HEADER_FILE
|
||||
|
||||
#define EIGEN_TIMER(n) ((TIMER_TypeDef *) (AP_TIMER0_BASE_ADDR + 0x1000*n))
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
|
||||
/** \brief Internal used data structure */
|
||||
typedef struct
|
||||
{
|
||||
bool isInited; /**< Whether timer has been initialized */
|
||||
struct
|
||||
{
|
||||
uint32_t TCTLR; /**< Timer Control Register */
|
||||
uint32_t TIVR; /**< Timer Init Value Register */
|
||||
uint32_t TMR[3]; /**< Timer Match N Register */
|
||||
} backupRegisters; /**< Backup registers for low power restore */
|
||||
} TimerDatabase_t;
|
||||
|
||||
static bool gIsTimerDriverInited = false;
|
||||
|
||||
static TimerDatabase_t gTimerDataBase[TIMER_INSTANCE_NUM];
|
||||
|
||||
#endif
|
||||
|
||||
static ClockId_e gTimerClocks[TIMER_INSTANCE_NUM*2] = {PCLK_TIMER0, FCLK_TIMER0,
|
||||
PCLK_TIMER1, FCLK_TIMER1,
|
||||
PCLK_TIMER2, FCLK_TIMER2,
|
||||
PCLK_TIMER3, FCLK_TIMER3,
|
||||
PCLK_TIMER4, FCLK_TIMER4,
|
||||
PCLK_TIMER5, FCLK_TIMER5
|
||||
};
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
|
||||
/**
|
||||
\brief Bitmap of TIMER working status,
|
||||
when all TIMER instances are not working, we can vote to enter to low power state.
|
||||
*/
|
||||
static uint32_t gTimerWorkingStatus;
|
||||
|
||||
/**
|
||||
\fn static void TIMER_enterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
\brief Perform necessary preparations before sleep.
|
||||
After recovering from SLPMAN_SLEEP1_STATE, TIMER hareware is repowered, we backup
|
||||
some registers here first so that we can restore user's configurations after exit.
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
static void TIMER_enterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
for(i = 0; i < TIMER_INSTANCE_NUM; i++)
|
||||
{
|
||||
if(gTimerDataBase[i].isInited == true)
|
||||
{
|
||||
gTimerDataBase[i].backupRegisters.TCTLR = EIGEN_TIMER(i)->TCTLR;
|
||||
gTimerDataBase[i].backupRegisters.TIVR = EIGEN_TIMER(i)->TIVR;
|
||||
gTimerDataBase[i].backupRegisters.TMR[0] = EIGEN_TIMER(i)->TMR[0];
|
||||
gTimerDataBase[i].backupRegisters.TMR[1] = EIGEN_TIMER(i)->TMR[1];
|
||||
gTimerDataBase[i].backupRegisters.TMR[2] = EIGEN_TIMER(i)->TMR[2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
\fn static void TIMER_exitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
\brief Restore after exit from sleep.
|
||||
After recovering from SLPMAN_SLEEP1_STATE, TIMER hareware is repowered, we restore user's configurations
|
||||
by aidding of the stored registers.
|
||||
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
|
||||
*/
|
||||
static void TIMER_exitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
for(i = 0; i < TIMER_INSTANCE_NUM; i++)
|
||||
{
|
||||
if(gTimerDataBase[i].isInited == true)
|
||||
{
|
||||
GPR_clockEnable(gTimerClocks[i*2]);
|
||||
GPR_clockEnable(gTimerClocks[i*2+1]);
|
||||
|
||||
EIGEN_TIMER(i)->TCTLR = gTimerDataBase[i].backupRegisters.TCTLR;
|
||||
EIGEN_TIMER(i)->TIVR = gTimerDataBase[i].backupRegisters.TIVR;
|
||||
EIGEN_TIMER(i)->TMR[0] = gTimerDataBase[i].backupRegisters.TMR[0];
|
||||
EIGEN_TIMER(i)->TMR[1] = gTimerDataBase[i].backupRegisters.TMR[1];
|
||||
EIGEN_TIMER(i)->TMR[2] = gTimerDataBase[i].backupRegisters.TMR[2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void TIMER_driverInit(void)
|
||||
{
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
uint32_t i;
|
||||
|
||||
if(gIsTimerDriverInited == false)
|
||||
{
|
||||
for(i = 0; i < TIMER_INSTANCE_NUM; i++)
|
||||
{
|
||||
gTimerDataBase[i].isInited = false;
|
||||
}
|
||||
|
||||
gTimerWorkingStatus = 0;
|
||||
slpManRegisterPredefinedBackupCb(SLP_CALLBACK_TIMER_MODULE, TIMER_enterLowPowerStatePrepare, NULL);
|
||||
slpManRegisterPredefinedRestoreCb(SLP_CALLBACK_TIMER_MODULE, TIMER_exitLowPowerStateRestore, NULL);
|
||||
|
||||
gIsTimerDriverInited = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void TIMER_getDefaultConfig(TimerConfig_t *config)
|
||||
{
|
||||
ASSERT(config);
|
||||
|
||||
config->clockSource = TIMER_INTERNAL_CLOCK;
|
||||
config->reloadOption = TIMER_RELOAD_ON_MATCH1;
|
||||
config->initValue = 0;
|
||||
config->match0 = 0x10000 >> 1U;
|
||||
config->match1 = 0x10000;
|
||||
config->match2 = 0xFFFFFFFFU;
|
||||
}
|
||||
|
||||
void TIMER_init(uint32_t instance, const TimerConfig_t *config)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
ASSERT(config);
|
||||
|
||||
TIMER_driverInit();
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
if(gTimerDataBase[instance].isInited == false)
|
||||
{
|
||||
#endif
|
||||
|
||||
CLOCK_clockEnable(gTimerClocks[instance*2]);
|
||||
CLOCK_clockEnable(gTimerClocks[instance*2+1]);
|
||||
|
||||
/* Stop timer counter */
|
||||
EIGEN_TIMER(instance)->TCCR = 0;
|
||||
|
||||
EIGEN_TIMER(instance)->TCTLR = EIGEN_VAL2FLD(TIMER_TCTLR_MODE, config->clockSource) | \
|
||||
EIGEN_VAL2FLD(TIMER_TCTLR_MCS, config->reloadOption);
|
||||
EIGEN_TIMER(instance)->TIVR = config->initValue;
|
||||
EIGEN_TIMER(instance)->TMR[0] = config->match0;
|
||||
EIGEN_TIMER(instance)->TMR[1] = config->match1;
|
||||
EIGEN_TIMER(instance)->TMR[2] = config->match2;
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
gTimerDataBase[instance].isInited = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void TIMER_deInit(uint32_t instance)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
if(gTimerDataBase[instance].isInited == true)
|
||||
{
|
||||
#endif
|
||||
CLOCK_clockDisable(gTimerClocks[instance*2]);
|
||||
CLOCK_clockDisable(gTimerClocks[instance*2+1]);
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
gTimerDataBase[instance].isInited = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void TIMER_setMatch(uint32_t instance, TimerMatchSelect_t matchNum, uint32_t matchValue)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
EIGEN_TIMER(instance)->TMR[matchNum] = matchValue;
|
||||
}
|
||||
|
||||
void TIMER_setInitValue(uint32_t instance, uint32_t initValue)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
EIGEN_TIMER(instance)->TIVR = initValue;
|
||||
}
|
||||
|
||||
void TIMER_setReloadOption(uint32_t instance, TimerReloadOption_t option)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
EIGEN_TIMER(instance)->TCTLR = (EIGEN_TIMER(instance)->TCTLR &~ TIMER_TCTLR_MCS_Msk) | EIGEN_VAL2FLD(TIMER_TCTLR_MCS, option);
|
||||
}
|
||||
|
||||
void TIMER_start(uint32_t instance)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
if(instance != 5) // timer 5 do not vote sleep
|
||||
{
|
||||
uint32_t mask = SaveAndSetIRQMask();
|
||||
|
||||
gTimerWorkingStatus |= (1U << instance);
|
||||
slpManDrvVoteSleep(SLP_VOTE_TIMER, SLP_ACTIVE_STATE);
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
}
|
||||
#endif
|
||||
EIGEN_TIMER(instance)->TCCR = 1U;
|
||||
}
|
||||
|
||||
void TIMER_stop(uint32_t instance)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
EIGEN_TIMER(instance)->TCCR = 0;
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
if(instance != 5) // timer 5 do not vote sleep
|
||||
{
|
||||
uint32_t mask = SaveAndSetIRQMask();
|
||||
|
||||
gTimerWorkingStatus &= ~(1U << instance);
|
||||
if (gTimerWorkingStatus == 0)
|
||||
slpManDrvVoteSleep(SLP_VOTE_TIMER, SLP_SLP1_STATE);
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
uint32_t TIMER_getCount(uint32_t instance)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
EIGEN_TIMER(instance)->TCLR = TIMER_TCLR_LATCH_Msk;
|
||||
|
||||
while((EIGEN_TIMER(instance)->TCLR & TIMER_TCLR_LATCH_Msk) == TIMER_TCLR_LATCH_Msk);
|
||||
|
||||
return EIGEN_TIMER(instance)->TCR;
|
||||
}
|
||||
|
||||
int32_t TIMER_setupPwm(uint32_t instance, const TimerPwmConfig_t *config)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
ASSERT(config);
|
||||
|
||||
uint32_t period;
|
||||
|
||||
CLOCK_clockEnable(gTimerClocks[instance*2]);
|
||||
CLOCK_clockEnable(gTimerClocks[instance*2+1]);
|
||||
|
||||
if(config->srcClock_HZ == 0 || config->pwmFreq_HZ == 0 || config->srcClock_HZ <= config->pwmFreq_HZ)
|
||||
return ARM_DRIVER_ERROR_PARAMETER;
|
||||
|
||||
period = config->srcClock_HZ / config->pwmFreq_HZ;
|
||||
|
||||
/* Set PWM period */
|
||||
EIGEN_TIMER(instance)->TMR[1] = period - 1;
|
||||
|
||||
/* Set duty cycle */
|
||||
if(config->dutyCyclePercent == 0)
|
||||
{
|
||||
EIGEN_TIMER(instance)->TMR[0] = period; // if TMR[0] > TMR[1], PWM output keeps low
|
||||
}
|
||||
else if(config->dutyCyclePercent == 100)
|
||||
{
|
||||
EIGEN_TIMER(instance)->TMR[0] = period - 1; // let TMR[0] == TMR[1]
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Note the higher pwm frequency is, the lower reslution of dutyCycle we'll get.
|
||||
Below calculation may overflow for specific dutyCyclePercent and in such case, TMR[0] > TMR[1], PWM output keeps low
|
||||
*/
|
||||
EIGEN_TIMER(instance)->TMR[0] = ((uint64_t)period) * (100U - config->dutyCyclePercent) / 100U - 1;
|
||||
}
|
||||
EIGEN_TIMER(instance)->TIVR = 0;
|
||||
|
||||
/* Enable PWM out */
|
||||
EIGEN_TIMER(instance)->TCTLR = (EIGEN_TIMER(instance)->TCTLR & ~ TIMER_TCTLR_MCS_Msk) | \
|
||||
EIGEN_VAL2FLD(TIMER_TCTLR_MCS, 2U) | TIMER_TCTLR_PWMOUT_Msk;
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
gTimerDataBase[instance].isInited = true;
|
||||
#endif
|
||||
|
||||
return ARM_DRIVER_OK;
|
||||
|
||||
}
|
||||
|
||||
void TIMER_updatePwmDutyCycle(uint32_t instance, uint32_t dutyCyclePercent)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
if(dutyCyclePercent == 0)
|
||||
{
|
||||
EIGEN_TIMER(instance)->TMR[0] = EIGEN_TIMER(instance)->TMR[1] + 1; // if TMR[0] > TMR[1], PWM output keeps low
|
||||
}
|
||||
else if(dutyCyclePercent >= 100)
|
||||
{
|
||||
EIGEN_TIMER(instance)->TMR[0] = EIGEN_TIMER(instance)->TMR[1]; // let TMR[0] == TMR[1]
|
||||
}
|
||||
else
|
||||
{
|
||||
EIGEN_TIMER(instance)->TMR[0] = ((uint64_t)EIGEN_TIMER(instance)->TMR[1] + 1) * (100U - dutyCyclePercent) / 100U - 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TIMER_interruptConfig(uint32_t instance, TimerMatchSelect_t match, TimerInterruptConfig_t config)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
uint32_t enableMask, typeMask, registerValue;
|
||||
|
||||
enableMask = 1U << (match + TIMER_TCTLR_IE_0_Pos);
|
||||
typeMask = 1U << (match + TIMER_TCTLR_IT_0_Pos);
|
||||
registerValue = EIGEN_TIMER(instance)->TCTLR;
|
||||
|
||||
switch(config)
|
||||
{
|
||||
case TIMER_INTERRUPT_DISABLED:
|
||||
|
||||
registerValue &= ~enableMask;
|
||||
EIGEN_TIMER(instance)->TCTLR = registerValue;
|
||||
break;
|
||||
|
||||
case TIMER_INTERRUPT_LEVEL:
|
||||
|
||||
registerValue |= enableMask;
|
||||
registerValue &= ~typeMask;
|
||||
EIGEN_TIMER(instance)->TCTLR = registerValue;
|
||||
break;
|
||||
|
||||
case TIMER_INTERRUPT_PULSE:
|
||||
|
||||
registerValue |= enableMask;
|
||||
registerValue |= typeMask;
|
||||
EIGEN_TIMER(instance)->TCTLR = registerValue;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TimerInterruptConfig_t TIMER_getInterruptConfig(uint32_t instance, TimerMatchSelect_t match)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
uint32_t enableMask, typeMask, registerValue;
|
||||
|
||||
enableMask = 1U << (match + TIMER_TCTLR_IE_0_Pos);
|
||||
typeMask = 1U << (match + TIMER_TCTLR_IT_0_Pos);
|
||||
registerValue = EIGEN_TIMER(instance)->TCTLR;
|
||||
|
||||
if ((enableMask & registerValue) == 0)
|
||||
return TIMER_INTERRUPT_DISABLED;
|
||||
else if ((typeMask & registerValue) == 0)
|
||||
return TIMER_INTERRUPT_LEVEL;
|
||||
else
|
||||
return TIMER_INTERRUPT_PULSE;
|
||||
}
|
||||
|
||||
uint32_t TIMER_getInterruptFlags(uint32_t instance)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
return EIGEN_TIMER(instance)->TSR;
|
||||
}
|
||||
|
||||
void TIMER_clearInterruptFlags(uint32_t instance, uint32_t mask)
|
||||
{
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
EIGEN_TIMER(instance)->TSR = mask;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t gNetLightInstance = 0xff;
|
||||
void TIMER_netlightEnable(uint8_t instance) // call by user in bsp_custom.c
|
||||
{
|
||||
gNetLightInstance = instance;
|
||||
}
|
||||
|
||||
/////// Internal use for Netlight Function /////////////////
|
||||
void TIMER_netlightPWM(uint8_t mode)
|
||||
{
|
||||
extern void delay_us(uint32_t us);
|
||||
uint8_t instance = gNetLightInstance;
|
||||
static uint8_t curMode;
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
uint32_t mask;
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, TIMER_netlightPWM_1, P_SIG, "Netlight mode=%u Instance=%d",mode, instance);
|
||||
#endif
|
||||
|
||||
if(instance == 0xff)
|
||||
return;
|
||||
|
||||
ASSERT(instance < TIMER_INSTANCE_NUM);
|
||||
|
||||
if(curMode == mode) // do nothing if mode not change
|
||||
return;
|
||||
|
||||
EIGEN_TIMER(instance)->TCCR = 0;
|
||||
|
||||
if(mode == 0)
|
||||
{
|
||||
EIGEN_TIMER(instance)->TMR[0] = 0xFFFFFFFF;
|
||||
EIGEN_TIMER(instance)->TMR[1] = 0; // TMR[0] > TMR[1], PWM output keeps low
|
||||
EIGEN_TIMER(instance)->TCCR = 1;
|
||||
delay_us(10);
|
||||
EIGEN_TIMER(instance)->TCCR = 0;
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
if(gTimerWorkingStatus & (1U << instance))
|
||||
{
|
||||
CLOCK_clockDisable(gTimerClocks[instance*2]);
|
||||
CLOCK_clockDisable(gTimerClocks[instance*2+1]);
|
||||
}
|
||||
mask = SaveAndSetIRQMask();
|
||||
gTimerWorkingStatus &= ~(1U << instance);
|
||||
if (gTimerWorkingStatus == 0)
|
||||
slpManDrvVoteSleep(SLP_VOTE_TIMER, SLP_SLP1_STATE);
|
||||
RestoreIRQMask(mask);
|
||||
#endif
|
||||
curMode = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
if((gTimerWorkingStatus & (1U << instance)) == 0)
|
||||
{
|
||||
CLOCK_clockEnable(gTimerClocks[instance*2]);
|
||||
CLOCK_clockEnable(gTimerClocks[instance*2+1]);
|
||||
}
|
||||
mask = SaveAndSetIRQMask();
|
||||
gTimerWorkingStatus |= (1U << instance);
|
||||
slpManDrvVoteSleep(SLP_VOTE_TIMER, SLP_ACTIVE_STATE);
|
||||
RestoreIRQMask(mask);
|
||||
#endif
|
||||
|
||||
/* Enable PWM out */
|
||||
EIGEN_TIMER(instance)->TCTLR = (EIGEN_TIMER(instance)->TCTLR & ~ TIMER_TCTLR_MCS_Msk) | \
|
||||
EIGEN_VAL2FLD(TIMER_TCTLR_MCS, 2U) | TIMER_TCTLR_PWMOUT_Msk;
|
||||
|
||||
if(mode == 1) // fast flash: 64ms high and 800ms low
|
||||
{
|
||||
EIGEN_TIMER(instance)->TMR[0] = 0x13D61FF;
|
||||
|
||||
EIGEN_TIMER(instance)->TMR[1] = 0x156C5FE;
|
||||
|
||||
EIGEN_TIMER(instance)->TCCR = 1;
|
||||
|
||||
curMode = mode;
|
||||
}
|
||||
else if(mode == 2) // slow flash: 64ms high and 2000ms low
|
||||
{
|
||||
EIGEN_TIMER(instance)->TMR[0] = 0x31974FF;
|
||||
|
||||
EIGEN_TIMER(instance)->TMR[1] = 0x332D8FE;
|
||||
|
||||
EIGEN_TIMER(instance)->TCCR = 1;
|
||||
|
||||
curMode = mode;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
|
||||
* File name: tls.c
|
||||
* Description: This driver is part of SCT(Security Top) module, only focus on AES and SHA functions which are
|
||||
* mostly used in TLS(transport layer security) area.
|
||||
* History: Rev1.0 2021-12-3
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "tls.h"
|
||||
|
||||
static __attribute__((aligned(4))) sctDescCfg_t sctDescCfg;
|
||||
|
||||
void sctInit()
|
||||
{
|
||||
// open clock
|
||||
CLOCK_clockEnable(SCT_RMI_HCLK);
|
||||
|
||||
GPR_swReset(RST_SCT_RMI_HCLK);
|
||||
GPR_swReset(RST_SCT_HCLK);
|
||||
|
||||
memset(&sctDescCfg, 0, sizeof(sctDescCfg_t));
|
||||
|
||||
// enable sct
|
||||
*(uint32_t *)SCT_ENABLE_REG = 1;
|
||||
|
||||
// set memory guard
|
||||
sctMemGuard_t *sctMemGuard = (sctMemGuard_t*)SCT_MEM_GUARD_REG;
|
||||
sctMemGuard->hAddr0 = MGR_HIGH_ADDR;
|
||||
sctMemGuard->lAddr0 = MGR_LOW_ADDR;
|
||||
sctMemGuard->hAddr1 = MGR_HIGH_ADDR1;
|
||||
sctMemGuard->lAddr1 = MGR_LOW_ADDR1;
|
||||
sctMemGuard->hAddr2 = MGR_HIGH_ADDR2;
|
||||
sctMemGuard->lAddr2 = MGR_LOW_ADDR2;
|
||||
sctMemGuard->hAddr3 = MGR_HIGH_ADDR3;
|
||||
sctMemGuard->lAddr3 = MGR_LOW_ADDR3;
|
||||
|
||||
// sct common config
|
||||
sctCfgWord0_t *cfgWord0 = (sctCfgWord0_t*)SCT_COMM_CFG0_REG;
|
||||
sctCfgWord1_t *cfgWord1 = (sctCfgWord1_t*)SCT_COMM_CFG1_REG;
|
||||
sctCfgWord0_t word0;
|
||||
cfgWord0->val = 0;
|
||||
cfgWord1->descMaxProcTickTime = 0x4fffb;
|
||||
|
||||
word0.ahbAcg = 0;
|
||||
word0.rmiAcg = 1;
|
||||
word0.chainStartUnilog = 1;
|
||||
word0.descDoneUnilog = 1;
|
||||
word0.chainEndUnilog = 1;
|
||||
word0.errorIntUnilog = 1;
|
||||
word0.usbEndianInd = 0;
|
||||
word0.memHighAddrOffset = 0;
|
||||
cfgWord0->val = word0.val;
|
||||
}
|
||||
|
||||
static uint32_t sctCheckBusy()
|
||||
{
|
||||
sctChaState_t *state = (sctChaState_t*)AES_SHA_CH4_STATE_REG;
|
||||
if (state->chaBeEmpty)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int sctTrigger(sctDescCfg_t* sctDescCfg)
|
||||
{
|
||||
if (sctCheckBusy())
|
||||
{
|
||||
return SCTDRV_BUSY;
|
||||
}
|
||||
|
||||
sctCfgWord_t* sctCfgWord = (sctCfgWord_t*)AES_SHA_CH4_CFG_REG;
|
||||
sctCfgWord->chanCfgWord1 = (uint32_t)sctDescCfg;
|
||||
CLOCK_clockEnable(SCT_HCLK);
|
||||
sctCfgWord->chanCfgWord5.trigger = 1;
|
||||
|
||||
return SCTDRV_OK;
|
||||
}
|
||||
|
||||
static int sctPollDone(uint32_t timeOutCycle)
|
||||
{
|
||||
while (timeOutCycle--)
|
||||
{
|
||||
delay_us(1);
|
||||
|
||||
if (!sctCheckBusy())
|
||||
{
|
||||
return SCTDRV_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return SCTDRV_TIMEOUT;
|
||||
}
|
||||
|
||||
|
||||
int32_t aesUpdate(aesInfo_t* aesInfo)
|
||||
{
|
||||
uint32_t ret = SCTDRV_OK;
|
||||
|
||||
sctDescCfg_t* sctDescCfgPtr = &sctDescCfg;
|
||||
sctDescCfgPtr->u1.aesField.length = aesInfo->length;
|
||||
sctDescCfgPtr->u1.aesField.dir = aesInfo->aesCtrl.dir;
|
||||
sctDescCfgPtr->u1.aesField.aesMode = aesInfo->aesCtrl.aesMode;
|
||||
sctDescCfgPtr->u1.aesField.paddingMode = aesInfo->aesCtrl.paddingMode;
|
||||
sctDescCfgPtr->u1.aesField.ckLen = aesInfo->aesCtrl.ckLen;
|
||||
sctDescCfgPtr->u1.aesField.aesCkSel = aesInfo->aesCtrl.aesCkSel;
|
||||
sctDescCfgPtr->u1.aesField.subType = 0; // aes
|
||||
sctDescCfgPtr->u1.aesField.type = 5; // default value is 5
|
||||
sctDescCfgPtr->srcAddr = aesInfo->srcAddr;
|
||||
sctDescCfgPtr->dstAddr = aesInfo->dstAddr;
|
||||
|
||||
if (aesInfo->aesCtrl.aesCkSel == 0) // from memory
|
||||
{
|
||||
sctDescCfgPtr->u2.aesCkAddr = aesInfo->aesCkAddr;;
|
||||
}
|
||||
|
||||
if (aesInfo->aesCtrl.aesMode == 1 || aesInfo->aesCtrl.aesMode == 2) // aes cbc, ctr mode
|
||||
{
|
||||
sctDescCfgPtr->u3.aesIvAddr = aesInfo->ivAddr;
|
||||
}
|
||||
|
||||
sctCfgWord_t* sctCfgWord = (sctCfgWord_t*)AES_SHA_CH4_CFG_REG;
|
||||
chanCfgWord0_t cfgWord0;
|
||||
cfgWord0.val = 0;
|
||||
if (aesInfo->aesCtrl.ckBLEndian == 1) // key is big endian
|
||||
{
|
||||
cfgWord0.ckBLEndian = 1;
|
||||
}
|
||||
|
||||
if (aesInfo->aesCtrl.aesIvBLEndian == 1) // iv is big endian
|
||||
{
|
||||
cfgWord0.aesIvBLEndian = 1;
|
||||
}
|
||||
|
||||
cfgWord0.fifoLen = 1; // only 1 descriptor(aes)
|
||||
sctCfgWord->chanCfgWord0.val = cfgWord0.val;
|
||||
|
||||
ret = sctTrigger(sctDescCfgPtr);
|
||||
if (ret != SCTDRV_OK)
|
||||
{
|
||||
return SCTDRV_BUSY;
|
||||
}
|
||||
|
||||
ret = sctPollDone(50000);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// if you need to loop call this api, "lastFlag" should be 0 for intermediate steps, and last step it should be 1.
|
||||
int32_t shaUpdate(shaType_e shaMode, uint32_t srcAddr, uint32_t dstAddr, uint32_t length, uint32_t lastFlag)
|
||||
{
|
||||
uint32_t ret = SCTDRV_OK;
|
||||
|
||||
// sha input should 64bytes aligned, if not, you need to padding it first
|
||||
if ((length & 0x3f) != 0)
|
||||
{
|
||||
return SCTDRV_PAMERR;
|
||||
}
|
||||
|
||||
sctDescCfg_t* sctDescCfgPtr = &sctDescCfg;
|
||||
sctDescCfgPtr->srcAddr = srcAddr; // sha input
|
||||
sctDescCfgPtr->dstAddr = dstAddr; // sha output
|
||||
sctDescCfgPtr->u1.shaField.length = length; // sha input length, should 64bytes aligned
|
||||
sctDescCfgPtr->u1.shaField.subType = 1; // 0: aes; 1:sha
|
||||
sctDescCfgPtr->u1.shaField.shaMode = shaMode;
|
||||
sctDescCfgPtr->u1.shaField.type = 5; // default value 5
|
||||
sctDescCfgPtr->u1.shaField.shaBls = 1; // sha output endian. 0: LE; 1: BE
|
||||
|
||||
if (lastFlag == 0)
|
||||
{
|
||||
sctDescCfgPtr->u1.shaField.rcs = 1; // data is continuous
|
||||
sctDescCfgPtr->u1.shaField.outEn = 0; // not output
|
||||
}
|
||||
else
|
||||
{
|
||||
sctDescCfgPtr->u1.shaField.rcs = 0; // data has been the last sector
|
||||
sctDescCfgPtr->u1.shaField.outEn = 1; // open sha output value
|
||||
}
|
||||
|
||||
sctDescCfgPtr->u3.shaHeadLen.headLen = 0; // no head
|
||||
|
||||
sctCfgWord_t* sctCfgWord = (sctCfgWord_t*)AES_SHA_CH4_CFG_REG;
|
||||
chanCfgWord0_t cfgWord0;
|
||||
cfgWord0.val = 0;
|
||||
cfgWord0.fifoLen = 1; // here only 1 descriptor(sha)
|
||||
sctCfgWord->chanCfgWord0.val = cfgWord0.val;
|
||||
|
||||
ret = sctTrigger(sctDescCfgPtr);
|
||||
if (ret != SCTDRV_OK)
|
||||
{
|
||||
return SCTDRV_BUSY;
|
||||
}
|
||||
|
||||
ret = sctPollDone(50000);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,442 @@
|
||||
#include "usbd_clscdc.h"
|
||||
#include "usbd_clscdc_cust_tp.h"
|
||||
|
||||
//#include "func_dbg.h"
|
||||
#include "string.h"
|
||||
#include "usbd_macro_def.h"
|
||||
#include "usbd_func_cconf.h"
|
||||
#include "usbd_func_cc.h"
|
||||
#include "usbd_multi_usrcfg_common.h"
|
||||
|
||||
|
||||
const usbd_cdc_desc_custp1_st t_usbd_cdc_desc_custp1 = {
|
||||
.intf_ctrl_desc = {
|
||||
/*Interface Descriptor */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
/* Interface descriptor type */
|
||||
INVALID_INTF_NUM, //VCOM_INTF_NUM_0, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints: One endpoints used */
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x01, /* bInterfaceProtocol: Common AT commands */
|
||||
0x00, /* iInterface: */
|
||||
},
|
||||
|
||||
.cdc_diep_desc = {
|
||||
/*Endpoint IN Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
INVALID_EP_NUM, //CDC_IN_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
|
||||
0x00 /* bInterval */
|
||||
},
|
||||
|
||||
.cdc_doep_desc = {
|
||||
/*Endpoint OUT Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
INVALID_EP_NUM, //CDC_OUT_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
uint8_t vcom_func_custp1_desc_ass(usb_func_ccinst_st *p_func_ccinst)
|
||||
{
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
p_ccinst_cdc_setting->desc_assigned = 0;
|
||||
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp1_2ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
p_ccinst_cdc_setting->p_desc_src = (const uint8_t *)(&t_usbd_cdc_desc_custp1);
|
||||
p_ccinst_cdc_setting->desc_src_size = sizeof(t_usbd_cdc_desc_custp1);
|
||||
|
||||
p_ccinst_cdc_setting->desc_assigned = 1;
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp1_desc_parse(usb_func_ccinst_st *p_func_ccinst)
|
||||
{
|
||||
const uint8_t * p_desc_buf;
|
||||
uint16_t pos = 0;
|
||||
uint8_t ret = usbd_ret_no_err;
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
usb_endpoint_descriptor_st * p_endp_d;
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp1_2ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
if(p_ccinst_cdc_setting->desc_assigned!=1)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
p_desc_buf = p_ccinst_cdc_setting->p_desc_src;
|
||||
|
||||
p_ccinst_cdc_setting->desc_parsed = 0;
|
||||
|
||||
p_ccinst_cdc_setting->epctrl_valid = 0;
|
||||
p_ccinst_cdc_setting->epin_valid = 0;
|
||||
p_ccinst_cdc_setting->epout_valid = 0;
|
||||
|
||||
p_ccinst_cdc_setting->interface_cnt = 0;
|
||||
|
||||
while(pos < p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
if (p_desc_buf[pos] == 0)
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
if ((pos+ p_desc_buf[pos]) > p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (p_desc_buf[pos+1])
|
||||
{
|
||||
case USB_ENDPOINT_DESCRIPTOR_TYPE:
|
||||
if (p_desc_buf[pos] != STANDARD_ENDPOINT_DESC_SIZE)
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
p_endp_d = (usb_endpoint_descriptor_st *)(&(p_desc_buf[pos]));
|
||||
if (p_endp_d->bmAttributes == USBC_CTRL_EP_BULK)
|
||||
{
|
||||
//if (p_endp_d->bEndpointAddress &0x80)
|
||||
|
||||
if (p_endp_d == (&t_usbd_cdc_desc_custp1.cdc_diep_desc))
|
||||
{
|
||||
p_ccinst_cdc_setting->epin_valid = 1;
|
||||
p_ccinst_cdc_setting->p_epin_d = p_endp_d;
|
||||
}
|
||||
else if (p_endp_d == (&t_usbd_cdc_desc_custp1.cdc_doep_desc))
|
||||
{
|
||||
p_ccinst_cdc_setting->epout_valid = 1;
|
||||
p_ccinst_cdc_setting->p_epout_d = p_endp_d;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else if (p_endp_d->bmAttributes == USBC_CTRL_EP_INTR)
|
||||
{
|
||||
if (p_endp_d->bEndpointAddress &0x80)
|
||||
{
|
||||
p_ccinst_cdc_setting->epctrl_valid = 1;
|
||||
p_ccinst_cdc_setting->p_epctrl_d = p_endp_d;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case USB_INTERFACE_DESCRIPTOR_TYPE:
|
||||
if (p_desc_buf[pos] !=STANDARD_INTERFACE_DESC_SIZE)
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
p_ccinst_cdc_setting->interface_cnt++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (ret!=usbd_ret_no_err)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos+= p_desc_buf[pos];
|
||||
}
|
||||
|
||||
if ((p_ccinst_cdc_setting->epctrl_valid ==1) ||
|
||||
(p_ccinst_cdc_setting->epin_valid ==0) ||
|
||||
(p_ccinst_cdc_setting->epout_valid==0)||
|
||||
(p_ccinst_cdc_setting->interface_cnt!=1) )
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
p_ccinst_cdc_setting->desc_parsed = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp1_bind(usb_func_ccinst_st *p_func_ccinst,
|
||||
ccinst_bind_call_data_st *p_bind_call_data)
|
||||
{
|
||||
uint8_t ret = usbd_ret_no_err;
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp1_2ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((p_ccinst_cdc_setting->desc_assigned==0)
|
||||
|| (p_ccinst_cdc_setting->desc_parsed==0))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
p_ccinst_cdc_setting->ep_datain_num = p_bind_call_data->ep_datain_num;
|
||||
p_ccinst_cdc_setting->ep_dataout_num = p_bind_call_data->ep_dataout_num;
|
||||
|
||||
p_ccinst_cdc_setting->interface_cnt = p_bind_call_data->interface_cnt;
|
||||
|
||||
p_ccinst_cdc_setting->intf_base_idx = p_bind_call_data->intf_base_idx;
|
||||
p_ccinst_cdc_setting->intf_1st_idx = p_bind_call_data->intf_1st_idx;
|
||||
|
||||
p_ccinst_cdc_setting->intf_str_id = p_bind_call_data->intf_str_id;
|
||||
p_ccinst_cdc_setting->binded = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp1_get_desc(usb_func_ccinst_st *p_func_ccinst, ccinst_desc_call_data_st*p_desc_call_data)
|
||||
{
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
usbd_cdc_desc_custp1_st *p_usbd_desc_dst;
|
||||
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp1_2ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_desc_call_data->desc_buff_size < p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
if (p_ccinst_cdc_setting->binded == 0)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
p_usbd_desc_dst = (usbd_cdc_desc_custp1_st *)(p_desc_call_data->p_desc_buff_ptr);
|
||||
|
||||
memcpy(p_usbd_desc_dst, p_ccinst_cdc_setting->p_desc_src, p_ccinst_cdc_setting->desc_src_size);
|
||||
|
||||
p_usbd_desc_dst->cdc_diep_desc.bEndpointAddress = EPIN_MARK_DIR(p_ccinst_cdc_setting->ep_datain_num);
|
||||
p_usbd_desc_dst->cdc_doep_desc.bEndpointAddress = p_ccinst_cdc_setting->ep_dataout_num;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.iInterface = p_ccinst_cdc_setting->intf_str_id;
|
||||
|
||||
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceNumber = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
|
||||
if (p_desc_call_data->b_intf_ctrl_desc_upd)
|
||||
{
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceClass = p_desc_call_data->bInterfaceClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceSubClass = p_desc_call_data->bInterfaceSubClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceProtocol = p_desc_call_data->bInterfaceProtocol;
|
||||
}
|
||||
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp1_get_othspd_desc(usb_func_ccinst_st *p_func_ccinst, ccinst_desc_call_data_st*p_desc_call_data)
|
||||
{
|
||||
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
usbd_cdc_desc_custp1_st *p_usbd_desc_dst;
|
||||
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp1_2ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_desc_call_data->desc_buff_size < p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
if (p_ccinst_cdc_setting->binded == 0)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
p_usbd_desc_dst = (usbd_cdc_desc_custp1_st*)(p_desc_call_data->p_desc_buff_ptr);
|
||||
memcpy(p_usbd_desc_dst, p_ccinst_cdc_setting->p_desc_src, p_ccinst_cdc_setting->desc_src_size);
|
||||
|
||||
|
||||
p_usbd_desc_dst->cdc_diep_desc.bEndpointAddress = EPIN_MARK_DIR(p_ccinst_cdc_setting->ep_datain_num);
|
||||
p_usbd_desc_dst->cdc_doep_desc.bEndpointAddress = p_ccinst_cdc_setting->ep_dataout_num;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.iInterface = p_ccinst_cdc_setting->intf_str_id;
|
||||
p_usbd_desc_dst->cdc_diep_desc.wMaxPacketSize_High = 0;
|
||||
p_usbd_desc_dst->cdc_diep_desc.wMaxPacketSize_Low = 0x40;
|
||||
p_usbd_desc_dst->cdc_doep_desc.wMaxPacketSize_High = 0;
|
||||
p_usbd_desc_dst->cdc_doep_desc.wMaxPacketSize_Low = 0x40;
|
||||
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceNumber = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
|
||||
if (p_desc_call_data->b_intf_ctrl_desc_upd)
|
||||
{
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceClass = p_desc_call_data->bInterfaceClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceSubClass = p_desc_call_data->bInterfaceSubClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceProtocol = p_desc_call_data->bInterfaceProtocol;
|
||||
}
|
||||
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
|
||||
uint8_t vcom_func_custp1_init(usb_func_ccinst_st *p_func_ccinst, uint8_t cfgidx)
|
||||
{
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp1_deinit(usb_func_ccinst_st *p_func_ccinst, uint8_t cfgidx)
|
||||
{
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp1_unbind(usb_func_ccinst_st *p_func_ccinst)
|
||||
{
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp1_2ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_ccinst_cdc_setting->binded==0)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
p_ccinst_cdc_setting->binded = 0;
|
||||
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
#if (VCOM_CCINST_SUBTP1_2EP_CNT > 0)
|
||||
const ccinst_setting_base_st t_vcom_custp1_base_setting =
|
||||
{
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp1_2ep
|
||||
};
|
||||
|
||||
ccinst_cdc_setting_st t_vcom_custp1_setting_arr[VCOM_CCINST_SUBTP1_2EP_CNT] ={
|
||||
//[0]
|
||||
{
|
||||
.bs_set = t_vcom_custp1_base_setting,
|
||||
},
|
||||
|
||||
#if (VCOM_CCINST_SUBTP1_2EP_CNT >=2)
|
||||
//[1]
|
||||
|
||||
{
|
||||
.bs_set = t_vcom_custp1_base_setting,
|
||||
},
|
||||
#endif
|
||||
|
||||
#if (VCOM_CCINST_SUBTP1_2EP_CNT >= 3)
|
||||
//[2]
|
||||
{
|
||||
.bs_set = t_vcom_custp1_base_setting,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
usb_func_ccinst_st t_vcom_func_custp1_arr[VCOM_CCINST_SUBTP1_2EP_CNT] ={
|
||||
//[0]
|
||||
{
|
||||
.p_cc_setting = &t_vcom_custp1_setting_arr[0],
|
||||
|
||||
.func_desc_ass = vcom_func_custp1_desc_ass,
|
||||
.func_desc_parse = vcom_func_custp1_desc_parse,
|
||||
.func_bind = vcom_func_custp1_bind,
|
||||
.func_get_desc = vcom_func_custp1_get_desc,
|
||||
.func_get_othspd_desc = vcom_func_custp1_get_othspd_desc,
|
||||
|
||||
.func_init = vcom_func_custp1_init,
|
||||
.func_deinit = vcom_func_custp1_deinit,
|
||||
.func_unbind = vcom_func_custp1_unbind,
|
||||
},
|
||||
|
||||
#if (VCOM_CCINST_SUBTP1_2EP_CNT >=2)
|
||||
//[1]
|
||||
|
||||
{
|
||||
.p_cc_setting = &t_vcom_custp1_setting_arr[1],
|
||||
.func_desc_ass = vcom_func_custp1_desc_ass,
|
||||
.func_desc_parse = vcom_func_custp1_desc_parse,
|
||||
.func_bind = vcom_func_custp1_bind,
|
||||
.func_get_desc = vcom_func_custp1_get_desc,
|
||||
.func_get_othspd_desc = vcom_func_custp1_get_othspd_desc,
|
||||
|
||||
.func_init = vcom_func_custp1_init,
|
||||
.func_deinit = vcom_func_custp1_deinit,
|
||||
.func_unbind = vcom_func_custp1_unbind,
|
||||
},
|
||||
#endif
|
||||
|
||||
#if (VCOM_CCINST_SUBTP1_2EP_CNT >= 3)
|
||||
//[2]
|
||||
{
|
||||
.p_cc_setting = &t_vcom_custp1_setting_arr[2],
|
||||
|
||||
.func_desc_ass = vcom_func_custp1_desc_ass,
|
||||
.func_desc_parse = vcom_func_custp1_desc_parse,
|
||||
.func_bind = vcom_func_custp1_bind,
|
||||
.func_get_desc = vcom_func_custp1_get_desc,
|
||||
.func_get_othspd_desc = vcom_func_custp1_get_othspd_desc,
|
||||
|
||||
.func_init = vcom_func_custp1_init,
|
||||
.func_deinit = vcom_func_custp1_deinit,
|
||||
.func_unbind = vcom_func_custp1_unbind,
|
||||
},
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,501 @@
|
||||
#include "usbd_clscdc.h"
|
||||
#include "usbd_clscdc_cust_tp.h"
|
||||
|
||||
//#include "func_dbg.h"
|
||||
#include "string.h"
|
||||
#include "usbd_macro_def.h"
|
||||
#include "usbd_func_cconf.h"
|
||||
#include "usbd_func_cc.h"
|
||||
#include "usbd_multi_usrcfg_common.h"
|
||||
#define CC_CUSTP2_CMDEP_MPS 16
|
||||
|
||||
const usbd_cdc_desc_custp2_st t_usbd_cdc_desc_custp2 = {
|
||||
.intf_ctrl_desc = {
|
||||
/*Interface Descriptor */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
/* Interface descriptor type */
|
||||
INVALID_INTF_NUM, //VCOM_INTF_NUM_0, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x03, /* bNumEndpoints: One endpoints used */
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x01, /* bInterfaceProtocol: Common AT commands */
|
||||
0x00, /* iInterface: */
|
||||
},
|
||||
|
||||
.cdc_head_desc = {
|
||||
/*Header Functional Descriptor*/
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x00, /* bDescriptorSubtype: Header Func Desc */
|
||||
0x10, /* bcdCDC: spec release number */
|
||||
0x01,
|
||||
},
|
||||
|
||||
.cdc_callmgr_desc = {
|
||||
/*Call Management Functional Descriptor*/
|
||||
0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x01, /* bDescriptorSubtype: Call Management Func Desc */
|
||||
0x00, /* bmCapabilities: D0+D1 */
|
||||
INVALID_INTF_NUM, /* bDataInterface: 1 */
|
||||
},
|
||||
|
||||
.cdc_acm_desc = {
|
||||
/*ACM Functional Descriptor*/
|
||||
0x04, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
|
||||
0x02, /* bmCapabilities */
|
||||
},
|
||||
|
||||
.cdc_union_desc = {
|
||||
/*Union Functional Descriptor*/
|
||||
0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x06, /* bDescriptorSubtype: Union func desc */
|
||||
INVALID_INTF_NUM,//VCOM_INTF_NUM_0, /* bMasterInterface: Communication class interface */
|
||||
INVALID_INTF_NUM,//VCOM_INTF_NUM_1, /* bSlaveInterface0: Data Class Interface */
|
||||
},
|
||||
|
||||
.cdc_cmd_ep_desc = {
|
||||
/*Endpoint 2 Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
INVALID_EP_NUM, //CDC_CMD_EP, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
LOBYTE(CC_CUSTP2_CMDEP_MPS), /* wMaxPacketSize: */
|
||||
HIBYTE(CC_CUSTP2_CMDEP_MPS),
|
||||
#ifdef USE_USBC_CTRL_HS
|
||||
0x10, /* bInterval: */
|
||||
#else
|
||||
0xFF, /* bInterval: */
|
||||
#endif /* USE_USBC_CTRL_HS */
|
||||
},
|
||||
|
||||
|
||||
.cdc_diep_desc = {
|
||||
/*Endpoint IN Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
INVALID_EP_NUM, //CDC_IN_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
|
||||
0x00 /* bInterval */
|
||||
},
|
||||
|
||||
.cdc_doep_desc = {
|
||||
/*Endpoint OUT Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
INVALID_EP_NUM, //CDC_OUT_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
uint8_t vcom_func_custp2_desc_ass(usb_func_ccinst_st *p_func_ccinst)
|
||||
{
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
p_ccinst_cdc_setting->desc_assigned = 0;
|
||||
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp2_3ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
p_ccinst_cdc_setting->p_desc_src =(const uint8_t *)(&t_usbd_cdc_desc_custp2);
|
||||
p_ccinst_cdc_setting->desc_src_size = sizeof(t_usbd_cdc_desc_custp2);
|
||||
p_ccinst_cdc_setting->desc_assigned = 1;
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp2_desc_parse(usb_func_ccinst_st *p_func_ccinst)
|
||||
{
|
||||
const uint8_t * p_desc_buf;
|
||||
uint16_t pos = 0;
|
||||
uint8_t ret = usbd_ret_no_err;
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
usb_endpoint_descriptor_st * p_endp_d;
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp2_3ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
if(p_ccinst_cdc_setting->desc_assigned!=1)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
p_desc_buf = p_ccinst_cdc_setting->p_desc_src;
|
||||
|
||||
p_ccinst_cdc_setting->desc_parsed = 0;
|
||||
|
||||
p_ccinst_cdc_setting->epctrl_valid = 0;
|
||||
p_ccinst_cdc_setting->epin_valid = 0;
|
||||
p_ccinst_cdc_setting->epout_valid = 0;
|
||||
|
||||
p_ccinst_cdc_setting->interface_cnt = 0;
|
||||
|
||||
while(pos < p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
if (p_desc_buf[pos] == 0)
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
if ((pos+ p_desc_buf[pos]) > p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (p_desc_buf[pos+1])
|
||||
{
|
||||
case USB_ENDPOINT_DESCRIPTOR_TYPE:
|
||||
if (p_desc_buf[pos] != STANDARD_ENDPOINT_DESC_SIZE)
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
p_endp_d = (usb_endpoint_descriptor_st *)(&(p_desc_buf[pos]));
|
||||
if (p_endp_d->bmAttributes == USBC_CTRL_EP_BULK)
|
||||
{
|
||||
//if (p_endp_d->bEndpointAddress &0x80)
|
||||
if (p_endp_d == (&t_usbd_cdc_desc_custp2.cdc_diep_desc))
|
||||
{
|
||||
p_ccinst_cdc_setting->epin_valid = 1;
|
||||
p_ccinst_cdc_setting->p_epin_d = p_endp_d;
|
||||
}
|
||||
else if (p_endp_d == (&t_usbd_cdc_desc_custp2.cdc_doep_desc))
|
||||
{
|
||||
p_ccinst_cdc_setting->epout_valid = 1;
|
||||
p_ccinst_cdc_setting->p_epout_d = p_endp_d;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (p_endp_d->bmAttributes == USBC_CTRL_EP_INTR)
|
||||
{
|
||||
if (p_endp_d->bEndpointAddress &0x80)
|
||||
{
|
||||
p_ccinst_cdc_setting->epctrl_valid = 1;
|
||||
p_ccinst_cdc_setting->p_epctrl_d = p_endp_d;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case USB_INTERFACE_DESCRIPTOR_TYPE:
|
||||
if (p_desc_buf[pos] !=STANDARD_INTERFACE_DESC_SIZE)
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
|
||||
p_ccinst_cdc_setting->interface_cnt++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (ret!=usbd_ret_no_err)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos+= p_desc_buf[pos];
|
||||
}
|
||||
|
||||
if ((p_ccinst_cdc_setting->epctrl_valid ==0) ||
|
||||
(p_ccinst_cdc_setting->epin_valid ==0) ||
|
||||
(p_ccinst_cdc_setting->epout_valid==0)||
|
||||
(p_ccinst_cdc_setting->interface_cnt!=1) )
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
p_ccinst_cdc_setting->desc_parsed = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp2_bind(usb_func_ccinst_st *p_func_ccinst,
|
||||
ccinst_bind_call_data_st *p_bind_call_data)
|
||||
{
|
||||
uint8_t ret = usbd_ret_no_err;
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp2_3ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((p_ccinst_cdc_setting->desc_assigned==0)
|
||||
|| (p_ccinst_cdc_setting->desc_parsed==0))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
p_ccinst_cdc_setting->ep_ctrl_num = p_bind_call_data->ep_ctrl_num;
|
||||
p_ccinst_cdc_setting->ep_datain_num = p_bind_call_data->ep_datain_num;
|
||||
p_ccinst_cdc_setting->ep_dataout_num = p_bind_call_data->ep_dataout_num;
|
||||
|
||||
|
||||
p_ccinst_cdc_setting->intf_base_idx = p_bind_call_data->intf_base_idx;
|
||||
p_ccinst_cdc_setting->intf_1st_idx = p_bind_call_data->intf_1st_idx;
|
||||
p_ccinst_cdc_setting->intf_2nd_idx = p_bind_call_data->intf_2nd_idx;
|
||||
p_ccinst_cdc_setting->intf_str_id = p_bind_call_data->intf_str_id;
|
||||
p_ccinst_cdc_setting->binded = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp2_get_desc(usb_func_ccinst_st *p_func_ccinst, ccinst_desc_call_data_st*p_desc_call_data)
|
||||
{
|
||||
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
usbd_cdc_desc_custp2_st *p_usbd_desc_dst;
|
||||
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp2_3ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_desc_call_data->desc_buff_size < p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
if (p_ccinst_cdc_setting->binded == 0)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
p_usbd_desc_dst = (usbd_cdc_desc_custp2_st *)(p_desc_call_data->p_desc_buff_ptr);
|
||||
|
||||
memcpy(p_usbd_desc_dst, p_ccinst_cdc_setting->p_desc_src, p_ccinst_cdc_setting->desc_src_size);
|
||||
p_usbd_desc_dst->cdc_cmd_ep_desc.bEndpointAddress = EPIN_MARK_DIR(p_ccinst_cdc_setting->ep_ctrl_num);
|
||||
p_usbd_desc_dst->cdc_diep_desc.bEndpointAddress = EPIN_MARK_DIR(p_ccinst_cdc_setting->ep_datain_num);
|
||||
p_usbd_desc_dst->cdc_doep_desc.bEndpointAddress = p_ccinst_cdc_setting->ep_dataout_num;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.iInterface = p_ccinst_cdc_setting->intf_str_id;
|
||||
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceNumber = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
|
||||
p_usbd_desc_dst->cdc_union_desc.bMasterInterface0 = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
p_usbd_desc_dst->cdc_union_desc.bSlaveInterface0 = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
|
||||
if (p_desc_call_data->b_intf_ctrl_desc_upd)
|
||||
{
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceClass = p_desc_call_data->bInterfaceClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceSubClass = p_desc_call_data->bInterfaceSubClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceProtocol = p_desc_call_data->bInterfaceProtocol;
|
||||
}
|
||||
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp2_get_othspd_desc(usb_func_ccinst_st *p_func_ccinst, ccinst_desc_call_data_st*p_desc_call_data)
|
||||
{
|
||||
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
usbd_cdc_desc_custp2_st *p_usbd_desc_dst;
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp2_3ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_desc_call_data->desc_buff_size < p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
if (p_ccinst_cdc_setting->binded == 0)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
p_usbd_desc_dst = (usbd_cdc_desc_custp2_st*)(p_desc_call_data->p_desc_buff_ptr);
|
||||
memcpy(p_usbd_desc_dst, p_ccinst_cdc_setting->p_desc_src, p_ccinst_cdc_setting->desc_src_size);
|
||||
|
||||
|
||||
p_usbd_desc_dst->cdc_cmd_ep_desc.bEndpointAddress = EPIN_MARK_DIR(p_ccinst_cdc_setting->ep_ctrl_num);
|
||||
p_usbd_desc_dst->cdc_cmd_ep_desc.bInterval = 0xff;
|
||||
|
||||
p_usbd_desc_dst->cdc_diep_desc.bEndpointAddress = EPIN_MARK_DIR(p_ccinst_cdc_setting->ep_datain_num);
|
||||
p_usbd_desc_dst->cdc_doep_desc.bEndpointAddress = p_ccinst_cdc_setting->ep_dataout_num;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.iInterface = p_ccinst_cdc_setting->intf_str_id;
|
||||
p_usbd_desc_dst->cdc_diep_desc.wMaxPacketSize_High = 0;
|
||||
p_usbd_desc_dst->cdc_diep_desc.wMaxPacketSize_Low = 0x40;
|
||||
p_usbd_desc_dst->cdc_doep_desc.wMaxPacketSize_High = 0;
|
||||
p_usbd_desc_dst->cdc_doep_desc.wMaxPacketSize_Low = 0x40;
|
||||
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceNumber = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
p_usbd_desc_dst->cdc_union_desc.bMasterInterface0 = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
p_usbd_desc_dst->cdc_union_desc.bSlaveInterface0 = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
|
||||
|
||||
if (p_desc_call_data->b_intf_ctrl_desc_upd)
|
||||
{
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceClass = p_desc_call_data->bInterfaceClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceSubClass = p_desc_call_data->bInterfaceSubClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceProtocol = p_desc_call_data->bInterfaceProtocol;
|
||||
}
|
||||
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t vcom_func_custp2_init(usb_func_ccinst_st *p_func_ccinst, uint8_t cfgidx)
|
||||
{
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp2_deinit(usb_func_ccinst_st *p_func_ccinst, uint8_t cfgidx)
|
||||
{
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_custp2_unbind(usb_func_ccinst_st *p_func_ccinst)
|
||||
{
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp2_3ep))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_ccinst_cdc_setting->binded==0)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
p_ccinst_cdc_setting->binded = 0;
|
||||
|
||||
return usbd_ret_no_err;
|
||||
|
||||
}
|
||||
|
||||
#if (VCOM_CCINST_SUBTP2_3EP_CNT > 0)
|
||||
const ccinst_setting_base_st t_vcom_custp2_base_setting =
|
||||
{
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp2_3ep
|
||||
};
|
||||
|
||||
ccinst_cdc_setting_st t_vcom_custp2_setting_arr[VCOM_CCINST_SUBTP2_3EP_CNT] ={
|
||||
//[0]
|
||||
{
|
||||
.bs_set = t_vcom_custp2_base_setting,
|
||||
},
|
||||
|
||||
#if (VCOM_CCINST_SUBTP2_3EP_CNT >=2)
|
||||
//[1]
|
||||
{
|
||||
.bs_set = t_vcom_custp2_base_setting,
|
||||
},
|
||||
#endif
|
||||
|
||||
#if (VCOM_CCINST_SUBTP2_3EP_CNT >= 3)
|
||||
//[2]
|
||||
{
|
||||
.bs_set = t_vcom_custp2_base_setting,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
usb_func_ccinst_st t_vcom_func_custp2_arr[VCOM_CCINST_SUBTP2_3EP_CNT] ={
|
||||
//[0]
|
||||
{
|
||||
.p_cc_setting = &t_vcom_custp2_setting_arr[0],
|
||||
.func_desc_ass = vcom_func_custp2_desc_ass,
|
||||
.func_desc_parse = vcom_func_custp2_desc_parse,
|
||||
.func_bind = vcom_func_custp2_bind,
|
||||
.func_get_desc = vcom_func_custp2_get_desc,
|
||||
.func_get_othspd_desc = vcom_func_custp2_get_othspd_desc,
|
||||
|
||||
.func_init = vcom_func_custp2_init,
|
||||
.func_deinit = vcom_func_custp2_deinit,
|
||||
.func_unbind = vcom_func_custp2_unbind,
|
||||
},
|
||||
|
||||
#if (VCOM_CCINST_SUBTP2_3EP_CNT >=2)
|
||||
//[1]
|
||||
|
||||
{
|
||||
.p_cc_setting = &t_vcom_custp2_setting_arr[1],
|
||||
|
||||
.func_desc_ass = vcom_func_custp2_desc_ass,
|
||||
.func_desc_parse = vcom_func_custp2_desc_parse,
|
||||
.func_bind = vcom_func_custp2_bind,
|
||||
.func_get_desc = vcom_func_custp2_get_desc,
|
||||
.func_get_othspd_desc = vcom_func_custp2_get_othspd_desc,
|
||||
|
||||
.func_init = vcom_func_custp2_init,
|
||||
.func_deinit = vcom_func_custp2_deinit,
|
||||
.func_unbind = vcom_func_custp2_unbind,
|
||||
},
|
||||
#endif
|
||||
|
||||
#if (VCOM_CCINST_SUBTP2_3EP_CNT >= 3)
|
||||
//[2]
|
||||
{
|
||||
.p_cc_setting = &t_vcom_custp2_setting_arr[2],
|
||||
.func_desc_ass = vcom_func_custp2_desc_ass,
|
||||
.func_desc_parse = vcom_func_custp2_desc_parse,
|
||||
.func_bind = vcom_func_custp2_bind,
|
||||
.func_get_desc = vcom_func_custp2_get_desc,
|
||||
.func_get_othspd_desc = vcom_func_custp2_get_othspd_desc,
|
||||
|
||||
.func_init = vcom_func_custp2_init,
|
||||
.func_deinit = vcom_func_custp2_deinit,
|
||||
.func_unbind = vcom_func_custp2_unbind,
|
||||
},
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,603 @@
|
||||
#include "usbd_clscdc.h"
|
||||
#include "usbd_clscdc_cust_tp.h"
|
||||
|
||||
#include "string.h"
|
||||
#include "usbd_macro_def.h"
|
||||
#include "usbd_func_cconf.h"
|
||||
#include "usbd_func_cc.h"
|
||||
#include "usbd_multi_usrcfg_common.h"
|
||||
typedef struct tag_usbd_cdc_ccinst_desc_inhrnt usbd_cdc_desc_inhrnt_st;
|
||||
|
||||
#define CC_INHRNT_CMDEP_MPS 16
|
||||
|
||||
|
||||
#define CCINHRNT_SET_LAST_ERR(err_no) usbd_set_mod_last_err(usb_ccinst_inhrnt_mod, err_no)
|
||||
|
||||
|
||||
const usbd_cdc_desc_inhrnt_st t_usbd_cdc_desc_inhrnt = {
|
||||
.intf_asso_desc = {
|
||||
// IAD COM1
|
||||
0x08, // bLength: Interface Descriptor size
|
||||
0x0B, // bDescriptorType: IAD
|
||||
INVALID_INTF_NUM, //VCOM_INTF_NUM_0, bFirstInterface
|
||||
0x02, // bInterfaceCount
|
||||
0x02, // bFunctionClass: CDC
|
||||
0x02, // bFunctionSubClass
|
||||
0x01, // bFunctionProtocol
|
||||
0x02, // iFunction
|
||||
},
|
||||
|
||||
.intf_ctrl_desc = {
|
||||
/*Interface Descriptor */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
/* Interface descriptor type */
|
||||
INVALID_INTF_NUM, //VCOM_INTF_NUM_0, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints: One endpoints used */
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x01, /* bInterfaceProtocol: Common AT commands */
|
||||
0x00, /* iInterface: */
|
||||
},
|
||||
|
||||
.cdc_head_desc = {
|
||||
/*Header Functional Descriptor*/
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x00, /* bDescriptorSubtype: Header Func Desc */
|
||||
0x10, /* bcdCDC: spec release number */
|
||||
0x01,
|
||||
},
|
||||
|
||||
.cdc_callmgr_desc = {
|
||||
/*Call Management Functional Descriptor*/
|
||||
0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x01, /* bDescriptorSubtype: Call Management Func Desc */
|
||||
0x00, /* bmCapabilities: D0+D1 */
|
||||
INVALID_INTF_NUM, /* bDataInterface: 1 */
|
||||
},
|
||||
|
||||
.cdc_acm_desc = {
|
||||
/*ACM Functional Descriptor*/
|
||||
0x04, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
|
||||
0x02, /* bmCapabilities */
|
||||
},
|
||||
|
||||
.cdc_union_desc = {
|
||||
/*Union Functional Descriptor*/
|
||||
0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x06, /* bDescriptorSubtype: Union func desc */
|
||||
INVALID_INTF_NUM,//VCOM_INTF_NUM_0, /* bMasterInterface: Communication class interface */
|
||||
INVALID_INTF_NUM,//VCOM_INTF_NUM_1, /* bSlaveInterface0: Data Class Interface */
|
||||
},
|
||||
|
||||
.cdc_cmd_ep_desc = {
|
||||
/*Endpoint 2 Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
INVALID_EP_NUM, //CDC_CMD_EP, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
LOBYTE(CC_INHRNT_CMDEP_MPS), /* wMaxPacketSize: */
|
||||
HIBYTE(CC_INHRNT_CMDEP_MPS),
|
||||
#ifdef USE_USBC_CTRL_HS
|
||||
0x10, /* bInterval: */
|
||||
#else
|
||||
0xFF, /* bInterval: */
|
||||
#endif /* USE_USBC_CTRL_HS */
|
||||
},
|
||||
|
||||
.intf_data_desc = {
|
||||
/*Data class interface descriptor*/
|
||||
0x09, /* bLength: Endpoint Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
|
||||
INVALID_INTF_NUM, //VCOM_INTF_NUM_1, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints: Two endpoints used */
|
||||
0x0A, /* bInterfaceClass: CDC */
|
||||
0x00, /* bInterfaceSubClass: */
|
||||
0x00, /* bInterfaceProtocol: */
|
||||
0x00, /* iInterface: */
|
||||
},
|
||||
|
||||
|
||||
.cdc_diep_desc = {
|
||||
/*Endpoint IN Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
INVALID_EP_NUM, //CDC_IN_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
|
||||
0x00 /* bInterval */
|
||||
},
|
||||
|
||||
.cdc_doep_desc = {
|
||||
/*Endpoint OUT Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
INVALID_EP_NUM, //CDC_OUT_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
uint8_t vcom_func_inhrnt_desc_ass(usb_func_ccinst_st *p_func_ccinst)
|
||||
{
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
p_ccinst_cdc_setting->desc_assigned = 0;
|
||||
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp0_inhrnt))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
p_ccinst_cdc_setting->p_desc_src =(const uint8_t *)(&t_usbd_cdc_desc_inhrnt);
|
||||
p_ccinst_cdc_setting->desc_src_size = sizeof(t_usbd_cdc_desc_inhrnt);
|
||||
p_ccinst_cdc_setting->desc_assigned = 1;
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_inhrnt_desc_parse(usb_func_ccinst_st *p_func_ccinst)
|
||||
{
|
||||
const uint8_t * p_desc_buf;
|
||||
uint16_t pos = 0;
|
||||
uint8_t ret = usbd_ret_no_err;
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
usb_endpoint_descriptor_st * p_endp_d;
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp0_inhrnt))
|
||||
{
|
||||
CCINHRNT_SET_LAST_ERR(desc_parse_err_tpinvalid);
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
if(p_ccinst_cdc_setting->desc_assigned!=1)
|
||||
{
|
||||
CCINHRNT_SET_LAST_ERR(desc_parse_err_ass0);
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
p_desc_buf = p_ccinst_cdc_setting->p_desc_src;
|
||||
|
||||
p_ccinst_cdc_setting->desc_parsed = 0;
|
||||
|
||||
p_ccinst_cdc_setting->epctrl_valid = 0;
|
||||
p_ccinst_cdc_setting->epin_valid = 0;
|
||||
p_ccinst_cdc_setting->epout_valid = 0;
|
||||
|
||||
p_ccinst_cdc_setting->interface_cnt = 0;
|
||||
|
||||
while(pos < p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
if (p_desc_buf[pos] == 0)
|
||||
{
|
||||
CCINHRNT_SET_LAST_ERR(desc_parse_err_len0);
|
||||
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
if ((pos+ p_desc_buf[pos]) > p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
CCINHRNT_SET_LAST_ERR(desc_parse_err_len_ovf);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (p_desc_buf[pos+1])
|
||||
{
|
||||
case USB_ENDPOINT_DESCRIPTOR_TYPE:
|
||||
if (p_desc_buf[pos] != STANDARD_ENDPOINT_DESC_SIZE)
|
||||
{
|
||||
CCINHRNT_SET_LAST_ERR(desc_parse_err_epdesclen);
|
||||
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
p_endp_d = (usb_endpoint_descriptor_st *)(&(p_desc_buf[pos]));
|
||||
if (p_endp_d->bmAttributes == USBC_CTRL_EP_BULK)
|
||||
{
|
||||
//if (p_endp_d->bEndpointAddress &0x80)
|
||||
if (p_endp_d == (&t_usbd_cdc_desc_inhrnt.cdc_diep_desc))
|
||||
{
|
||||
p_ccinst_cdc_setting->epin_valid = 1;
|
||||
p_ccinst_cdc_setting->p_epin_d = p_endp_d;
|
||||
}
|
||||
else if (p_endp_d == (&t_usbd_cdc_desc_inhrnt.cdc_doep_desc))
|
||||
{
|
||||
p_ccinst_cdc_setting->epout_valid = 1;
|
||||
p_ccinst_cdc_setting->p_epout_d = p_endp_d;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCINHRNT_SET_LAST_ERR(desc_parse_err_epdescptr_1);
|
||||
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (p_endp_d->bmAttributes == USBC_CTRL_EP_INTR)
|
||||
{
|
||||
if (p_endp_d == (&t_usbd_cdc_desc_inhrnt.cdc_cmd_ep_desc))
|
||||
|
||||
{
|
||||
p_ccinst_cdc_setting->epctrl_valid = 1;
|
||||
p_ccinst_cdc_setting->p_epctrl_d = p_endp_d;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
CCINHRNT_SET_LAST_ERR(desc_parse_err_epdescptr_2);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case USB_INTERFACE_DESCRIPTOR_TYPE:
|
||||
if (p_desc_buf[pos] !=STANDARD_INTERFACE_DESC_SIZE)
|
||||
{
|
||||
CCINHRNT_SET_LAST_ERR(desc_parse_err_intfdesclen);
|
||||
|
||||
ret = usbd_ret_fail;
|
||||
break;
|
||||
}
|
||||
|
||||
p_ccinst_cdc_setting->interface_cnt++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (ret!=usbd_ret_no_err)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos+= p_desc_buf[pos];
|
||||
}
|
||||
|
||||
if (ret!=usbd_ret_no_err)
|
||||
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if ((p_ccinst_cdc_setting->epctrl_valid ==0) ||
|
||||
(p_ccinst_cdc_setting->epin_valid ==0) ||
|
||||
(p_ccinst_cdc_setting->epout_valid==0)||
|
||||
(p_ccinst_cdc_setting->interface_cnt!=2) )
|
||||
{
|
||||
CCINHRNT_SET_LAST_ERR(desc_parse_err_parserslt);
|
||||
|
||||
ret = usbd_ret_fail;
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
p_ccinst_cdc_setting->desc_parsed = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_inhrnt_bind(usb_func_ccinst_st *p_func_ccinst,
|
||||
ccinst_bind_call_data_st *p_bind_call_data)
|
||||
{
|
||||
uint8_t ret = usbd_ret_no_err;
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp0_inhrnt))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((p_ccinst_cdc_setting->desc_assigned==0)
|
||||
|| (p_ccinst_cdc_setting->desc_parsed==0))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
p_ccinst_cdc_setting->ep_ctrl_num = p_bind_call_data->ep_ctrl_num;
|
||||
p_ccinst_cdc_setting->ep_datain_num = p_bind_call_data->ep_datain_num;
|
||||
p_ccinst_cdc_setting->ep_dataout_num = p_bind_call_data->ep_dataout_num;
|
||||
|
||||
|
||||
p_ccinst_cdc_setting->intf_base_idx = p_bind_call_data->intf_base_idx;
|
||||
p_ccinst_cdc_setting->intf_1st_idx = p_bind_call_data->intf_1st_idx;
|
||||
p_ccinst_cdc_setting->intf_2nd_idx = p_bind_call_data->intf_2nd_idx;
|
||||
p_ccinst_cdc_setting->intf_str_id = p_bind_call_data->intf_str_id;
|
||||
|
||||
p_ccinst_cdc_setting->binded = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_inhrnt_get_desc(usb_func_ccinst_st *p_func_ccinst, ccinst_desc_call_data_st*p_desc_call_data)
|
||||
{
|
||||
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
usbd_cdc_desc_inhrnt_st *p_usbd_desc_dst;
|
||||
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp0_inhrnt))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_desc_call_data->desc_buff_size < p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
if (p_ccinst_cdc_setting->binded == 0)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
p_usbd_desc_dst = (usbd_cdc_desc_inhrnt_st *)(p_desc_call_data->p_desc_buff_ptr);
|
||||
memcpy(p_usbd_desc_dst, p_ccinst_cdc_setting->p_desc_src, p_ccinst_cdc_setting->desc_src_size);
|
||||
|
||||
|
||||
p_usbd_desc_dst->cdc_cmd_ep_desc.bEndpointAddress = EPIN_MARK_DIR(p_ccinst_cdc_setting->ep_ctrl_num);
|
||||
p_usbd_desc_dst->cdc_diep_desc.bEndpointAddress = EPIN_MARK_DIR(p_ccinst_cdc_setting->ep_datain_num);
|
||||
p_usbd_desc_dst->cdc_doep_desc.bEndpointAddress = p_ccinst_cdc_setting->ep_dataout_num;
|
||||
|
||||
|
||||
p_usbd_desc_dst->cdc_callmgr_desc.bDataInterface = p_ccinst_cdc_setting->intf_2nd_idx;
|
||||
|
||||
p_usbd_desc_dst->intf_asso_desc.bFirstInterface = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
p_usbd_desc_dst->intf_asso_desc.bInterfaceCount = p_ccinst_cdc_setting->interface_cnt;
|
||||
|
||||
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceNumber = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
p_usbd_desc_dst->cdc_union_desc.bMasterInterface0 = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
p_usbd_desc_dst->cdc_union_desc.bSlaveInterface0 = p_ccinst_cdc_setting->intf_2nd_idx;
|
||||
|
||||
p_usbd_desc_dst->intf_data_desc.bInterfaceNumber = p_ccinst_cdc_setting->intf_2nd_idx;
|
||||
|
||||
p_usbd_desc_dst->intf_ctrl_desc.iInterface = p_ccinst_cdc_setting->intf_str_id;
|
||||
p_usbd_desc_dst->intf_asso_desc.iFunction = p_ccinst_cdc_setting->intf_str_id;
|
||||
|
||||
if (p_desc_call_data->b_intf_ctrl_desc_upd)
|
||||
{
|
||||
p_usbd_desc_dst->intf_asso_desc.bFunctionClass = p_desc_call_data->bInterfaceClass;
|
||||
p_usbd_desc_dst->intf_asso_desc.bFunctionSubClass = p_desc_call_data->bInterfaceSubClass;
|
||||
p_usbd_desc_dst->intf_asso_desc.bFunctionProtocol = p_desc_call_data->bInterfaceProtocol;
|
||||
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceClass = p_desc_call_data->bInterfaceClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceSubClass = p_desc_call_data->bInterfaceSubClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceProtocol = p_desc_call_data->bInterfaceProtocol;
|
||||
}
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_inhrnt_get_othspd_desc(usb_func_ccinst_st *p_func_ccinst, ccinst_desc_call_data_st*p_desc_call_data)
|
||||
{
|
||||
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
usbd_cdc_desc_inhrnt_st *p_usbd_desc_dst;
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp0_inhrnt))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_desc_call_data->desc_buff_size < p_ccinst_cdc_setting->desc_src_size)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
if (p_ccinst_cdc_setting->binded == 0)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
|
||||
p_usbd_desc_dst = (usbd_cdc_desc_inhrnt_st*)(p_desc_call_data->p_desc_buff_ptr);
|
||||
memcpy(p_usbd_desc_dst, p_ccinst_cdc_setting->p_desc_src, p_ccinst_cdc_setting->desc_src_size);
|
||||
|
||||
|
||||
p_usbd_desc_dst->cdc_cmd_ep_desc.bEndpointAddress = EPIN_MARK_DIR(p_ccinst_cdc_setting->ep_ctrl_num);
|
||||
p_usbd_desc_dst->cdc_cmd_ep_desc.bInterval = 0xff;
|
||||
|
||||
p_usbd_desc_dst->cdc_diep_desc.bEndpointAddress = EPIN_MARK_DIR(p_ccinst_cdc_setting->ep_datain_num);
|
||||
p_usbd_desc_dst->cdc_doep_desc.bEndpointAddress = p_ccinst_cdc_setting->ep_dataout_num;
|
||||
|
||||
p_usbd_desc_dst->cdc_diep_desc.wMaxPacketSize_High = 0;
|
||||
p_usbd_desc_dst->cdc_diep_desc.wMaxPacketSize_Low = 0x40;
|
||||
p_usbd_desc_dst->cdc_doep_desc.wMaxPacketSize_High = 0;
|
||||
p_usbd_desc_dst->cdc_doep_desc.wMaxPacketSize_Low = 0x40;
|
||||
|
||||
p_usbd_desc_dst->cdc_callmgr_desc.bDataInterface = p_ccinst_cdc_setting->intf_2nd_idx;
|
||||
|
||||
p_usbd_desc_dst->intf_asso_desc.bFirstInterface = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
p_usbd_desc_dst->intf_asso_desc.bInterfaceCount = p_ccinst_cdc_setting->interface_cnt;
|
||||
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceNumber = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
p_usbd_desc_dst->cdc_union_desc.bMasterInterface0 = p_ccinst_cdc_setting->intf_1st_idx;
|
||||
p_usbd_desc_dst->cdc_union_desc.bSlaveInterface0 = p_ccinst_cdc_setting->intf_2nd_idx;
|
||||
|
||||
p_usbd_desc_dst->intf_data_desc.bInterfaceNumber = p_ccinst_cdc_setting->intf_2nd_idx;
|
||||
|
||||
p_usbd_desc_dst->intf_ctrl_desc.iInterface = p_ccinst_cdc_setting->intf_str_id;
|
||||
p_usbd_desc_dst->intf_asso_desc.iFunction = p_ccinst_cdc_setting->intf_str_id;
|
||||
|
||||
if (p_desc_call_data->b_intf_ctrl_desc_upd)
|
||||
{
|
||||
p_usbd_desc_dst->intf_asso_desc.bFunctionClass = p_desc_call_data->bInterfaceClass;
|
||||
p_usbd_desc_dst->intf_asso_desc.bFunctionSubClass = p_desc_call_data->bInterfaceSubClass;
|
||||
p_usbd_desc_dst->intf_asso_desc.bFunctionProtocol = p_desc_call_data->bInterfaceProtocol;
|
||||
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceClass = p_desc_call_data->bInterfaceClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceSubClass = p_desc_call_data->bInterfaceSubClass;
|
||||
p_usbd_desc_dst->intf_ctrl_desc.bInterfaceProtocol = p_desc_call_data->bInterfaceProtocol;
|
||||
}
|
||||
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t vcom_func_inhrnt_init(usb_func_ccinst_st *p_func_ccinst, uint8_t cfgidx)
|
||||
{
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_inhrnt_deinit(usb_func_ccinst_st *p_func_ccinst, uint8_t cfgidx)
|
||||
{
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
uint8_t vcom_func_inhrnt_unbind(usb_func_ccinst_st *p_func_ccinst)
|
||||
{
|
||||
ccinst_cdc_setting_st* p_ccinst_cdc_setting;
|
||||
|
||||
p_ccinst_cdc_setting = p_func_ccinst->p_cc_setting;
|
||||
#ifdef VCOM_CHK_CCINST_TYPE
|
||||
if ((p_ccinst_cdc_setting->bs_set.setting_maintp!=ccinst_setting_cdc_vcom_maintp) ||
|
||||
(p_ccinst_cdc_setting->bs_set.setting_subtp != ccinst_setting_vcom_subtp0_inhrnt))
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_ccinst_cdc_setting->binded==0)
|
||||
{
|
||||
return usbd_ret_fail;
|
||||
}
|
||||
p_ccinst_cdc_setting->binded = 0;
|
||||
|
||||
|
||||
return usbd_ret_no_err;
|
||||
}
|
||||
|
||||
#if (VCOM_CCINST_SUBTP0_INHERENT_CNT > 0)
|
||||
const ccinst_setting_base_st t_vcom_custp0_base_setting =
|
||||
{
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
};
|
||||
|
||||
ccinst_cdc_setting_st t_vcom_custp0_setting_arr[VCOM_CCINST_SUBTP0_INHERENT_CNT] ={
|
||||
//[0]
|
||||
{
|
||||
.bs_set = t_vcom_custp0_base_setting,
|
||||
},
|
||||
|
||||
#if (VCOM_CCINST_SUBTP0_INHERENT_CNT >=2)
|
||||
//[1]
|
||||
{
|
||||
.bs_set = t_vcom_custp0_base_setting,
|
||||
},
|
||||
#endif
|
||||
|
||||
#if (VCOM_CCINST_SUBTP0_INHERENT_CNT >= 3)
|
||||
//[2]
|
||||
{
|
||||
.bs_set = t_vcom_custp0_base_setting,
|
||||
},
|
||||
#endif
|
||||
|
||||
#if (VCOM_CCINST_SUBTP0_INHERENT_CNT >= 4)
|
||||
//[2]
|
||||
{
|
||||
.bs_set = t_vcom_custp0_base_setting,
|
||||
},
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
usb_func_ccinst_st t_vcom_func_custp0_inhrnt_arr[VCOM_CCINST_SUBTP0_INHERENT_CNT] ={
|
||||
//[0]
|
||||
{
|
||||
.p_cc_setting = &t_vcom_custp0_setting_arr[0],
|
||||
.func_desc_ass = vcom_func_inhrnt_desc_ass,
|
||||
.func_desc_parse = vcom_func_inhrnt_desc_parse,
|
||||
.func_bind = vcom_func_inhrnt_bind,
|
||||
.func_get_desc = vcom_func_inhrnt_get_desc,
|
||||
.func_get_othspd_desc = vcom_func_inhrnt_get_othspd_desc,
|
||||
|
||||
.func_init = vcom_func_inhrnt_init,
|
||||
.func_deinit = vcom_func_inhrnt_deinit,
|
||||
.func_unbind = vcom_func_inhrnt_unbind,
|
||||
},
|
||||
|
||||
#if (VCOM_CCINST_SUBTP0_INHERENT_CNT >=2)
|
||||
//[1]
|
||||
|
||||
{
|
||||
.p_cc_setting = &t_vcom_custp0_setting_arr[1],
|
||||
|
||||
.func_desc_ass = vcom_func_inhrnt_desc_ass,
|
||||
.func_desc_parse = vcom_func_inhrnt_desc_parse,
|
||||
.func_bind = vcom_func_inhrnt_bind,
|
||||
.func_get_desc = vcom_func_inhrnt_get_desc,
|
||||
.func_get_othspd_desc = vcom_func_inhrnt_get_othspd_desc,
|
||||
|
||||
.func_init = vcom_func_inhrnt_init,
|
||||
.func_deinit = vcom_func_inhrnt_deinit,
|
||||
.func_unbind = vcom_func_inhrnt_unbind,
|
||||
},
|
||||
#endif
|
||||
|
||||
#if (VCOM_CCINST_SUBTP0_INHERENT_CNT >= 3)
|
||||
//[2]
|
||||
{
|
||||
.p_cc_setting = &t_vcom_custp0_setting_arr[2],
|
||||
.func_desc_ass = vcom_func_inhrnt_desc_ass,
|
||||
.func_desc_parse = vcom_func_inhrnt_desc_parse,
|
||||
.func_bind = vcom_func_inhrnt_bind,
|
||||
.func_get_desc = vcom_func_inhrnt_get_desc,
|
||||
.func_get_othspd_desc = vcom_func_inhrnt_get_othspd_desc,
|
||||
|
||||
.func_init = vcom_func_inhrnt_init,
|
||||
.func_deinit = vcom_func_inhrnt_deinit,
|
||||
.func_unbind = vcom_func_inhrnt_unbind,
|
||||
},
|
||||
#endif
|
||||
|
||||
#if (VCOM_CCINST_SUBTP0_INHERENT_CNT >= 4)
|
||||
//[3]
|
||||
{
|
||||
.p_cc_setting = &t_vcom_custp0_setting_arr[3],
|
||||
.func_desc_ass = vcom_func_inhrnt_desc_ass,
|
||||
.func_desc_parse = vcom_func_inhrnt_desc_parse,
|
||||
.func_bind = vcom_func_inhrnt_bind,
|
||||
.func_get_desc = vcom_func_inhrnt_get_desc,
|
||||
.func_get_othspd_desc = vcom_func_inhrnt_get_othspd_desc,
|
||||
|
||||
.func_init = vcom_func_inhrnt_init,
|
||||
.func_deinit = vcom_func_inhrnt_deinit,
|
||||
.func_unbind = vcom_func_inhrnt_unbind,
|
||||
},
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
#include "bsp.h"
|
||||
//#include "bsp_custom.h"
|
||||
#ifndef USB_DRV_SMALL_IMAGE
|
||||
#include "plat_config.h"
|
||||
#include DEBUG_LOG_HEADER_FILE
|
||||
#endif
|
||||
#include "string.h"
|
||||
|
||||
#include "rndis_protocol.h"
|
||||
#include "usbmst_external.h"
|
||||
|
||||
#define INFBUF ((uint32_t *)((uint8_t *)&(m->RequestId) + m->InformationBufferOffset))
|
||||
#define CFGBUF ((rndis_config_parameter_t *) INFBUF)
|
||||
#define PARMNAME ((uint8_t *)CFGBUF + CFGBUF->ParameterNameOffset)
|
||||
#define PARMVALUE ((uint8_t *)CFGBUF + CFGBUF->ParameterValueOffset)
|
||||
#define PARMVALUELENGTH CFGBUF->ParameterValueLength
|
||||
#define PARM_NAME_LENGTH 25 /* Maximum parameter name length */
|
||||
|
||||
#define MAC_OPT NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \
|
||||
NDIS_MAC_OPTION_RECEIVE_SERIALIZED | \
|
||||
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | \
|
||||
NDIS_MAC_OPTION_NO_LOOPBACK
|
||||
|
||||
static const char *rndis_vendor = RNDIS_VENDOR;
|
||||
|
||||
|
||||
const uint32_t OIDSupportedList[] =
|
||||
{
|
||||
OID_GEN_SUPPORTED_LIST,
|
||||
OID_GEN_HARDWARE_STATUS,
|
||||
OID_GEN_MEDIA_SUPPORTED,
|
||||
OID_GEN_MEDIA_IN_USE,
|
||||
OID_GEN_MAXIMUM_FRAME_SIZE,
|
||||
OID_GEN_LINK_SPEED,
|
||||
OID_GEN_TRANSMIT_BLOCK_SIZE,
|
||||
OID_GEN_RECEIVE_BLOCK_SIZE,
|
||||
OID_GEN_VENDOR_ID,
|
||||
OID_GEN_VENDOR_DESCRIPTION,
|
||||
OID_GEN_VENDOR_DRIVER_VERSION,
|
||||
OID_GEN_CURRENT_PACKET_FILTER,
|
||||
OID_GEN_MAXIMUM_TOTAL_SIZE,
|
||||
OID_GEN_PROTOCOL_OPTIONS,
|
||||
OID_GEN_MAC_OPTIONS,
|
||||
OID_GEN_MEDIA_CONNECT_STATUS,
|
||||
OID_GEN_MAXIMUM_SEND_PACKETS,
|
||||
OID_802_3_PERMANENT_ADDRESS,
|
||||
OID_802_3_CURRENT_ADDRESS,
|
||||
OID_802_3_MULTICAST_LIST,
|
||||
OID_802_3_MAXIMUM_LIST_SIZE,
|
||||
OID_802_3_MAC_OPTIONS
|
||||
};
|
||||
|
||||
#define OID_LIST_LENGTH (sizeof(OIDSupportedList) / sizeof(*OIDSupportedList))
|
||||
#define ENC_BUF_SIZE (OID_LIST_LENGTH * 4 + 32)
|
||||
|
||||
static const uint8_t station_hwaddr[6] = { RNDIS_HWADDR };
|
||||
static const uint8_t permanent_hwaddr[6] = { RNDIS_HWADDR };
|
||||
extern uint32_t connect_status;
|
||||
|
||||
//used for malloc buffer
|
||||
uint32_t RndisGetEncBufSize(void)
|
||||
{
|
||||
return ENC_BUF_SIZE;
|
||||
}
|
||||
|
||||
void FuncRndisInitNotify(void)
|
||||
{
|
||||
#if (!defined(USB_DRV_SMALL_IMAGE))
|
||||
usbDevNotifyRndisEvent(NOTIFY_MSG_INIT, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FuncRndisHaltNotify(void)
|
||||
{
|
||||
#if (!defined(USB_DRV_SMALL_IMAGE))
|
||||
usbDevNotifyRndisEvent(NOTIFY_MSG_HALT, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FuncRndisResetNotify(void)
|
||||
{
|
||||
#if (!defined(USB_DRV_SMALL_IMAGE))
|
||||
usbDevNotifyRndisEvent(NOTIFY_MSG_RESET, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void RdsProInitalMsgHdl(rndis_generic_msg_t *msgIn)
|
||||
{
|
||||
rndis_initialize_cmplt_t *m;
|
||||
m = ((rndis_initialize_cmplt_t *)msgIn);
|
||||
/* m->MessageID is same as before */
|
||||
m->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
|
||||
m->MessageLength = sizeof(rndis_initialize_cmplt_t);
|
||||
m->MajorVersion = RNDIS_MAJOR_VERSION;
|
||||
m->MinorVersion = RNDIS_MINOR_VERSION;
|
||||
m->Status = RNDIS_STATUS_SUCCESS;
|
||||
m->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
|
||||
m->Medium = RNDIS_MEDIUM_802_3;
|
||||
m->MaxPacketsPerTransfer = RNDIS_MAX_PACK_PER_XFER;
|
||||
m->MaxTransferSize = RNDIS_RX_BUFFER_SIZE;
|
||||
m->PacketAlignmentFactor = 0;
|
||||
m->AfListOffset = 0;
|
||||
m->AfListSize = 0;
|
||||
}
|
||||
|
||||
void RdsProQueryCmplt(rndis_query_msg_t *m, int status, const void *data, int size)
|
||||
{
|
||||
rndis_query_cmplt_t *c = (rndis_query_cmplt_t *)m;
|
||||
|
||||
c->MessageType = REMOTE_NDIS_QUERY_CMPLT;
|
||||
c->MessageLength = sizeof(rndis_query_cmplt_t) + size;
|
||||
c->InformationBufferLength = size;
|
||||
c->InformationBufferOffset = 16;
|
||||
c->Status = status;
|
||||
memcpy(c + 1, data, size);
|
||||
}
|
||||
|
||||
void RdsProQueryCmplt32(rndis_query_msg_t *m, int status, uint32_t data)
|
||||
{
|
||||
rndis_query_cmplt_t *c = (rndis_query_cmplt_t *)m;
|
||||
|
||||
c->MessageType = REMOTE_NDIS_QUERY_CMPLT;
|
||||
c->MessageLength = sizeof(rndis_query_cmplt_t) + 4;
|
||||
c->InformationBufferLength = 4;
|
||||
c->InformationBufferOffset = 16;
|
||||
c->Status = status;
|
||||
*(uint32_t *)(c + 1) = data;
|
||||
}
|
||||
|
||||
void RdsProQueryHdl(rndis_query_msg_t *m, rndis_ctrl_data_st *p_ctrl_data)
|
||||
{
|
||||
switch (m->Oid)
|
||||
{
|
||||
case OID_GEN_SUPPORTED_LIST: RdsProQueryCmplt(m,RNDIS_STATUS_SUCCESS, OIDSupportedList, 4 * OID_LIST_LENGTH); return;
|
||||
case OID_GEN_VENDOR_DRIVER_VERSION: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, 0x00001000); return;
|
||||
case OID_802_3_CURRENT_ADDRESS: RdsProQueryCmplt(m,RNDIS_STATUS_SUCCESS, &station_hwaddr, 6); return;
|
||||
case OID_802_3_PERMANENT_ADDRESS: RdsProQueryCmplt(m,RNDIS_STATUS_SUCCESS, &permanent_hwaddr, 6); return;
|
||||
case OID_GEN_MEDIA_SUPPORTED: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return;
|
||||
case OID_GEN_MEDIA_IN_USE: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return;
|
||||
case OID_GEN_PHYSICAL_MEDIUM: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, NDIS_MEDIUM_802_3); return;
|
||||
case OID_GEN_HARDWARE_STATUS: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, 0); return;
|
||||
case OID_GEN_LINK_SPEED: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, RNDIS_LINK_SPEED / 100); return;
|
||||
case OID_GEN_VENDOR_ID: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, 0x00FFFFFF); return;
|
||||
case OID_GEN_VENDOR_DESCRIPTION: RdsProQueryCmplt(m,RNDIS_STATUS_SUCCESS, rndis_vendor, strlen(rndis_vendor) + 1); return;
|
||||
case OID_GEN_CURRENT_PACKET_FILTER: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, p_ctrl_data->oid_packet_filter); return;
|
||||
case OID_GEN_MAXIMUM_FRAME_SIZE: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, ETH_MAX_PACKET_SIZE - ETH_HEADER_SIZE); return;
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, ETH_MAX_PACKET_SIZE); return;
|
||||
case OID_GEN_TRANSMIT_BLOCK_SIZE: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, ETH_MAX_PACKET_SIZE); return;
|
||||
case OID_GEN_RECEIVE_BLOCK_SIZE: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, ETH_MAX_PACKET_SIZE); return;
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, connect_status); return;
|
||||
case OID_GEN_RNDIS_CONFIG_PARAMETER: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, 0); return;
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, 1); return;
|
||||
case OID_802_3_MULTICAST_LIST: RdsProQueryCmplt32(m,RNDIS_STATUS_NOT_SUPPORTED, 0); return;
|
||||
case OID_802_3_MAC_OPTIONS: RdsProQueryCmplt32(m,RNDIS_STATUS_NOT_SUPPORTED, 0); return;
|
||||
case OID_GEN_MAC_OPTIONS: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, 0); return;
|
||||
case OID_802_3_RCV_ERROR_ALIGNMENT: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, 0); return;
|
||||
case OID_802_3_XMIT_ONE_COLLISION: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, 0); return;
|
||||
case OID_802_3_XMIT_MORE_COLLISIONS: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, 0); return;
|
||||
case OID_GEN_XMIT_OK: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, p_ctrl_data->usb_eth_stat.txok); return;
|
||||
case OID_GEN_RCV_OK: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, p_ctrl_data->usb_eth_stat.rxok); return;
|
||||
case OID_GEN_RCV_ERROR: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, p_ctrl_data->usb_eth_stat.rxbad); return;
|
||||
case OID_GEN_XMIT_ERROR: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, p_ctrl_data->usb_eth_stat.txbad); return;
|
||||
case OID_GEN_RCV_NO_BUFFER: RdsProQueryCmplt32(m,RNDIS_STATUS_SUCCESS, 0); return;
|
||||
default: RdsProQueryCmplt(m,RNDIS_STATUS_FAILURE, NULL, 0); return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RdsProCfgParaHdl(const char *data, int keyoffset, int valoffset, int keylen, int vallen)
|
||||
{
|
||||
(void)data;
|
||||
(void)keyoffset;
|
||||
(void)valoffset;
|
||||
(void)keylen;
|
||||
(void)vallen;
|
||||
}
|
||||
|
||||
void RdsProPktFilter(uint32_t newfilter)
|
||||
{
|
||||
(void)newfilter;
|
||||
}
|
||||
|
||||
void RdsProSetMsgHdl(rndis_set_msg_t *msgIn, rndis_ctrl_data_st *p_ctrl_data)
|
||||
{
|
||||
rndis_set_cmplt_t *c;
|
||||
rndis_set_msg_t *m;
|
||||
rndis_Oid_t oid;
|
||||
|
||||
c = (rndis_set_cmplt_t *)msgIn;
|
||||
m = (rndis_set_msg_t *)msgIn;
|
||||
|
||||
oid = m->Oid;
|
||||
c->MessageType = REMOTE_NDIS_SET_CMPLT;
|
||||
c->MessageLength = sizeof(rndis_set_cmplt_t);
|
||||
c->Status = RNDIS_STATUS_SUCCESS;
|
||||
|
||||
switch (oid)
|
||||
{
|
||||
case OID_GEN_RNDIS_CONFIG_PARAMETER:
|
||||
{
|
||||
rndis_config_parameter_t *p;
|
||||
char *ptr = (char *)m;
|
||||
ptr += sizeof(rndis_generic_msg_t);
|
||||
ptr += m->InformationBufferOffset;
|
||||
p = (rndis_config_parameter_t *)ptr;
|
||||
RdsProCfgParaHdl(ptr, p->ParameterNameOffset, p->ParameterValueOffset, p->ParameterNameLength, p->ParameterValueLength);
|
||||
}
|
||||
break;
|
||||
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
p_ctrl_data->oid_packet_filter = *INFBUF;
|
||||
if (p_ctrl_data->oid_packet_filter)
|
||||
{
|
||||
RdsProPktFilter(p_ctrl_data->oid_packet_filter);
|
||||
p_ctrl_data->rndis_state = rndis_data_initialized;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_ctrl_data->rndis_state = rndis_initialized;
|
||||
}
|
||||
break;
|
||||
|
||||
case OID_GEN_CURRENT_LOOKAHEAD:
|
||||
break;
|
||||
|
||||
case OID_GEN_PROTOCOL_OPTIONS:
|
||||
break;
|
||||
|
||||
case OID_802_3_MULTICAST_LIST:
|
||||
break;
|
||||
case OID_PNP_ADD_WAKE_UP_PATTERN:
|
||||
case OID_PNP_REMOVE_WAKE_UP_PATTERN:
|
||||
case OID_PNP_ENABLE_WAKE_UP:
|
||||
default:
|
||||
c->Status = RNDIS_STATUS_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void RdsProResetMsgHdl(rndis_reset_cmplt_t *m, rndis_ctrl_data_st *p_ctrl_data)
|
||||
{
|
||||
p_ctrl_data->rndis_state = rndis_uninitialized;
|
||||
m->MessageType = REMOTE_NDIS_RESET_CMPLT;
|
||||
m->MessageLength = sizeof(rndis_reset_cmplt_t);
|
||||
m->Status = RNDIS_STATUS_SUCCESS;
|
||||
m->AddressingReset = 1;
|
||||
}
|
||||
|
||||
void RdsProKeepAliveMsgHdl(rndis_keepalive_cmplt_t *m, uint32_t RequestId, rndis_ctrl_data_st *p_ctrl_data)
|
||||
{
|
||||
(void)p_ctrl_data;
|
||||
m->RequestId = RequestId;
|
||||
|
||||
m->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
|
||||
m->MessageLength = sizeof(rndis_keepalive_cmplt_t);
|
||||
m->Status = RNDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,378 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "cmsis_os2.h"
|
||||
#include "usb_portmon.h"
|
||||
#include "apmu_external.h"
|
||||
#include "plat_config.h"
|
||||
#include "string.h"
|
||||
#include "bsp_custom.h"
|
||||
#include "slpman.h"
|
||||
#include "usb_ext_inc.h"
|
||||
|
||||
#include DEBUG_LOG_HEADER_FILE
|
||||
typedef int (*pfn_PadWakeupHook)(uint32_t pad_num);
|
||||
|
||||
|
||||
osEventFlagsId_t vBusEvtFlags = NULL;
|
||||
#define USB_VBUS_EVT_FLAG 1
|
||||
//5 for module AirM2M E3 BOARD vbus pad
|
||||
//#define USB_WKUP_PAD_IDX 5
|
||||
//for module AirM2M E1 BOARD vbus pad
|
||||
uint8_t usb_wkup_pad_idx = 1;
|
||||
#define VBUS_FILTER_MAX_SAMPLE_CNT 10
|
||||
|
||||
extern uint8_t usbstack_clear_ctx_stat(void);
|
||||
extern uint8_t usbstack_ctx_stat_ison(void);
|
||||
extern uint8_t usbstack_ctx_stat_isoff(void);
|
||||
extern uint8_t usbstack_get_ctx_stat(void);
|
||||
extern void usbstack_set_ctx_vbus_mode(uint8_t vbus_mode_en, uint8_t vbus_pad_idx);
|
||||
extern void usbstack_top_var_clear(void);
|
||||
|
||||
extern int RegPadWakeupIntrHook(pfn_PadWakeupHook pfunc);
|
||||
|
||||
|
||||
|
||||
|
||||
extern void BSP_UsbDeInit(void);
|
||||
extern void BSP_UsbInit(void);
|
||||
int usb_portmon_intr_cb(void);
|
||||
int Pad1WakeupHook(void);
|
||||
int PadCmnWakeupHook(uint32_t pad_num);
|
||||
|
||||
void usb_portmon_padcfg(void)
|
||||
{
|
||||
APmuWakeupPadSettings_t wakeupPadSetting;
|
||||
wakeupPadSetting.negEdgeEn = true;
|
||||
wakeupPadSetting.posEdgeEn = true;
|
||||
wakeupPadSetting.pullDownEn = false;
|
||||
wakeupPadSetting.pullUpEn = false;
|
||||
apmuSetWakeupPadCfg(usb_wkup_pad_idx, true, &wakeupPadSetting);
|
||||
}
|
||||
|
||||
uint8_t usb_portmon_wkuppad_level(uint32_t idx);
|
||||
|
||||
uint8_t usb_portmon_vbuspad_level(void)
|
||||
{
|
||||
return usb_portmon_wkuppad_level(usb_wkup_pad_idx);
|
||||
}
|
||||
|
||||
|
||||
#define USB_PORTMON_WAIT_INIT_START 10
|
||||
#define USB_PORTMON_WAIT_FILTER 10
|
||||
#define USB_PORTMON_WAIT_ALWAYS 0xffffffff
|
||||
|
||||
typedef enum
|
||||
{
|
||||
usb_portmon_state_none= 0,
|
||||
usb_portmon_state_filter_reset = 1,
|
||||
usb_portmon_state_filter_sample = 2,
|
||||
usb_portmon_state_trigger = 3,
|
||||
usb_portmon_state_stable = 4,
|
||||
}usb_portmon_state_type;
|
||||
|
||||
uint32_t usb_portmon_stat = usb_portmon_state_none;
|
||||
|
||||
usb_portmon_state_type usb_portmon_getstat(void)
|
||||
{
|
||||
return usb_portmon_stat;
|
||||
}
|
||||
|
||||
void usb_portmon_setstat(usb_portmon_state_type stat)
|
||||
{
|
||||
usb_portmon_stat = stat;
|
||||
}
|
||||
|
||||
uint8_t vbus_val_last = 0;
|
||||
|
||||
int usb_portmon_init(void)
|
||||
{
|
||||
uint32_t ret;
|
||||
usbstack_clear_ctx_stat();
|
||||
vBusEvtFlags = osEventFlagsNew(NULL);
|
||||
if (vBusEvtFlags== NULL)
|
||||
{
|
||||
EC_ASSERT((0), 0, 0, 0);
|
||||
}
|
||||
|
||||
usb_wkup_pad_idx = BSP_UsbGetVBUSWkupPad();
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_init_1, P_WARNING, 1,"usb_wkup_pad_idx %d", usb_wkup_pad_idx);
|
||||
|
||||
if (usb_wkup_pad_idx>WAKEUP_PAD_5)
|
||||
{
|
||||
EC_ASSERT(0, usb_wkup_pad_idx, WAKEUP_PAD_5, 0);
|
||||
}
|
||||
|
||||
usbstack_top_var_clear();
|
||||
usbstack_set_ctx_vbus_mode(1,usb_wkup_pad_idx);
|
||||
|
||||
NVIC_DisableIRQ(PadWakeup0_IRQn+usb_wkup_pad_idx);
|
||||
NVIC_ClearPendingIRQ(PadWakeup0_IRQn+usb_wkup_pad_idx);
|
||||
|
||||
ret = RegPadWakeupIntrHook(PadCmnWakeupHook);
|
||||
EC_ASSERT((ret==0), 0, 0, 0);
|
||||
|
||||
|
||||
usb_portmon_stat = usb_portmon_state_filter_reset;
|
||||
usb_portmon_padcfg();
|
||||
NVIC_EnableIRQ(PadWakeup0_IRQn+usb_wkup_pad_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_portmon_deinit(void){
|
||||
NVIC_DisableIRQ(PadWakeup0_IRQn+usb_wkup_pad_idx);
|
||||
if (vBusEvtFlags !=NULL){
|
||||
osEventFlagsDelete(vBusEvtFlags);
|
||||
vBusEvtFlags = NULL;
|
||||
}
|
||||
usb_portmon_stat = usb_portmon_state_none;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t usbpm_vote_handle = 0xff;
|
||||
|
||||
void usb_portmon_task(void *arg)
|
||||
{
|
||||
uint32_t vbus_evtflag;
|
||||
uint32_t vbus_filter_sample_cnt = 0;
|
||||
uint8_t vbus_val_cur = 0;
|
||||
slpManApplyPlatVoteHandle("usbpm", &usbpm_vote_handle);
|
||||
slpManPlatVoteDisableSleep(usbpm_vote_handle, SLP_SLP2_STATE);
|
||||
|
||||
usb_portmon_init();
|
||||
|
||||
uint32_t usb_portmon_wait = USB_PORTMON_WAIT_ALWAYS;
|
||||
while(1)
|
||||
{
|
||||
switch (usb_portmon_getstat())
|
||||
{
|
||||
case usb_portmon_state_none:
|
||||
usb_portmon_setstat(usb_portmon_state_filter_reset);
|
||||
break;
|
||||
case usb_portmon_state_filter_reset:
|
||||
|
||||
usb_portmon_wait = USB_PORTMON_WAIT_INIT_START;
|
||||
vbus_evtflag = 0;
|
||||
vbus_evtflag = osEventFlagsWait (vBusEvtFlags, USB_VBUS_EVT_FLAG, osFlagsWaitAny, usb_portmon_wait);
|
||||
vbus_val_last = usb_portmon_vbuspad_level();
|
||||
|
||||
//reset vbus fileter sample cnt
|
||||
vbus_filter_sample_cnt = 0;
|
||||
if (vbus_evtflag&USB_VBUS_EVT_FLAG)
|
||||
{
|
||||
//filtered type 3, likely
|
||||
//detect evt in stable state, delay USB_PORTMON_WAIT_FILTER in filter state, detect evt again continuously in USB_PORTMON_WAIT_FILTER
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_1_1, P_WARNING, 2,"filter reset detect evt %x, vbus %d", vbus_evtflag, usb_portmon_vbuspad_level() );
|
||||
}
|
||||
else if (vbus_evtflag == osErrorTimeout)
|
||||
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_1_2, P_WARNING, 2,"filter reset (to) evt %x, vbus %d", vbus_evtflag, usb_portmon_vbuspad_level() );
|
||||
}
|
||||
usb_portmon_setstat(usb_portmon_state_filter_sample);
|
||||
break;
|
||||
case usb_portmon_state_filter_sample:
|
||||
usb_portmon_wait = USB_PORTMON_WAIT_FILTER;
|
||||
vbus_evtflag = 0;
|
||||
vbus_evtflag = osEventFlagsWait (vBusEvtFlags, USB_VBUS_EVT_FLAG, osFlagsWaitAny, usb_portmon_wait);
|
||||
if (vbus_evtflag&USB_VBUS_EVT_FLAG)
|
||||
{
|
||||
//filtered type 3, likely
|
||||
//detect evt in stable state, delay USB_PORTMON_WAIT_FILTER in filter state, detect evt again continuously in USB_PORTMON_WAIT_FILTER
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_2_1, P_WARNING, 2,"port filtered unstable evt %x, vbus %d", vbus_evtflag, usb_portmon_vbuspad_level() );
|
||||
usb_portmon_setstat(usb_portmon_state_filter_reset);
|
||||
break;
|
||||
}
|
||||
|
||||
if (vbus_evtflag == osErrorTimeout)
|
||||
{
|
||||
vbus_val_cur = usb_portmon_vbuspad_level();
|
||||
|
||||
if (vbus_val_last!=vbus_val_cur)
|
||||
{
|
||||
//unlikely
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_2_2, P_WARNING, 2,"port vbus filter unstable level vbus last %d,vbus cur = %d", vbus_val_last, vbus_val_cur);
|
||||
usb_portmon_setstat(usb_portmon_state_filter_reset);
|
||||
|
||||
vbus_val_last = vbus_val_cur;
|
||||
break;
|
||||
}
|
||||
|
||||
//anyway update vbus_val_last
|
||||
vbus_val_last = vbus_val_cur;
|
||||
|
||||
//vbus_val_last==vbus_val_cur case
|
||||
//add vbus fileter sample cnt
|
||||
vbus_filter_sample_cnt++;
|
||||
if(vbus_filter_sample_cnt<VBUS_FILTER_MAX_SAMPLE_CNT)
|
||||
{
|
||||
//wait for more sample cnt
|
||||
break;
|
||||
}
|
||||
|
||||
if ((usbstack_ctx_stat_isoff()==1) && (vbus_val_cur ==0))
|
||||
{
|
||||
//filtered type 1, unlikely
|
||||
//detect evt in stable state, delay USB_PORTMON_WAIT_FILTER in filter state, but no pad val change
|
||||
//no trigger for vbus 0 and usb ctx stat is not on
|
||||
usb_portmon_setstat(usb_portmon_state_stable);
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_2_3, P_WARNING, 1,"port filtered type2(to) invalid vbus, evt %x, vbus 0 ", vbus_evtflag);
|
||||
}
|
||||
else if ((usbstack_ctx_stat_ison()==1) && (vbus_val_cur ==1))
|
||||
{
|
||||
//filtered type 2, unlikely
|
||||
//detect evt in stable state, delay USB_PORTMON_WAIT_FILTER in filter state, but no pad val change
|
||||
//no trigger for vbus 1 and usb ctx stat is on
|
||||
usb_portmon_setstat(usb_portmon_state_stable);
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_2_4, P_WARNING, 1,"port filtered type3(to) invalid vbus, evt %x ,vbus 1", vbus_evtflag);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if ((usbstack_ctx_stat_isoff()==0) &&(usbstack_ctx_stat_ison()==0))
|
||||
{
|
||||
//anyway pass to trigger state, then cause assert
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_2_5, P_WARNING, 2,"port vbus trigger warning, ctx stat not valid %x, vbus %d", usbstack_get_ctx_stat(), vbus_val_cur);
|
||||
}
|
||||
|
||||
//most likely
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_2_6, P_INFO, 2,"port vbus trigger, evt %x ,vbus %d", vbus_evtflag, vbus_val_cur);
|
||||
usb_portmon_setstat(usb_portmon_state_trigger);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case usb_portmon_state_trigger:
|
||||
//check the vbus if it is plug out
|
||||
|
||||
if (vbus_val_cur==0)
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_3_1, P_WARNING, 0,"BSP_UsbDeInit");
|
||||
BSP_UsbDeInit();
|
||||
if(usbstack_ctx_stat_isoff()==0)
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_3_2, P_ERROR, 0,"BSP_UsbDeInit, ctx stat not match");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//check the vbus if it is plug in
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_3_3, P_WARNING, 0,"BSP_UsbInit");
|
||||
|
||||
usblpw_clear_lpusbwkup_src();
|
||||
if (usblpw_retothwk_cur_stg_success()==0)
|
||||
{
|
||||
//all other not succ stag anyway set to terminate
|
||||
usblpw_retothwk_set_terminate_stage();
|
||||
}
|
||||
|
||||
BSP_UsbInit();
|
||||
if(usbstack_ctx_stat_ison()==0)
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_3_4, P_ERROR, 0,"BSP_UsbInit, ctx stat not match");
|
||||
}
|
||||
}
|
||||
vbus_val_last = usb_portmon_vbuspad_level();
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_3_5, P_WARNING, 2,"port vbus last %d,vbus cur = %d", vbus_val_last, vbus_val_cur);
|
||||
|
||||
usb_portmon_setstat(usb_portmon_state_stable);
|
||||
break;
|
||||
|
||||
case usb_portmon_state_stable:
|
||||
//vote enable sleep when stable state
|
||||
slpManPlatVoteEnableSleep(usbpm_vote_handle, SLP_SLP2_STATE);
|
||||
usb_portmon_wait = USB_PORTMON_WAIT_ALWAYS;
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_4_1, P_WARNING, 0,"port stable wait evt change");
|
||||
vbus_evtflag = 0;
|
||||
vbus_evtflag = osEventFlagsWait (vBusEvtFlags, USB_VBUS_EVT_FLAG, osFlagsWaitAny|osFlagsNoClear, usb_portmon_wait);
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_task_4_2, P_WARNING, 1,"port stable detect evt %x", vbus_evtflag);
|
||||
if (vbus_evtflag&USB_VBUS_EVT_FLAG)
|
||||
{
|
||||
usb_portmon_setstat(usb_portmon_state_filter_reset);
|
||||
}
|
||||
|
||||
//vote disable sleep when unstable state
|
||||
slpManPlatVoteDisableSleep(usbpm_vote_handle, SLP_SLP2_STATE);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int usb_portmon_intr_cb(void)
|
||||
{
|
||||
uint32_t wkup_val = usb_portmon_vbuspad_level();
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_portmon_intr_cb_1, P_INFO, 1,"wkup_val:0x%x", wkup_val);
|
||||
if (usb_portmon_getstat()>usb_portmon_state_none)
|
||||
{
|
||||
if (vBusEvtFlags)
|
||||
{
|
||||
osEventFlagsSet (vBusEvtFlags, USB_VBUS_EVT_FLAG);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Pad1WakeupHook(void)
|
||||
{
|
||||
return usb_portmon_intr_cb();
|
||||
}
|
||||
|
||||
int Pad5WakeupHook(void)
|
||||
{
|
||||
return usb_portmon_intr_cb();
|
||||
}
|
||||
|
||||
int PadCmnWakeupHook(uint32_t pad_num)
|
||||
{
|
||||
if (pad_num==usb_wkup_pad_idx)
|
||||
{
|
||||
switch (usb_wkup_pad_idx)
|
||||
{
|
||||
case 1:
|
||||
Pad1WakeupHook();
|
||||
break;
|
||||
case 5:
|
||||
Pad5WakeupHook();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (RTE_USB_EN == 1)
|
||||
#define USBPORTON_TASK_STACK_SIZE (1024)
|
||||
static uint8_t usb_portmon_task_stack[USBPORTON_TASK_STACK_SIZE];
|
||||
static StaticTask_t usb_portmon_task_tcb;
|
||||
|
||||
//share task stack_ptr
|
||||
uint8_t *usb_wkmon_portmon_share_stack_ptr(void)
|
||||
{
|
||||
return &(usb_portmon_task_stack[0]);
|
||||
}
|
||||
|
||||
uint32_t usb_wkmon_portmon_share_stack_size(void)
|
||||
{
|
||||
return USBPORTON_TASK_STACK_SIZE;
|
||||
}
|
||||
|
||||
|
||||
void usb_portmon_task_init(void)
|
||||
{
|
||||
osThreadAttr_t task_attr;
|
||||
uint8_t * stack_ptr = usb_wkmon_portmon_share_stack_ptr();
|
||||
uint32_t stack_size = usb_wkmon_portmon_share_stack_size();
|
||||
|
||||
memset(&task_attr,0,sizeof(task_attr));
|
||||
memset(stack_ptr, 0xA5,stack_size);
|
||||
task_attr.name = "usbpm";
|
||||
task_attr.stack_mem = stack_ptr;
|
||||
task_attr.stack_size = stack_size;
|
||||
task_attr.priority = osPriorityNormal;
|
||||
task_attr.cb_mem = &usb_portmon_task_tcb;//task control block
|
||||
task_attr.cb_size = sizeof(StaticTask_t);//size of task control block
|
||||
|
||||
osThreadNew(usb_portmon_task, NULL, &task_attr);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,596 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "cmsis_os2.h"
|
||||
#include "usb_wkmon.h"
|
||||
#include "apmu_external.h"
|
||||
#include "plat_config.h"
|
||||
#include "string.h"
|
||||
#include "bsp_custom.h"
|
||||
#include "slpman.h"
|
||||
#include DEBUG_LOG_HEADER_FILE
|
||||
#include "usb_ext_inc.h"
|
||||
#include "task.h"
|
||||
#include "usbd_errinfo.h"
|
||||
//#include "gpr.h"
|
||||
|
||||
#if (USB_WKMON_TASK_EXIST==1)
|
||||
typedef enum
|
||||
{
|
||||
usb_wkmon_state_uninit = 0,
|
||||
usb_wkmon_state_idle = 1,
|
||||
usb_wkmon_state_start,
|
||||
|
||||
usb_wkmon_state_detecting,
|
||||
usb_wkmon_state_actv,
|
||||
usb_wkmon_state_succ ,
|
||||
usb_wkmon_state_terminate,
|
||||
|
||||
}usb_wkmon_state_type;
|
||||
|
||||
uint32_t usb_wkmon_stat = usb_wkmon_state_uninit;
|
||||
|
||||
void usb_wkmon_setstat(usb_wkmon_state_type stat);
|
||||
|
||||
|
||||
osEventFlagsId_t LPUsbWkStatEvtFlags = NULL;
|
||||
osEventFlagsId_t LPUsbWkDetEvtFlags = NULL;
|
||||
|
||||
#define USB_RETWKUP_STAT_EVT_UPD_FLAG (1UL<0)
|
||||
#define USB_RETWKUP_STAT_EVT_START_FLAG (1UL<<1)
|
||||
#define USB_RETWKUP_STAT_EVT_RESET_FLAG (1UL<<2)
|
||||
|
||||
#define USB_RETWKUP_DEV_EVT_UPD_FLAG (1UL<0)
|
||||
#define USB_RETWKUP_DEV_EVT_TRIG_FLAG (1UL<<1)
|
||||
#define USB_RETWKUP_DEV_EVT_RESET_FLAG (1UL<<2)
|
||||
|
||||
typedef int (*pfn_LPUsbWkupHook)(void);
|
||||
extern int RegLPUSBWkupIntrHook(pfn_LPUsbWkupHook pfunc);
|
||||
|
||||
|
||||
int usb_wkmon_intr_cb(void);
|
||||
int USBMonLPWkupIRQHook(void);
|
||||
//#define TEST_LOW_USB_HCLK
|
||||
int usb_wkmon_pre_init(void)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
usb_wkmon_stat = usb_wkmon_state_uninit;
|
||||
|
||||
#ifdef TEST_LOW_USB_HCLK
|
||||
GPR_clockEnable(CLK_HF102M);
|
||||
GPR_setClockSrc(CLK_CC, CLK_CC_SEL_102M);
|
||||
#endif
|
||||
|
||||
LPUsbWkStatEvtFlags = osEventFlagsNew(NULL);
|
||||
if (LPUsbWkStatEvtFlags== NULL)
|
||||
{
|
||||
EC_ASSERT((0), 0, 0, 0);
|
||||
}
|
||||
|
||||
LPUsbWkDetEvtFlags = osEventFlagsNew(NULL);
|
||||
if (LPUsbWkDetEvtFlags== NULL)
|
||||
{
|
||||
EC_ASSERT((0), 0, 0, 0);
|
||||
}
|
||||
|
||||
if (NVIC_GetEnableIRQ(LpusbWakeup_IRQn))
|
||||
{
|
||||
//illegal LpusbWakeup_IRQn before start
|
||||
EC_ASSERT(0, usbd_get_mod_last_err(), usblpw_retothwk_get_cur_stg(), usblpw_get_retothwk_proc_stat());
|
||||
}
|
||||
|
||||
ret = RegLPUSBWkupIntrHook(USBMonLPWkupIRQHook);
|
||||
EC_ASSERT((ret==0), 0, 0, 0);
|
||||
usb_wkmon_setstat(usb_wkmon_state_idle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int usb_wkmon_cmmon_clear(void){
|
||||
usblpw_wkmon_ll_enter_ctx_clear();
|
||||
usblpw_wkmon_lpusbwkup_flag_clear();
|
||||
|
||||
#ifdef TEST_LOW_USB_HCLK
|
||||
GPR_clockEnable(CLK_HF102M);
|
||||
|
||||
GPR_setClockSrc(CLK_CC, CLK_CC_SEL_102M);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_wkmon_deinit(void){
|
||||
if (LPUsbWkStatEvtFlags !=NULL){
|
||||
osEventFlagsDelete(LPUsbWkStatEvtFlags);
|
||||
LPUsbWkStatEvtFlags = NULL;
|
||||
}
|
||||
if (LPUsbWkDetEvtFlags !=NULL){
|
||||
osEventFlagsDelete(LPUsbWkDetEvtFlags);
|
||||
LPUsbWkDetEvtFlags = NULL;
|
||||
}
|
||||
|
||||
|
||||
usb_wkmon_setstat(usb_wkmon_state_uninit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_wkmon_hibslp2_stat_evt_start(void)
|
||||
{
|
||||
uint32_t stat_evtflag;
|
||||
uint32_t det_evtflag;
|
||||
if (LPUsbWkDetEvtFlags)
|
||||
{
|
||||
det_evtflag = USB_RETWKUP_DEV_EVT_RESET_FLAG |USB_RETWKUP_DEV_EVT_TRIG_FLAG | USB_RETWKUP_DEV_EVT_UPD_FLAG;
|
||||
osEventFlagsClear(LPUsbWkDetEvtFlags, det_evtflag);
|
||||
|
||||
//any uncleared stat abort
|
||||
det_evtflag = USB_RETWKUP_DEV_EVT_UPD_FLAG;
|
||||
osEventFlagsSet (LPUsbWkDetEvtFlags, det_evtflag);
|
||||
}
|
||||
|
||||
if (LPUsbWkStatEvtFlags)
|
||||
{
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_RESET_FLAG | USB_RETWKUP_STAT_EVT_START_FLAG|USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
osEventFlagsClear (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_START_FLAG|USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
osEventFlagsSet (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_wkmon_slp1_stat_evt_start(void)
|
||||
{
|
||||
uint32_t stat_evtflag;
|
||||
uint32_t det_evtflag;
|
||||
uint32_t irqflag;
|
||||
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_slp1_stat_evt_start_1, P_WARNING, 3,"usb_wkmon_stat %d, det evt 0x%x, stat evt 0x%x", usb_wkmon_stat, LPUsbWkDetEvtFlags, LPUsbWkStatEvtFlags);
|
||||
irqflag = SaveAndSetIRQMask();
|
||||
|
||||
switch (usb_wkmon_stat)
|
||||
{
|
||||
case usb_wkmon_state_idle:
|
||||
if (LPUsbWkDetEvtFlags)
|
||||
{
|
||||
det_evtflag = USB_RETWKUP_DEV_EVT_RESET_FLAG |USB_RETWKUP_DEV_EVT_TRIG_FLAG | USB_RETWKUP_DEV_EVT_UPD_FLAG;
|
||||
osEventFlagsClear(LPUsbWkDetEvtFlags, det_evtflag);
|
||||
|
||||
//any uncleared stat abort
|
||||
det_evtflag = USB_RETWKUP_DEV_EVT_UPD_FLAG;
|
||||
osEventFlagsSet (LPUsbWkDetEvtFlags, det_evtflag);
|
||||
}
|
||||
|
||||
if (LPUsbWkStatEvtFlags)
|
||||
{
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_RESET_FLAG | USB_RETWKUP_STAT_EVT_START_FLAG|USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
osEventFlagsClear (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_START_FLAG|USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
osEventFlagsSet (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
}
|
||||
break;
|
||||
|
||||
case usb_wkmon_state_start:
|
||||
//unlikely here, this stat is sleep disabled
|
||||
case usb_wkmon_state_actv:
|
||||
//unlikely , this stat is sleep disabled, deal as all reset
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_slp1_stat_evt_start_2, P_WARNING, 0,"usb_wkmon_stat unlikely");
|
||||
|
||||
case usb_wkmon_state_detecting:
|
||||
|
||||
//abort detecting and reset to none
|
||||
if (LPUsbWkDetEvtFlags)
|
||||
{
|
||||
det_evtflag = USB_RETWKUP_DEV_EVT_RESET_FLAG |USB_RETWKUP_DEV_EVT_TRIG_FLAG | USB_RETWKUP_DEV_EVT_UPD_FLAG;
|
||||
osEventFlagsClear(LPUsbWkDetEvtFlags,det_evtflag);
|
||||
|
||||
//any uncleared stat abort
|
||||
det_evtflag = USB_RETWKUP_DEV_EVT_RESET_FLAG;
|
||||
osEventFlagsSet (LPUsbWkDetEvtFlags, det_evtflag);
|
||||
}
|
||||
|
||||
//start
|
||||
if (LPUsbWkStatEvtFlags)
|
||||
{
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_RESET_FLAG | USB_RETWKUP_STAT_EVT_START_FLAG|USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
osEventFlagsClear (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_START_FLAG|USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
osEventFlagsSet (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
}
|
||||
|
||||
break;
|
||||
case usb_wkmon_state_succ:
|
||||
//start
|
||||
if (LPUsbWkStatEvtFlags)
|
||||
{
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_RESET_FLAG | USB_RETWKUP_STAT_EVT_START_FLAG|USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
osEventFlagsClear (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_RESET_FLAG|USB_RETWKUP_STAT_EVT_START_FLAG|USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
osEventFlagsSet (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
EC_ASSERT(0, usbd_get_mod_last_err(), usblpw_retothwk_get_cur_stg(), usb_wkmon_stat);
|
||||
break;
|
||||
}
|
||||
RestoreIRQMask(irqflag);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int usb_wkmon_slp1_nothwk_evt_reset(void)
|
||||
{
|
||||
uint32_t stat_evtflag;
|
||||
uint32_t det_evtflag;
|
||||
uint32_t irqflag;
|
||||
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_slp1_nothwk_evt_reset_1, P_WARNING, 3,"usb_wkmon_stat %d, det evt 0x%x, stat evt 0x%x", usb_wkmon_stat, LPUsbWkDetEvtFlags, LPUsbWkStatEvtFlags);
|
||||
irqflag = SaveAndSetIRQMask();
|
||||
|
||||
switch (usb_wkmon_stat)
|
||||
{
|
||||
case usb_wkmon_state_uninit:
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_slp1_stat_evt_start_uninit, P_WARNING, 0," ");
|
||||
break;
|
||||
case usb_wkmon_state_idle:
|
||||
if (LPUsbWkDetEvtFlags)
|
||||
{
|
||||
det_evtflag = USB_RETWKUP_DEV_EVT_RESET_FLAG |USB_RETWKUP_DEV_EVT_TRIG_FLAG | USB_RETWKUP_DEV_EVT_UPD_FLAG;
|
||||
osEventFlagsClear(LPUsbWkDetEvtFlags, det_evtflag);
|
||||
}
|
||||
|
||||
if (LPUsbWkStatEvtFlags)
|
||||
{
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_RESET_FLAG | USB_RETWKUP_STAT_EVT_START_FLAG|USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
osEventFlagsClear (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
}
|
||||
break;
|
||||
|
||||
case usb_wkmon_state_start:
|
||||
//unlikely here, this stat is sleep disabled
|
||||
case usb_wkmon_state_actv:
|
||||
//unlikely , this stat is sleep disabled, deal as all reset
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_slp1_stat_evt_start_2, P_WARNING, 0,"usb_wkmon_stat unlikely");
|
||||
|
||||
case usb_wkmon_state_detecting:
|
||||
|
||||
//abort detecting and reset to none
|
||||
if (LPUsbWkDetEvtFlags)
|
||||
{
|
||||
det_evtflag = USB_RETWKUP_DEV_EVT_RESET_FLAG |USB_RETWKUP_DEV_EVT_TRIG_FLAG | USB_RETWKUP_DEV_EVT_UPD_FLAG;
|
||||
osEventFlagsClear(LPUsbWkDetEvtFlags,det_evtflag);
|
||||
|
||||
//any uncleared stat abort
|
||||
det_evtflag = USB_RETWKUP_DEV_EVT_RESET_FLAG;
|
||||
osEventFlagsSet (LPUsbWkDetEvtFlags, det_evtflag);
|
||||
}
|
||||
|
||||
//start
|
||||
if (LPUsbWkStatEvtFlags)
|
||||
{
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_RESET_FLAG | USB_RETWKUP_STAT_EVT_START_FLAG|USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
osEventFlagsClear (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_RESET_FLAG;
|
||||
osEventFlagsSet (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
}
|
||||
|
||||
break;
|
||||
case usb_wkmon_state_succ:
|
||||
//start
|
||||
if (LPUsbWkStatEvtFlags)
|
||||
{
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_RESET_FLAG | USB_RETWKUP_STAT_EVT_START_FLAG|USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
osEventFlagsClear (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_RESET_FLAG;
|
||||
osEventFlagsSet (LPUsbWkStatEvtFlags, stat_evtflag);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
EC_ASSERT(0, usbd_get_mod_last_err(), usblpw_retothwk_get_cur_stg(), usb_wkmon_stat);
|
||||
break;
|
||||
}
|
||||
RestoreIRQMask(irqflag);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
usb_wkmon_state_type usb_wkmon_getstat(void)
|
||||
{
|
||||
return usb_wkmon_stat;
|
||||
}
|
||||
|
||||
void usb_wkmon_setstat(usb_wkmon_state_type stat)
|
||||
{
|
||||
usb_wkmon_stat = stat;
|
||||
}
|
||||
|
||||
void BSP_UsbWkIRQLog(void);
|
||||
//uint8_t BSP_UsbRetOthWkLaterRestOnly(void);
|
||||
|
||||
|
||||
uint8_t usbwkm_vote_handle = 0xff;
|
||||
|
||||
//5ms
|
||||
//#define USBWKM_DET_WAIT_TIME 5
|
||||
uint8_t usblpw_rd_reg_retwkup_ctxstat(void);
|
||||
|
||||
void usb_wkmon_task(void *arg)
|
||||
{
|
||||
uint32_t stat_evtflag;
|
||||
uint32_t det_evtflag;
|
||||
|
||||
uint32_t stat_evt_retval;
|
||||
uint32_t det_evt_retval;
|
||||
|
||||
uint32_t irqflag;
|
||||
|
||||
uint8_t ret;
|
||||
uint8_t stage;
|
||||
usb_wkmon_setstat(usb_wkmon_state_idle);
|
||||
|
||||
slpManApplyPlatVoteHandle("usbwk", &usbwkm_vote_handle);
|
||||
//slpManPlatVoteDisableSleep(usbwkm_vote_handle, SLP_SLP1_STATE);
|
||||
while(1)
|
||||
{
|
||||
switch (usb_wkmon_getstat())
|
||||
{
|
||||
case usb_wkmon_state_idle:
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_START_FLAG | USB_RETWKUP_STAT_EVT_UPD_FLAG;
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_state_none_0, P_INFO, 0,"start");
|
||||
stat_evt_retval = osEventFlagsWait (LPUsbWkStatEvtFlags, stat_evtflag, osFlagsWaitAny, portMAX_DELAY);
|
||||
stage = usblpw_retothwk_get_cur_stg();
|
||||
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_state_none_1, P_INFO, 2,"stage 0x%x, stat_evt_retval:0x%x", stage, stat_evt_retval);
|
||||
|
||||
if (stat_evt_retval&USB_RETWKUP_STAT_EVT_START_FLAG)
|
||||
{
|
||||
if ((usblpw_retothwk_cur_stg_hibslp2_wkmon()==0) &&(usblpw_retothwk_cur_stg_slp1_wkmon()==0))
|
||||
{
|
||||
//only enabled from wkmon is legal
|
||||
//ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_state_none_2, P_WARNING, 1,"wkmon stage %d not match", stage);
|
||||
EC_ASSERT(0, usbd_get_mod_last_err(), usblpw_retothwk_get_cur_stg(), usblpw_get_retothwk_proc_stat());
|
||||
break;
|
||||
//continue;
|
||||
}
|
||||
|
||||
slpManPlatVoteDisableSleep(usbwkm_vote_handle, SLP_SLP1_STATE);
|
||||
usb_wkmon_setstat(usb_wkmon_state_start);
|
||||
break;
|
||||
}
|
||||
else if (stat_evt_retval&0x80000000)
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_state_none_3, P_WARNING, 1,"stat_evt_retval err 0x%x", stat_evt_retval);
|
||||
}
|
||||
else
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_state_none_4, P_WARNING, 1,"stat_evt_retval no proc 0x%x", stat_evt_retval);
|
||||
}
|
||||
break;
|
||||
case usb_wkmon_state_start:
|
||||
if (NVIC_GetEnableIRQ(LpusbWakeup_IRQn))
|
||||
{
|
||||
//illegal LpusbWakeup_IRQn before start
|
||||
EC_ASSERT(0, usbd_get_mod_last_err(), usblpw_retothwk_get_cur_stg(), usblpw_get_retothwk_proc_stat());
|
||||
break;
|
||||
}
|
||||
|
||||
irqflag = SaveAndSetIRQMask();
|
||||
//enable here after the wkup irq hook, otherwise the irq may not clear in irq hook
|
||||
usblpw_enable_lpusbwkup_src();
|
||||
usblpw_wkmon_lpusbwkup_flag_set();
|
||||
usb_wkmon_setstat(usb_wkmon_state_detecting);
|
||||
slpManPlatVoteEnableSleep(usbwkm_vote_handle, SLP_SLP1_STATE);
|
||||
//because no usb drv is active here, so enable
|
||||
slpManDrvVoteSleep(SLP_VOTE_LPUSB, SLP_SLP1_STATE);
|
||||
RestoreIRQMask(irqflag);
|
||||
break;
|
||||
|
||||
case usb_wkmon_state_detecting:
|
||||
det_evt_retval = 0;
|
||||
det_evtflag = USB_RETWKUP_DEV_EVT_RESET_FLAG | USB_RETWKUP_DEV_EVT_TRIG_FLAG | USB_RETWKUP_DEV_EVT_UPD_FLAG;
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_1_0_0, P_INFO, 0,"usb_wkmon_state_detecting start");
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_1_0_1, P_INFO, 1,"ctx stat reg %d", usblpw_rd_reg_retwkup_ctxstat());
|
||||
|
||||
//may sleep here, current is enable sleep default
|
||||
det_evt_retval = osEventFlagsWait (LPUsbWkDetEvtFlags, det_evtflag, osFlagsWaitAny, portMAX_DELAY);
|
||||
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_1_1, P_INFO, 1,"det_evt_retval:0x%x", det_evt_retval);
|
||||
if (det_evt_retval&USB_RETWKUP_DEV_EVT_TRIG_FLAG)
|
||||
{
|
||||
//tirg stat, sleep is disabled by irq hook
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_1_2, P_WARNING, 0,"detect evt succ");
|
||||
ret = usblpw_retothwk_wkmon_idle_to_actv_proc();
|
||||
if (ret !=0)
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_1_3_1, P_WARNING, 0,"usblpw_retothwk_wkmon_idle_to_actv_proc fail");
|
||||
usb_wkmon_setstat(usb_wkmon_state_terminate);
|
||||
EC_ASSERT(0, usbd_get_mod_last_err(), usblpw_retothwk_get_cur_stg(), usblpw_get_retothwk_proc_stat());
|
||||
//assert here
|
||||
break;
|
||||
}
|
||||
if (usblpw_retothwk_cur_proc_stat_gpwr_umatch())
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_1_3_2, P_WARNING, 0,"usblpw_retothwk_wkmon_idle_to_actv_proc more detecting");
|
||||
|
||||
irqflag = SaveAndSetIRQMask();
|
||||
//enable here after the wkup irq hook, otherwise the irq may not clear in irq hook
|
||||
usblpw_enable_lpusbwkup_src();
|
||||
usblpw_wkmon_lpusbwkup_flag_set();
|
||||
usb_wkmon_setstat(usb_wkmon_state_detecting);
|
||||
slpManPlatVoteEnableSleep(usbwkm_vote_handle, SLP_SLP1_STATE);
|
||||
//because no usb drv is active here, so enable
|
||||
slpManDrvVoteSleep(SLP_VOTE_LPUSB, SLP_SLP1_STATE);
|
||||
RestoreIRQMask(irqflag);
|
||||
break;
|
||||
}
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_1_4, P_WARNING, 0,"usblpw_retothwk_wkmon_idle_to_actv_proc succ");
|
||||
|
||||
usb_wkmon_setstat(usb_wkmon_state_actv);
|
||||
}
|
||||
else if (det_evt_retval&USB_RETWKUP_DEV_EVT_RESET_FLAG)
|
||||
{
|
||||
//must be triggered by sleep1
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_1_5, P_WARNING, 0,"detecting reset event ");
|
||||
|
||||
//unlikely just wait for next trigger, restart
|
||||
usb_wkmon_setstat(usb_wkmon_state_idle);
|
||||
}
|
||||
else if (det_evt_retval == osErrorTimeout)
|
||||
|
||||
{
|
||||
//slpManPlatVoteEnableSleep(usbwkm_vote_handle, SLP_SLP1_STATE);
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_1_6, P_WARNING, 0,"detect (to) ");
|
||||
usb_wkmon_setstat(usb_wkmon_state_detecting);
|
||||
}
|
||||
else
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_1_7, P_WARNING, 0,"unknown event ");
|
||||
|
||||
//unlikely just wait for next trigger, restart
|
||||
slpManPlatVoteEnableSleep(usbwkm_vote_handle, SLP_SLP1_STATE);
|
||||
usb_wkmon_setstat(usb_wkmon_state_start);
|
||||
}
|
||||
break;
|
||||
|
||||
case usb_wkmon_state_actv:
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_2_0, P_WARNING, 0,"usblpw_retothwk_wkmon_actv_proc start");
|
||||
|
||||
ret = usblpw_retothwk_wkmon_actv_proc();
|
||||
if (ret != 0)
|
||||
{
|
||||
//terminate laterdet or assert
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_2_1, P_WARNING, 0,"usblpw_retothwk_wkmon_actv_proc fail");
|
||||
usb_wkmon_setstat(usb_wkmon_state_terminate);
|
||||
EC_ASSERT(0, usbd_get_mod_last_err(), usblpw_retothwk_get_cur_stg(), usblpw_get_retothwk_proc_stat());
|
||||
break;
|
||||
}
|
||||
|
||||
if (usblpw_retothwk_cur_stg_success()==0)
|
||||
{
|
||||
usb_wkmon_setstat(usb_wkmon_state_terminate);
|
||||
EC_ASSERT(0, usbd_get_mod_last_err(), usblpw_retothwk_get_cur_stg(), usblpw_get_retothwk_proc_stat());
|
||||
}
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_2_2, P_WARNING, 0,"usblpw_retothwk_wkmon_actv_proc succ");
|
||||
|
||||
usblpw_wkmon_lpusbwkup_flag_clear();
|
||||
usb_wkmon_setstat(usb_wkmon_state_succ);// try next loopo
|
||||
|
||||
break;
|
||||
case usb_wkmon_state_succ:
|
||||
stat_evtflag = USB_RETWKUP_STAT_EVT_RESET_FLAG;
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_state_succ_0, P_INFO, 0,"start");
|
||||
|
||||
slpManPlatVoteEnableSleep(usbwkm_vote_handle, SLP_SLP1_STATE);
|
||||
stat_evt_retval = osEventFlagsWait (LPUsbWkStatEvtFlags, stat_evtflag, osFlagsWaitAny, portMAX_DELAY);
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_state_succ_1, P_INFO, 1,"stat_evt_retval:0x%x", stat_evt_retval);
|
||||
if (stat_evt_retval&USB_RETWKUP_STAT_EVT_RESET_FLAG)
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_state_succ_2, P_WARNING, 0,"stat_evt_retval reset");
|
||||
usb_wkmon_setstat(usb_wkmon_state_idle);
|
||||
break;
|
||||
}
|
||||
else if (stat_evt_retval&0x80000000)
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_state_succ_3, P_WARNING, 0,"stat_evt_retval err ");
|
||||
}
|
||||
else
|
||||
{
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usb_wkmon_task_state_succ_4, P_WARNING, 0, "stat_evt_retval default proc as reset");
|
||||
usb_wkmon_setstat(usb_wkmon_state_idle);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
EC_ASSERT(0, usbd_get_mod_last_err(), usblpw_retothwk_get_cur_stg(), usb_wkmon_getstat());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BSP_LPUsbWkIRQLog(void)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, BSP_LPUsbWkIRQLog_1, P_VALUE, "othwkup stage %d, proc_stat %d", usblpw_get_retothwk_stage(), usblpw_get_retothwk_proc_stat());
|
||||
}
|
||||
|
||||
|
||||
int usb_wkmon_intr_cb(void)
|
||||
{
|
||||
if ((usblpw_retothwk_cur_stg_hibslp2_wkmon()) || (usblpw_retothwk_cur_stg_slp1_wkmon()))
|
||||
{
|
||||
if (usb_wkmon_getstat()==usb_wkmon_state_detecting)
|
||||
{
|
||||
//the legal wkmon stat is usb_wkmon_state_detecting for dev event
|
||||
osEventFlagsSet (LPUsbWkDetEvtFlags, USB_RETWKUP_DEV_EVT_TRIG_FLAG|USB_RETWKUP_DEV_EVT_UPD_FLAG);
|
||||
NVIC_DisableIRQ(LpusbWakeup_IRQn);
|
||||
slpManPlatVoteDisableSleep(usbwkm_vote_handle, SLP_SLP1_STATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, usb_wkmon_intr_cb_1_0, P_VALUE, "usb_wkmon_stat %d not match, no event sent", usb_wkmon_getstat());
|
||||
}
|
||||
|
||||
if (usblpw_wkmon_ll_enter_ctx_get())
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, usb_wkmon_intr_cb_1_1, P_VALUE, "chk_abort_ll_inirq, wkmon_lpusbwkup_flag %x", usblpw_wkmon_lpusbwkup_flag_get());
|
||||
|
||||
usblpw_enter_wkmon_chk_abort_ll_inirq();
|
||||
}
|
||||
}
|
||||
else if (usblpw_retothwk_cur_stg_none()==0)
|
||||
{
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, usb_wkmon_intr_cb_2, P_VALUE, "unlegal stag");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int USBMonLPWkupIRQHook(void)
|
||||
{
|
||||
BSP_LPUsbWkIRQLog();
|
||||
return usb_wkmon_intr_cb();
|
||||
}
|
||||
|
||||
#define USBWKM_TASK_STACK_SIZE (1024)
|
||||
//#define USB_WKMON_PRIVATE_STACK
|
||||
#ifdef USB_WKMON_PRIVATE_STACK
|
||||
static uint8_t usb_wkmon_task_stack[USBWKM_TASK_STACK_SIZE];
|
||||
static StaticTask_t usb_wkmon_task_tcb;
|
||||
|
||||
uint8_t *usb_wkmon_get_stack_ptr(void)
|
||||
{
|
||||
return &(usb_wkmon_task_stack[0]);
|
||||
}
|
||||
|
||||
uint32_t usb_wkmon_get_stack_size(void)
|
||||
{
|
||||
return USBWKM_TASK_STACK_SIZE;
|
||||
}
|
||||
#else
|
||||
static StaticTask_t usb_wkmon_task_tcb;
|
||||
|
||||
extern uint8_t *usb_wkmon_portmon_share_stack_ptr(void);
|
||||
extern uint32_t usb_wkmon_portmon_share_stack_size(void);
|
||||
|
||||
#endif
|
||||
void usb_wkmon_task_init(void)
|
||||
{
|
||||
osThreadAttr_t task_attr;
|
||||
uint8_t * stack_ptr = usb_wkmon_portmon_share_stack_ptr();
|
||||
uint32_t stack_size = usb_wkmon_portmon_share_stack_size();
|
||||
memset(&task_attr,0,sizeof(task_attr));
|
||||
memset(stack_ptr, 0xA5,stack_size);
|
||||
task_attr.name = "usbwkm";
|
||||
task_attr.stack_mem = stack_ptr;
|
||||
task_attr.stack_size = stack_size;
|
||||
task_attr.priority = osPriorityNormal;
|
||||
task_attr.cb_mem = &usb_wkmon_task_tcb;//task control block
|
||||
task_attr.cb_size = sizeof(StaticTask_t);//size of task control block
|
||||
|
||||
osThreadNew(usb_wkmon_task, NULL, &task_attr);
|
||||
}
|
||||
@@ -0,0 +1,993 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "cmsis_os2.h"
|
||||
#include "plat_config.h"
|
||||
#include "string.h"
|
||||
#include "usbd_clscdc.h"
|
||||
#include "usbd_func_cc.h"
|
||||
#include "usbd_multi_usrcfg_common.h"
|
||||
|
||||
#ifndef USB_DRV_SMALL_IMAGE
|
||||
#include "plat_config.h"
|
||||
|
||||
#include DEBUG_LOG_HEADER_FILE
|
||||
#endif
|
||||
#include "RTE_Device.h"
|
||||
|
||||
#define USBD_MULTIDEV_LOAD_FAIL 1
|
||||
|
||||
#define EP_REMAP_CUSTOM_CNT 13
|
||||
|
||||
#define CUST_DEF_TEST_TYPE1
|
||||
//#define CUST_DEF_TEST_TYPE3
|
||||
|
||||
//#define USBD_EMC_MAC_CONFIG
|
||||
#ifdef USBD_EMC_MAC_CONFIG
|
||||
|
||||
extern uint8_t *ecm_dev_local_string[1];
|
||||
void update_ecm_mac(void)
|
||||
{
|
||||
#ifndef USB_DRV_SMALL_IMAGE
|
||||
ecm_dev_local_string[0] = (uint8_t*)"2089846a96ab";//update the ecm mac here
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (VCOM_CCINST_SUBTP0_INHERENT_CNT>0)
|
||||
extern usb_func_ccinst_st t_vcom_func_custp0_inhrnt_arr[VCOM_CCINST_SUBTP0_INHERENT_CNT];
|
||||
#endif
|
||||
|
||||
extern usb_func_ccinst_st t_vcom_func_custp1_arr[VCOM_CCINST_SUBTP1_2EP_CNT];
|
||||
extern usb_func_ccinst_st t_vcom_func_custp2_arr[VCOM_CCINST_SUBTP2_3EP_CNT];
|
||||
|
||||
typedef struct {
|
||||
uint8_t vcom_ccinst_subtp0_inhrnt_cnt;
|
||||
uint8_t vcom_ccinst_subtp1_2ep_cnt;
|
||||
uint8_t vcom_ccinst_subtp2_3ep_cnt;
|
||||
usb_func_ccinst_st *p_vcom_ccinst_subtp0_entry;
|
||||
usb_func_ccinst_st *p_vcom_ccinst_subtp1_entry;
|
||||
usb_func_ccinst_st *p_vcom_ccinst_subtp2_entry;
|
||||
|
||||
}usbd_multidev_ccinst_res_st;
|
||||
|
||||
usbd_multidev_ccinst_res_st t_usbd_multidev_ccinst_res =
|
||||
{
|
||||
.vcom_ccinst_subtp0_inhrnt_cnt = VCOM_CCINST_SUBTP0_INHERENT_CNT,
|
||||
.vcom_ccinst_subtp1_2ep_cnt = VCOM_CCINST_SUBTP1_2EP_CNT,
|
||||
.vcom_ccinst_subtp2_3ep_cnt = VCOM_CCINST_SUBTP2_3EP_CNT,
|
||||
#if (VCOM_CCINST_SUBTP0_INHERENT_CNT>0)
|
||||
.p_vcom_ccinst_subtp0_entry = &(t_vcom_func_custp0_inhrnt_arr[0]),
|
||||
#endif
|
||||
#if (VCOM_CCINST_SUBTP1_2EP_CNT >0)
|
||||
.p_vcom_ccinst_subtp1_entry = &(t_vcom_func_custp1_arr[0]),
|
||||
#endif
|
||||
#if (VCOM_CCINST_SUBTP2_3EP_CNT >0)
|
||||
.p_vcom_ccinst_subtp2_entry = &(t_vcom_func_custp2_arr[0]),
|
||||
#endif
|
||||
};
|
||||
//#define CUST_DEF_TEST_TYPE2//change at/log order--ok
|
||||
//#define CUST_DEF_TEST_TYPE3//add a vcom---ok
|
||||
//#define CUST_DEF_TEST_TYPE4//remove a vcom---ok also need to modify dev create/destory
|
||||
//#define CUST_DEF_TEST_TYPE5//remove rndis--ok also need to modify dev create/destory
|
||||
//#define CUST_DEF_TEST_TYPE6//change ep--ok
|
||||
|
||||
|
||||
/*
|
||||
org: if0/1/2/3/4
|
||||
iep =2/4/6/8/10
|
||||
oep=1/2/3/4/5
|
||||
intep=1/2/3/4/5-also in-type
|
||||
|
||||
usr cfg:
|
||||
usb driver still use org epidx, map 2 usr defined ep in below table
|
||||
should make sure no same ep num in below table
|
||||
|
||||
e.g-1. if0 use iep=2 oep=1,intep=1, but user define iep=10, oep=5,intep still 1
|
||||
epin_remap_custom_tbl[2] =10
|
||||
epout_remap_custom_tbl[1]=5
|
||||
epin_remap_custom_tbl[10]=2 //not used but change to another val
|
||||
epout_remap_custom_tbl[5]=1//not used but change to another val
|
||||
|
||||
e.g-2. if0 use iep=2 oep=1,intep=1, if2 use iep=6 oep=3,intep=5. usr want switch if0/2 ep
|
||||
epin_remap_custom_tbl[2] =6
|
||||
epout_remap_custom_tbl[1]=3
|
||||
epin_remap_custom_tbl[6]=2
|
||||
epout_remap_custom_tbl[3]=1
|
||||
|
||||
|
||||
NOTE:
|
||||
1 currently, if enbale rndis, rndis should be at the first interface,
|
||||
if not,rndis enum will have some issue, mostly win host issue, need further debug
|
||||
|
||||
2 after add or remove some if, e.g. remmove PPP vcom or add a raw VCOM, user should also modify
|
||||
ccio dev create logic: not create corresponding dev if removed and create new dev if added.
|
||||
if still not clear ask EC for help
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef CUST_DEF_TEST_TYPE1
|
||||
|
||||
const uint8_t epin_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 1,2,3,4,5,6,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
|
||||
const uint8_t epout_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 1,2,3,4,5,6,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
#if ((defined LOW_SPEED_SERVICE_ONLY) || (defined LITE_FEATURE_MODE))
|
||||
|
||||
|
||||
#if (VCOM_CCINST_CASE_SEL==VCOM_CCINST_ORG_CASE)
|
||||
|
||||
static multidev_custom_info_st t_multidev_custom_info = {
|
||||
#ifdef __USER_CODE__
|
||||
.elem_cnt = 4,
|
||||
.elem_arr[0] =
|
||||
{
|
||||
(const uint8_t*)"vcom3",
|
||||
multidev_tp_vcom_com,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[1] =
|
||||
{
|
||||
(const uint8_t*)"vcom0",
|
||||
multidev_tp_vcom_at,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[2] =
|
||||
{
|
||||
(const uint8_t*)"vcom1",
|
||||
multidev_tp_vcom_log,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
|
||||
.elem_arr[3] =
|
||||
{
|
||||
(const uint8_t*)"vcom2",
|
||||
multidev_tp_vcom_ppp,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
#else
|
||||
.elem_cnt = 2,
|
||||
.elem_arr[0] =
|
||||
{
|
||||
(const uint8_t*)"vcom0",
|
||||
multidev_tp_vcom_at,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[1] =
|
||||
{
|
||||
(const uint8_t*)"vcom1",
|
||||
multidev_tp_vcom_log,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
#else
|
||||
|
||||
static multidev_custom_info_st t_multidev_custom_info = {
|
||||
.elem_cnt = 2,
|
||||
.elem_arr[0] =
|
||||
{
|
||||
(const uint8_t*)"vcom0",
|
||||
multidev_tp_vcom_at,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp2_3ep,
|
||||
},
|
||||
.elem_arr[1] =
|
||||
{
|
||||
(const uint8_t*)"vcom1",
|
||||
multidev_tp_vcom_log,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp1_2ep,
|
||||
},
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#else
|
||||
#if (VCOM_CCINST_CASE_SEL==VCOM_CCINST_ORG_CASE)
|
||||
static multidev_custom_info_st t_multidev_custom_info = {
|
||||
.elem_cnt = 5,
|
||||
.elem_arr[0] =
|
||||
{
|
||||
(const uint8_t*)"rndis",
|
||||
multidev_tp_rndis,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
.elem_arr[1] =
|
||||
{
|
||||
(const uint8_t*)"ecm",
|
||||
multidev_tp_ecm,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
|
||||
.elem_arr[2] =
|
||||
{
|
||||
(const uint8_t*)"vcom0",
|
||||
multidev_tp_vcom_at,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[3] =
|
||||
{
|
||||
(const uint8_t*)"vcom1",
|
||||
multidev_tp_vcom_log,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
|
||||
.elem_arr[4] =
|
||||
{
|
||||
(const uint8_t*)"vcom2",
|
||||
multidev_tp_vcom_ppp,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
#if (VCOM_CCINST_CASE_SEL==VCOM_CCINST_CUST_CASE)
|
||||
|
||||
static multidev_custom_info_st t_multidev_custom_info = {
|
||||
.elem_cnt = 5,
|
||||
.elem_arr[0] =
|
||||
{
|
||||
(const uint8_t*)"rndis",
|
||||
multidev_tp_rndis,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
.elem_arr[1] =
|
||||
{
|
||||
(const uint8_t*)"ecm",
|
||||
multidev_tp_ecm,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
|
||||
.elem_arr[2] =
|
||||
{
|
||||
(const uint8_t*)"vcom0",
|
||||
multidev_tp_vcom_at,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp2_3ep,
|
||||
},
|
||||
.elem_arr[3] =
|
||||
{
|
||||
(const uint8_t*)"vcom1",
|
||||
multidev_tp_vcom_log,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp1_2ep,
|
||||
},
|
||||
|
||||
.elem_arr[4] =
|
||||
{
|
||||
(const uint8_t*)"vcom2",
|
||||
multidev_tp_vcom_ppp,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp2_3ep,
|
||||
},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CUST_DEF_TEST_TYPE2
|
||||
const uint8_t epin_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 1,2,3,4,5,6,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
|
||||
const uint8_t epout_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 1,2,3,4,5,6,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
static multidev_custom_info_st t_multidev_custom_info = {
|
||||
.elem_cnt = 5,
|
||||
.elem_arr[0] =
|
||||
{
|
||||
(const uint8_t*)"rndis",
|
||||
multidev_tp_rndis,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
.elem_arr[1] =
|
||||
{
|
||||
(const uint8_t*)"ecm",
|
||||
multidev_tp_ecm,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
.elem_arr[2] =
|
||||
{
|
||||
(const uint8_t*)"vcom0",
|
||||
multidev_tp_vcom_log,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[3] =
|
||||
{
|
||||
(const uint8_t*)"vcom1",
|
||||
multidev_tp_vcom_at,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[4] =
|
||||
{
|
||||
(const uint8_t*)"vcom2",
|
||||
multidev_tp_vcom_ppp,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CUST_DEF_TEST_TYPE3
|
||||
const uint8_t epin_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 1,2,3,4,5,6,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
|
||||
const uint8_t epout_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 1,2,3,4,5,6,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
static multidev_custom_info_st t_multidev_custom_info = {
|
||||
.elem_cnt = 6,
|
||||
.elem_arr[0] =
|
||||
{
|
||||
(const uint8_t*)"rndis",
|
||||
multidev_tp_rndis,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
.elem_arr[1] =
|
||||
{
|
||||
(const uint8_t*)"ecm",
|
||||
multidev_tp_ecm,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
.elem_arr[2] =
|
||||
{
|
||||
(const uint8_t*)"vcom0",
|
||||
multidev_tp_vcom_at,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[3] =
|
||||
{
|
||||
(const uint8_t*)"vcom1",
|
||||
multidev_tp_vcom_log,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[4] =
|
||||
{
|
||||
(const uint8_t*)"vcom2",
|
||||
multidev_tp_vcom_ppp,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[5] =
|
||||
{
|
||||
(const uint8_t*)"vcom3",
|
||||
multidev_tp_vcom_com,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CUST_DEF_TEST_TYPE4
|
||||
const uint8_t epin_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 1,2,3,4,5,6,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
|
||||
const uint8_t epout_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 1,2,3,4,5,6,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
static multidev_custom_info_st t_multidev_custom_info = {
|
||||
.elem_cnt = 4,
|
||||
.elem_arr[0] =
|
||||
{
|
||||
(const uint8_t*)"rndis",
|
||||
multidev_tp_rndis,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
.elem_arr[1] =
|
||||
{
|
||||
(const uint8_t*)"ecm",
|
||||
multidev_tp_ecm,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
.elem_arr[2] =
|
||||
{
|
||||
(const uint8_t*)"vcom0",
|
||||
multidev_tp_vcom_log,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[3] =
|
||||
{
|
||||
(const uint8_t*)"vcom1",
|
||||
multidev_tp_vcom_at,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
|
||||
.elem_arr[4] =
|
||||
{
|
||||
NULL,
|
||||
multidev_tp_none,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef CUST_DEF_TEST_TYPE5
|
||||
const uint8_t epin_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 1,2,3,4,5,6,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
|
||||
const uint8_t epout_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 1,2,3,4,5,6,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
static multidev_custom_info_st t_multidev_custom_info = {
|
||||
.elem_cnt = 3,
|
||||
.elem_arr[0] =
|
||||
{
|
||||
(const uint8_t*)"vcom0",
|
||||
multidev_tp_vcom_at,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[1] =
|
||||
{
|
||||
(const uint8_t*)"vcom1",
|
||||
multidev_tp_vcom_log,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[2] =
|
||||
{
|
||||
(const uint8_t*)"vcom2",
|
||||
multidev_tp_vcom_ppp,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[3] =
|
||||
{
|
||||
NULL,
|
||||
multidev_tp_none,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef CUST_DEF_TEST_TYPE6
|
||||
const uint8_t epin_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 1,6,3,4,5,2,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
|
||||
const uint8_t epout_remap_custom_tbl[EP_REMAP_CUSTOM_CNT] = {
|
||||
0, 3,2,1,4,5,6,7,8,9,10,11,12
|
||||
};
|
||||
|
||||
|
||||
static multidev_custom_info_st t_multidev_custom_info = {
|
||||
.elem_cnt = 5,
|
||||
.elem_arr[0] =
|
||||
{
|
||||
(const uint8_t*)"rndis",
|
||||
multidev_tp_rndis,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
.elem_arr[1] =
|
||||
{
|
||||
(const uint8_t*)"ecm",
|
||||
multidev_tp_ecm,
|
||||
ccinst_setting_mainttp_none,
|
||||
ccinst_setting_subtp_none,
|
||||
},
|
||||
.elem_arr[2] =
|
||||
{
|
||||
(const uint8_t*)"vcom0",
|
||||
multidev_tp_vcom_at,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[3] =
|
||||
{
|
||||
(const uint8_t*)"vcom1",
|
||||
multidev_tp_vcom_log,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[4] =
|
||||
{
|
||||
(const uint8_t*)"vcom2",
|
||||
multidev_tp_vcom_ppp,
|
||||
ccinst_setting_cdc_vcom_maintp,
|
||||
ccinst_setting_vcom_subtp0_inhrnt,
|
||||
},
|
||||
.elem_arr[5] =
|
||||
{
|
||||
NULL,
|
||||
multidev_tp_none,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
extern uint32_t usbc_dev_int_handler (void);
|
||||
void USB_IRQ_Handler(void)
|
||||
{
|
||||
#if (RTE_USB_EN == 1)
|
||||
#if MEASURE_USB_INT_TIME
|
||||
extern void TMU_APTimeReadOpen(UINT32 *sysTime);
|
||||
uint32_t startTime, endTime;
|
||||
TMU_APTimeReadOpen(&startTime);
|
||||
#endif
|
||||
usbc_dev_int_handler();
|
||||
#if MEASURE_USB_INT_TIME
|
||||
TMU_APTimeReadOpen(&endTime);
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, USB_IRQ_Handler_0, P_VALUE, "USB IRQ Time=%d", (endTime-startTime)&0x1FFFFFFF);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uint8_t usbcustom_epin_id_map(uint8_t ep_idx)
|
||||
{
|
||||
if (ep_idx > EP_REMAP_CUSTOM_CNT)
|
||||
{
|
||||
return 0xff;
|
||||
}
|
||||
return epin_remap_custom_tbl[ep_idx];
|
||||
}
|
||||
|
||||
uint8_t usbcustom_epout_id_map(uint8_t ep_idx)
|
||||
{
|
||||
if (ep_idx > EP_REMAP_CUSTOM_CNT)
|
||||
{
|
||||
return 0xff;
|
||||
}
|
||||
return epout_remap_custom_tbl[ep_idx];
|
||||
}
|
||||
|
||||
uint8_t usbcustom_multidev_ccinfo_maprst(void)
|
||||
{
|
||||
uint8_t idx;
|
||||
usb_func_ccinst_st * p_ccinst;
|
||||
ccinst_cdc_setting_st *p_ccinst_cdc_set;
|
||||
|
||||
for(idx = 0; idx < t_usbd_multidev_ccinst_res.vcom_ccinst_subtp0_inhrnt_cnt; idx++)
|
||||
{
|
||||
p_ccinst = t_usbd_multidev_ccinst_res.p_vcom_ccinst_subtp0_entry;
|
||||
if (p_ccinst==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
|
||||
p_ccinst = p_ccinst+idx;
|
||||
p_ccinst_cdc_set = p_ccinst->p_cc_setting;
|
||||
if (p_ccinst_cdc_set==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
p_ccinst_cdc_set->map_flag = 0;
|
||||
}
|
||||
|
||||
for(idx = 0; idx < t_usbd_multidev_ccinst_res.vcom_ccinst_subtp1_2ep_cnt;idx++)
|
||||
{
|
||||
p_ccinst = t_usbd_multidev_ccinst_res.p_vcom_ccinst_subtp1_entry;
|
||||
if (p_ccinst==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
|
||||
p_ccinst = p_ccinst+idx;
|
||||
p_ccinst_cdc_set = p_ccinst->p_cc_setting;
|
||||
if(p_ccinst_cdc_set==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
p_ccinst_cdc_set->map_flag = 0;
|
||||
}
|
||||
|
||||
for(idx = 0; idx < t_usbd_multidev_ccinst_res.vcom_ccinst_subtp2_3ep_cnt;idx++)
|
||||
{
|
||||
p_ccinst = t_usbd_multidev_ccinst_res.p_vcom_ccinst_subtp2_entry;
|
||||
if (p_ccinst==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
p_ccinst = p_ccinst+idx;
|
||||
p_ccinst_cdc_set = p_ccinst->p_cc_setting;
|
||||
if(p_ccinst_cdc_set==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
|
||||
p_ccinst_cdc_set->map_flag = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t usbcustom_multidev_ccinfo_map(usbcust_mdcd_ccinfo_st *p_mdcd_ccinfo)
|
||||
{
|
||||
uint8_t idx;
|
||||
usb_func_ccinst_st * p_ccinst;
|
||||
ccinst_cdc_setting_st *p_ccinst_cdc_set;
|
||||
uint8_t map_valid = 0;
|
||||
if(p_mdcd_ccinfo->setting_maintp == ccinst_setting_cdc_vcom_maintp)
|
||||
{
|
||||
if (p_mdcd_ccinfo->setting_subtp== ccinst_setting_vcom_subtp0_inhrnt)
|
||||
{
|
||||
for(idx = 0; idx < t_usbd_multidev_ccinst_res.vcom_ccinst_subtp0_inhrnt_cnt;idx++)
|
||||
{
|
||||
p_ccinst = t_usbd_multidev_ccinst_res.p_vcom_ccinst_subtp0_entry;
|
||||
if (p_ccinst==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
p_ccinst = p_ccinst+idx;
|
||||
p_ccinst_cdc_set = p_ccinst->p_cc_setting;
|
||||
if (p_ccinst_cdc_set==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
if (p_ccinst_cdc_set->map_flag ==1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
p_ccinst_cdc_set->map_flag = 1;
|
||||
map_valid = 1;
|
||||
p_mdcd_ccinfo->p_func_ccinst = p_ccinst;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
else if (p_mdcd_ccinfo->setting_subtp== ccinst_setting_vcom_subtp1_2ep)
|
||||
{
|
||||
for(idx = 0; idx < t_usbd_multidev_ccinst_res.vcom_ccinst_subtp1_2ep_cnt;idx++)
|
||||
{
|
||||
p_ccinst = t_usbd_multidev_ccinst_res.p_vcom_ccinst_subtp1_entry;
|
||||
if (p_ccinst==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
|
||||
p_ccinst = p_ccinst+idx;
|
||||
p_ccinst_cdc_set = p_ccinst->p_cc_setting;
|
||||
if (p_ccinst_cdc_set==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
if (p_ccinst_cdc_set->map_flag ==1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
p_ccinst_cdc_set->map_flag = 1;
|
||||
map_valid = 1;
|
||||
p_mdcd_ccinfo->p_func_ccinst = p_ccinst;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (p_mdcd_ccinfo->setting_subtp== ccinst_setting_vcom_subtp2_3ep)
|
||||
{
|
||||
for(idx = 0; idx < t_usbd_multidev_ccinst_res.vcom_ccinst_subtp2_3ep_cnt;idx++)
|
||||
{
|
||||
p_ccinst = t_usbd_multidev_ccinst_res.p_vcom_ccinst_subtp2_entry;
|
||||
if (p_ccinst==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
p_ccinst = p_ccinst+idx;
|
||||
p_ccinst_cdc_set = p_ccinst->p_cc_setting;
|
||||
if (p_ccinst_cdc_set==NULL)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
if (p_ccinst_cdc_set->map_flag ==1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
p_ccinst_cdc_set->map_flag = 1;
|
||||
map_valid = 1;
|
||||
p_mdcd_ccinfo->p_func_ccinst = p_ccinst;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//other dev not support ccinst
|
||||
p_mdcd_ccinfo->p_func_ccinst = NULL;
|
||||
map_valid = 1;
|
||||
}
|
||||
|
||||
//load cnt is limited to MULTI_LOAD_CNT_MAX
|
||||
#ifndef USB_DRV_SMALL_IMAGE
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usbcustom_multidev_ccinfo_map_1, P_ERROR, 4, \
|
||||
"clstype %d, inst_id %d, maintp %d, subtp %d", \
|
||||
p_mdcd_ccinfo->cls_type, \
|
||||
p_mdcd_ccinfo->inst_id, \
|
||||
p_mdcd_ccinfo->setting_maintp, \
|
||||
p_mdcd_ccinfo->setting_subtp);
|
||||
#endif
|
||||
|
||||
if (map_valid==0)
|
||||
{
|
||||
#ifndef USB_DRV_SMALL_IMAGE
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usbcustom_multidev_ccinfo_map_2, P_ERROR, 4, \
|
||||
"clstype %d, inst_id %d, maintp %d, subtp %d", \
|
||||
p_mdcd_ccinfo->cls_type, \
|
||||
p_mdcd_ccinfo->inst_id, \
|
||||
p_mdcd_ccinfo->setting_maintp, \
|
||||
p_mdcd_ccinfo->setting_subtp);
|
||||
EC_ASSERT(0, p_mdcd_ccinfo->cls_type, p_mdcd_ccinfo->inst_id, \
|
||||
(p_mdcd_ccinfo->setting_maintp<<8) |p_mdcd_ccinfo->setting_subtp);
|
||||
#else
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uint8_t usbcustom_multidev_cfg_reset(void)
|
||||
{
|
||||
uint8_t loop_idx;
|
||||
uint32_t map_flag = 0;
|
||||
uint32_t cur_flag = 0;
|
||||
uint8_t ret;
|
||||
if (epout_remap_custom_tbl[0]!=0)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
for (loop_idx = 1; loop_idx < EP_REMAP_CUSTOM_CNT; loop_idx++)
|
||||
{
|
||||
if (epout_remap_custom_tbl[loop_idx] >= EP_REMAP_CUSTOM_CNT)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
cur_flag = (1UL<<epout_remap_custom_tbl[loop_idx]);
|
||||
if (cur_flag&map_flag)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
map_flag |= (1UL<<epout_remap_custom_tbl[loop_idx]);
|
||||
}
|
||||
ret = usbcustom_multidev_ccinfo_maprst();
|
||||
|
||||
if(ret)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
#ifdef USBD_EMC_MAC_CONFIG
|
||||
update_ecm_mac();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
multidev_custom_info_st* usbcustom_multidev_cfg_update(void)
|
||||
{
|
||||
return &t_multidev_custom_info;
|
||||
}
|
||||
|
||||
uint8_t usbcustom_multidev_cfg_end(multidev_load_info_st *p_multidev_load)
|
||||
{
|
||||
if ((p_multidev_load->load_cnt+ p_multidev_load->filter_cnt ) != t_multidev_custom_info.elem_cnt)
|
||||
{
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
|
||||
if (p_multidev_load->load_cnt > MULTI_DEV_LOADCNT_MAX)
|
||||
{
|
||||
//load cnt is limited to MULTI_LOAD_CNT_MAX
|
||||
#ifndef USB_DRV_SMALL_IMAGE
|
||||
ECOMM_TRACE(UNILOG_PLA_DRIVER, usbcustom_multidev_cfg_end_1, P_ERROR, 1,"p_multidev_load->load_cnt %x", p_multidev_load->load_cnt);
|
||||
#endif
|
||||
return USBD_MULTIDEV_LOAD_FAIL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *usbcustom_multidev_strdesc(usbcust_mdcd_strdesc_st *p_mdcd_strdesc)
|
||||
{
|
||||
uint8_t* p_intf_str_desc = (uint8_t*)"default";
|
||||
switch(p_mdcd_strdesc->cls_type)
|
||||
{
|
||||
case multidev_tp_rndis:
|
||||
p_intf_str_desc = (uint8_t*)"rndis";
|
||||
break;
|
||||
case multidev_tp_ecm:
|
||||
p_intf_str_desc = (uint8_t*)"ecm";
|
||||
break;
|
||||
case multidev_tp_vcom_at:
|
||||
p_intf_str_desc = (uint8_t*)"at";
|
||||
break;
|
||||
case multidev_tp_vcom_log:
|
||||
p_intf_str_desc = (uint8_t*)"log";
|
||||
break;
|
||||
case multidev_tp_vcom_ppp:
|
||||
p_intf_str_desc = (uint8_t*)"ppp";
|
||||
break;
|
||||
case multidev_tp_vcom_com:
|
||||
p_intf_str_desc = (uint8_t*)"com";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef USB_DRV_SMALL_IMAGE
|
||||
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, usbcustom_multidevstr_desc_1, P_DEBUG, \
|
||||
"cls_type %d, inst_id 0x%x, name %s, intf string %s", \
|
||||
p_mdcd_strdesc->cls_type, \
|
||||
p_mdcd_strdesc->inst_id, \
|
||||
p_mdcd_strdesc->p_func_name, \
|
||||
p_intf_str_desc);
|
||||
|
||||
#endif
|
||||
return p_intf_str_desc;
|
||||
}
|
||||
|
||||
uint8_t usbcustom_multidev_cmndesc(usbcust_mdcd_cmndesc_st *p_mdcd_cmndesc)
|
||||
{
|
||||
|
||||
usbcust_cmndesc_data_st *p_cmndesc_data= &(p_mdcd_cmndesc->t_cmndesc_data);
|
||||
|
||||
switch(p_mdcd_cmndesc->cls_type)
|
||||
{
|
||||
case multidev_tp_rndis:
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceClass = 0xE0;
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceSubClass = 0x01;
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceProtocol = 0x03;
|
||||
p_cmndesc_data->b_intf_ctrl_desc_upd = 1;
|
||||
|
||||
#ifndef USB_DRV_SMALL_IMAGE
|
||||
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, usbcustom_multidev_cmndesc_1, P_DEBUG, \
|
||||
"name %s, cls = 0x%x, subcls 0x%x, protocol 0x%x", \
|
||||
p_mdcd_cmndesc->p_func_name, \
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceClass, \
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceSubClass, \
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceProtocol);
|
||||
#endif
|
||||
break;
|
||||
case multidev_tp_ecm:
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceClass = 0x02;
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceSubClass = 0x06;
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceProtocol = 0x00;
|
||||
p_cmndesc_data->b_intf_ctrl_desc_upd = 1;
|
||||
|
||||
#ifndef USB_DRV_SMALL_IMAGE
|
||||
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, usbcustom_multidev_cmndesc_1, P_DEBUG, \
|
||||
"name %s, cls = 0x%x, subcls 0x%x, protocol 0x%x", \
|
||||
p_mdcd_cmndesc->p_func_name, \
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceClass, \
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceSubClass, \
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceProtocol);
|
||||
#endif
|
||||
break;
|
||||
case multidev_tp_vcom_at:
|
||||
case multidev_tp_vcom_log:
|
||||
case multidev_tp_vcom_ppp:
|
||||
case multidev_tp_vcom_com:
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceClass = 0x02;
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceSubClass = 0x02;
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceProtocol = 0x01;
|
||||
p_cmndesc_data->b_intf_ctrl_desc_upd = 1;
|
||||
|
||||
#ifndef USB_DRV_SMALL_IMAGE
|
||||
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, usbcustom_multidev_cmndesc_1, P_DEBUG, \
|
||||
"name %s, cls = 0x%x, subcls 0x%x, protocol 0x%x", \
|
||||
p_mdcd_cmndesc->p_func_name, \
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceClass, \
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceSubClass, \
|
||||
p_cmndesc_data->intf_ctrl_desc.bInterfaceProtocol);
|
||||
#endif
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t usbcustom_multidev_ctrl_proc(usbcust_md_ctrl_st* p_usbcust_md_ctrl)
|
||||
{
|
||||
// t_ctl_req.cmd Bit 31 : 0 host to dev, 1 dev to host
|
||||
|
||||
#ifndef USB_DRV_SMALL_IMAGE
|
||||
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, usbcustom_multidev_ctrl_proc_1, P_DEBUG, \
|
||||
"cls_type = %d, inst_id %d, name %s, req 0x%x", \
|
||||
p_usbcust_md_ctrl->cls_type, \
|
||||
p_usbcust_md_ctrl->inst_id, \
|
||||
p_usbcust_md_ctrl->p_func_name, \
|
||||
p_usbcust_md_ctrl->t_ctl_req.cmd);
|
||||
#if 0
|
||||
ECPLAT_DUMP(UNILOG_PLA_DRIVER, usbcustom_multidev_ctrl_proc_2, P_DEBUG, \
|
||||
"clsdev req data:", \
|
||||
p_usbcust_md_ctrl->t_ctl_req.len, \
|
||||
p_usbcust_md_ctrl->t_ctl_req.buf);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __USER_CODE__
|
||||
extern void usb_ctrl_pre_proc(usbcust_md_ctrl_st *);
|
||||
usb_ctrl_pre_proc(p_usbcust_md_ctrl);
|
||||
#endif
|
||||
p_usbcust_md_ctrl->t_ctl_req.cmd &= (~(0x1UL<<31));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\fn usblpw_innophy_enh_drv_strenth(void)
|
||||
\brief used by USB driver, called when USBC init.
|
||||
user could modify the para below for differnt use cases
|
||||
\note cfg usb phy para for none standard usb cable,e.g. fly wire in production line
|
||||
0x4d0b0030: Enables pre-emphasis----should keep default val set below
|
||||
0x4d0b0040: b[5:3] Tx HS pre_emphasize strength configure, 3b111 represents the
|
||||
strongest , 3b000 the weakest
|
||||
0x4d0b0064: b[6:3] Rx squelch trigger point configures
|
||||
0x4d0b0124: b[4:2] HS eye height tuning
|
||||
if any problem ,contact EC
|
||||
|
||||
*/
|
||||
void usblpw_innophy_enh_drv_strenth(void)
|
||||
{
|
||||
volatile uint32_t* addr = (volatile uint32_t*)0x4d0b0030;
|
||||
* addr = (* addr &~ (0x7<<0)) | (0x5<<0);
|
||||
|
||||
addr = (volatile uint32_t*)0x4d0b0040;
|
||||
* addr = (* addr &~ (0x7<<3)) | (0x4<<3);
|
||||
|
||||
addr = (volatile uint32_t*)0x4d0b0064;
|
||||
* addr = (* addr &~ (0xf<<3)) | (0x6<<3);
|
||||
|
||||
addr = (volatile uint32_t*)0x4d0b0124;
|
||||
* addr = (* addr &~ (0x7<<2)) | (0x5<<2);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
#include <stdio.h>
|
||||
#include "usbd_multi_clstype.h"
|
||||
|
||||
|
||||
#define USB_DEV_QUALIFIER_DESC_ARR_SIZE 0x0A
|
||||
|
||||
|
||||
#define DEF_LANGID_STR 0x409
|
||||
#define DEF_MANUFACT_STR "AirM2M";
|
||||
#define DEF_PRODUCT_HS_STR "AirM2M Compo";
|
||||
#define DEF_SER_NUM_HS_STR "000000000001"
|
||||
|
||||
#define DEF_CFG_HS_STR "Compo Config"
|
||||
#define DEF_INTF_HS_STR "Compo Interface"
|
||||
|
||||
|
||||
#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
|
||||
#define USB_STRING_DESCRIPTOR_TYPE 0x03
|
||||
#define USB_SIZ_STRING_LANGID 4
|
||||
#define USB_SIZ_DEVICE_DESC 0x12
|
||||
|
||||
#define LOBYTE(x) ((uint8_t)(x & 0x00FF))
|
||||
#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8))
|
||||
|
||||
|
||||
#define USB_DESC_TYPE_DEVICE 1
|
||||
#define USB_DESC_TYPE_CONFIGURATION 2
|
||||
#define USB_DESC_TYPE_STRING 3
|
||||
#define USB_DESC_TYPE_INTERFACE 4
|
||||
#define USB_DESC_TYPE_ENDPOINT 5
|
||||
#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
|
||||
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
|
||||
|
||||
|
||||
uint32_t udev_last_err = 0;
|
||||
|
||||
|
||||
|
||||
uint8_t usbd_dev_desc_arr[USB_SIZ_DEVICE_DESC] =
|
||||
{
|
||||
0x12, /* bLength */
|
||||
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
0x00,
|
||||
0x02, /* bcdUSB = 2.00 */
|
||||
0xEF, /* bDeviceClass: IAD */
|
||||
0x02, /* bDeviceSubClass */
|
||||
0x01, /* bDeviceProtocol */
|
||||
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
|
||||
0xd1,
|
||||
0x19, /* idVendor = 0x19d1 */
|
||||
0x01,
|
||||
0x00, /* idProduct = 0x0001 */
|
||||
|
||||
0x00,
|
||||
0x02, /* bcdDevice = 2.00 */
|
||||
1, /* Index of string descriptor describing manufacturer */
|
||||
2, /* Index of string descriptor describing product */
|
||||
3, /* Index of string descriptor describing the device's serial number */
|
||||
0x01 /* bNumConfigurations */
|
||||
};
|
||||
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
uint8_t usbd_dev_qualifier_desc_arr[USB_DEV_QUALIFIER_DESC_ARR_SIZE] =
|
||||
{
|
||||
USB_DEV_QUALIFIER_DESC_ARR_SIZE,
|
||||
USB_DESC_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0xEF,
|
||||
0x02,
|
||||
0x01,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
};
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
uint8_t usbd_dev_langid_desc[USB_SIZ_STRING_LANGID] =
|
||||
{
|
||||
USB_SIZ_STRING_LANGID,
|
||||
USB_DESC_TYPE_STRING,
|
||||
LOBYTE(DEF_LANGID_STR),
|
||||
HIBYTE(DEF_LANGID_STR),
|
||||
};
|
||||
|
||||
uint8_t *usbcustom_product_str_desc(void)
|
||||
{
|
||||
return (uint8_t *)DEF_PRODUCT_HS_STR;
|
||||
}
|
||||
|
||||
uint8_t *usbcustom_manufacture_str_desc(void)
|
||||
{
|
||||
return (uint8_t *)DEF_MANUFACT_STR;
|
||||
}
|
||||
|
||||
uint8_t *usbcustom_ser_str_desc(void)
|
||||
{
|
||||
return (uint8_t *)DEF_SER_NUM_HS_STR;
|
||||
}
|
||||
|
||||
uint8_t *usbcustom_cfg_str_desc(void)
|
||||
{
|
||||
return (uint8_t *)DEF_CFG_HS_STR;
|
||||
}
|
||||
|
||||
uint8_t *usbcustom_intf_str_desc(void)
|
||||
{
|
||||
return (uint8_t *)DEF_INTF_HS_STR;
|
||||
}
|
||||
|
||||
uint8_t *usbcustom_qulifier_desc(void)
|
||||
{
|
||||
return usbd_dev_qualifier_desc_arr;
|
||||
}
|
||||
|
||||
uint8_t usbcustom_cfg_remote_wkup_bit(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t usbcustom_cfg_self_powered_bit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t usbcustom_cfg_max_power(void)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
void udev_notify_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void udev_notify_device_reset (uint8_t speed)
|
||||
{
|
||||
}
|
||||
|
||||
void udev_notify_device_config (void)
|
||||
{
|
||||
}
|
||||
|
||||
void udev_notify_device_suspend(void)
|
||||
{
|
||||
}
|
||||
|
||||
void udev_notify_device_resume(void)
|
||||
{
|
||||
}
|
||||
|
||||
void udev_notify_device_connect (void)
|
||||
{
|
||||
}
|
||||
|
||||
void udev_notify_device_disconnect (void)
|
||||
{
|
||||
}
|
||||
|
||||
void udev_set_last_err(uint32_t err_no)
|
||||
{
|
||||
udev_last_err = err_no;
|
||||
}
|
||||
|
||||
|
||||
uint32_t udev_get_last_err(void)
|
||||
{
|
||||
return udev_last_err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
#include "string.h"
|
||||
#include "cmsis_os2.h"
|
||||
#include "hal_misc.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "usb_bl_api.h"
|
||||
|
||||
int vcomx_isconnect(uint8_t vcom_num);
|
||||
int vcomx_get_in_waiting(uint8_t vcom_num);
|
||||
int vcomx_poll_rx(uint8_t vcom_num, uint32_t timeout);
|
||||
int vcomx_recv(uint8_t vcom_num, uint8_t* buf, uint16_t len);
|
||||
int vcomx_get_out_avail(uint8_t vcom_num);
|
||||
int vcomx_poll_tx(uint8_t vcom_num, uint32_t timeout);
|
||||
int vcomx_send(uint8_t vcom_num, uint8_t* buf, uint16_t len);
|
||||
|
||||
|
||||
#ifdef VCOM_DBGEN
|
||||
void vcom_dbg_putchar(uint8_t ch);
|
||||
|
||||
void vcomdbg_hex(uint32_t hex)
|
||||
{
|
||||
uint16_t val;
|
||||
for (int32_t idx = 28; idx >=0; idx-=4)
|
||||
{
|
||||
val = ((hex>>idx)&0xf) + 0x30;
|
||||
if(val>=0x3a)
|
||||
{
|
||||
val = val + 0x27;
|
||||
}
|
||||
vcom_dbg_putchar(val);
|
||||
}
|
||||
}
|
||||
|
||||
void vcomdbg_str(uint8_t* str)
|
||||
{
|
||||
while(*str)
|
||||
{
|
||||
vcom_dbg_putchar(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
void vcomdbg_str_and_hex(uint8_t* str, uint32_t hex)
|
||||
{
|
||||
vcomdbg_str(str);
|
||||
//vcomdbg_str((uint8_t*)"\r\n");
|
||||
vcomdbg_hex(hex);
|
||||
vcomdbg_str((uint8_t*)"\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void vcom_app_delay(uint32_t ticks)
|
||||
{
|
||||
volatile int us_cnt = 0;
|
||||
volatile int loop_in_us;
|
||||
//depend on code speed, add 6 for flash code at 50M, cpu 204m
|
||||
for (us_cnt = 0; us_cnt < ticks*1000; us_cnt+=6){
|
||||
loop_in_us = 0;
|
||||
while(loop_in_us++< 70);
|
||||
}
|
||||
}
|
||||
|
||||
int vcom_app_recv_proc(uint8_t vcom_num, uint8_t* rcvbuf_ptr, uint32_t size, uint8_t timeout)
|
||||
{
|
||||
int rxwait_cnt;
|
||||
int poll_stat;
|
||||
uint8_t recvd_size = 0;
|
||||
int byte_cnt = 0;
|
||||
uint32_t ticks_tmout = timeout; // 1tick for 1ms
|
||||
uint32_t ticks_elapsed = 0;
|
||||
uint32_t ticks_step = 1;
|
||||
|
||||
if (size ==0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (vcomx_isconnect(vcom_num) <=0)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom[%d] not connected%x \r\n", vcom_num);
|
||||
return ERR_DEV_NO_CONNECT;
|
||||
}
|
||||
|
||||
//rxwait_cnt = p_serial_vcom->p_ops->get_in_waiting(p_serial_vcom);
|
||||
rxwait_cnt = vcomx_get_in_waiting(vcom_num);
|
||||
if (rxwait_cnt <0)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("get_in_waiting err %d \r\n", rxwait_cnt);
|
||||
return rxwait_cnt;
|
||||
}
|
||||
if (rxwait_cnt ==0)
|
||||
{
|
||||
if (ticks_elapsed >=ticks_tmout)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("recv timeout, recved bytes %d \r\n", recvd_size);
|
||||
return recvd_size;
|
||||
}
|
||||
|
||||
//poll_stat = p_serial_vcom->p_ops->poll_rx(p_serial_vcom, 0);
|
||||
poll_stat =vcomx_poll_rx(vcom_num, 0);
|
||||
if ((poll_stat <0) && (poll_stat!=ERR_DEV_RX_TIMOUT))
|
||||
{
|
||||
VCDBG_STR_AND_HEX("recv poll state break %d \r\n", poll_stat);
|
||||
return poll_stat;
|
||||
}
|
||||
vcom_app_delay(ticks_step);
|
||||
ticks_elapsed += ticks_step;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rxwait_cnt> size)
|
||||
{
|
||||
rxwait_cnt = size;
|
||||
}
|
||||
|
||||
//byte_cnt = p_serial_vcom->p_ops->recv(p_serial_vcom, rcvbuf_ptr, rxwait_cnt);
|
||||
byte_cnt = vcomx_recv(vcom_num, rcvbuf_ptr, rxwait_cnt);
|
||||
if (byte_cnt < 0)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("recv state break %d \r\n", byte_cnt);
|
||||
return byte_cnt;
|
||||
}
|
||||
|
||||
recvd_size += byte_cnt;
|
||||
if (recvd_size>=size)
|
||||
{
|
||||
return recvd_size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vcom_app_send_proc(uint8_t vcom_num, uint8_t* sndbuf_ptr, uint32_t size, uint8_t timeout)
|
||||
{
|
||||
int txavail_cnt;
|
||||
int poll_stat;
|
||||
int byte_cnt;
|
||||
uint8_t sended_size = 0;
|
||||
uint32_t ticks_tmout = timeout; // 1tick for 1ms
|
||||
uint32_t ticks_elapsed = 0;
|
||||
uint32_t ticks_step = 1;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (vcomx_isconnect(vcom_num) <= 0)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom[%d] not connected \r\n", vcom_num);
|
||||
return ERR_DEV_NO_CONNECT;
|
||||
}
|
||||
|
||||
//txavail_cnt = p_serial_vcom->p_ops->get_out_avail(p_serial_vcom);
|
||||
txavail_cnt = vcomx_get_out_avail(vcom_num);
|
||||
if (txavail_cnt == 0)
|
||||
{
|
||||
if (ticks_elapsed >=ticks_tmout)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom[%d] \r\n", vcom_num);
|
||||
VCDBG_STR_AND_HEX("send timeout, sended bytes %x \r\n", sended_size);
|
||||
return sended_size;
|
||||
}
|
||||
//poll_stat = p_serial_vcom->p_ops->poll_tx(p_serial_vcom, 0);
|
||||
poll_stat = vcomx_poll_tx(vcom_num, 0);
|
||||
if ((poll_stat <0) && (poll_stat!=ERR_DEV_RX_TIMOUT))
|
||||
{
|
||||
VCDBG_STR_AND_HEX("send poll state break %d \r\n", poll_stat);
|
||||
return poll_stat;
|
||||
}
|
||||
|
||||
vcom_app_delay(ticks_step);
|
||||
ticks_elapsed += ticks_step;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (size < txavail_cnt)
|
||||
{
|
||||
txavail_cnt = size;
|
||||
}
|
||||
|
||||
//byte_cnt = p_serial_vcom->p_ops->send(p_serial_vcom, sndbuf_ptr, txavail_cnt);
|
||||
byte_cnt = vcomx_send(vcom_num, sndbuf_ptr, txavail_cnt);
|
||||
if (byte_cnt <0)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("send state break %d \r\n", byte_cnt);
|
||||
return byte_cnt;
|
||||
}
|
||||
|
||||
sended_size +=byte_cnt;
|
||||
if (sended_size>=size)
|
||||
{
|
||||
return sended_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,378 @@
|
||||
#include "ec618.h"
|
||||
#include "string.h"
|
||||
#include "cmsis_os2.h"
|
||||
#include "hal_misc.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "bl_bsp.h"
|
||||
#include "usb_bl_api.h"
|
||||
|
||||
int vcomx_isconnect(uint8_t vcom_num);
|
||||
int vcomx_get_in_waiting(uint8_t vcom_num);
|
||||
int vcomx_poll_rx(uint8_t vcom_num, uint32_t timeout);
|
||||
int vcomx_recv(uint8_t vcom_num, uint8_t* buf, uint16_t len);
|
||||
int vcomx_get_out_avail(uint8_t vcom_num);
|
||||
int vcomx_poll_tx(uint8_t vcom_num, uint32_t timeout);
|
||||
int vcomx_send(uint8_t vcom_num, uint8_t* buf, uint16_t len);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
vcom_step_idle = 0,
|
||||
vcom_step_recv ,
|
||||
vcom_step_send ,
|
||||
vcom_step_busy_sending ,
|
||||
|
||||
}vcom_app_step_type;
|
||||
|
||||
#define VCOM_STATE_IDLE 0
|
||||
#define VCOM_TEST_BUF_SIZE 0x400
|
||||
typedef struct
|
||||
{
|
||||
//uint8_t recv_en;
|
||||
//uint8_t send_en;
|
||||
vcom_app_step_type step;
|
||||
uint32_t received_len;
|
||||
uint32_t sended_len;
|
||||
uint8_t vcom_rcvbuff[VCOM_TEST_BUF_SIZE];
|
||||
uint8_t vcom_sndbuff[VCOM_TEST_BUF_SIZE];
|
||||
}vcom_app_ctx_st;
|
||||
|
||||
#define VCOM_NUM_MAX 3
|
||||
vcom_app_ctx_st vcom_app_ctx[VCOM_NUM_MAX];
|
||||
|
||||
void vcom_app_ctx_init(void)
|
||||
{
|
||||
memset(&vcom_app_ctx, 0, sizeof(vcom_app_ctx));
|
||||
}
|
||||
|
||||
int vcom_app_ctx_is_idlestep(uint8_t vcom_num)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return -1;
|
||||
}
|
||||
if(vcom_app_ctx[vcom_num].step == vcom_step_idle)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t vcom_app_ctx_is_recvstep(uint8_t vcom_num)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return 0;
|
||||
}
|
||||
if(vcom_app_ctx[vcom_num].step == vcom_step_recv)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t vcom_app_ctx_is_sendstep(uint8_t vcom_num)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return 0;
|
||||
}
|
||||
if(vcom_app_ctx[vcom_num].step == vcom_step_send)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t vcom_app_ctx_is_busysending(uint8_t vcom_num)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return 0;
|
||||
}
|
||||
if(vcom_app_ctx[vcom_num].step == vcom_step_busy_sending)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vcom_app_ctx_set_step(uint8_t vcom_num, vcom_app_step_type step)
|
||||
{
|
||||
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return;
|
||||
}
|
||||
vcom_app_ctx[vcom_num].step = step;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
int vcom_app_get_rcvbuff_size(uint8_t vcom_num)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return -1;
|
||||
}
|
||||
return sizeof(vcom_app_ctx[vcom_num].vcom_rcvbuff);
|
||||
}
|
||||
|
||||
uint8_t* vcom_app_get_rcvbuff_ptr(uint8_t vcom_num)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return NULL;
|
||||
}
|
||||
return &(vcom_app_ctx[vcom_num].vcom_rcvbuff[0]);
|
||||
}
|
||||
|
||||
int vcom_app_get_sndbuff_size(uint8_t vcom_num)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return -1;
|
||||
}
|
||||
return sizeof(vcom_app_ctx[vcom_num].vcom_sndbuff);
|
||||
}
|
||||
|
||||
uint8_t* vcom_app_get_sndbuff_ptr(uint8_t vcom_num)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return NULL;
|
||||
}
|
||||
return &(vcom_app_ctx[vcom_num].vcom_sndbuff[0]);
|
||||
}
|
||||
|
||||
int vcom_app_update_recved_size(uint8_t vcom_num, uint32_t size)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return -1;
|
||||
}
|
||||
vcom_app_ctx[vcom_num].received_len = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vcom_app_update_sended_size(uint8_t vcom_num, uint32_t size)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return -1;
|
||||
}
|
||||
vcom_app_ctx[vcom_num].sended_len = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vcom_app_get_recved_size(uint8_t vcom_num)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return -1;
|
||||
}
|
||||
return vcom_app_ctx[vcom_num].received_len;
|
||||
}
|
||||
|
||||
int vcom_app_get_sended_size(uint8_t vcom_num)
|
||||
{
|
||||
if (vcom_num>=VCOM_NUM_MAX)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom_num(%d) error \r\n", vcom_num);
|
||||
return -1;
|
||||
}
|
||||
return vcom_app_ctx[vcom_num].sended_len;
|
||||
}
|
||||
|
||||
int vcom_app_send_proc(uint8_t vcom_num, uint8_t* sndbuf_ptr, uint32_t size, uint8_t timeout);
|
||||
int vcom_app_recv_proc(uint8_t vcom_num, uint8_t* rcvbuf_ptr, uint32_t size, uint8_t timeout);
|
||||
void vcom_app_delay(uint32_t ticks);
|
||||
|
||||
void vcom_loopback_test(void *p)
|
||||
{
|
||||
int ret;
|
||||
int txavail_cnt;
|
||||
//#if DEVICE_VCOM_INSTANCE
|
||||
uint32_t sended_size;
|
||||
uint8_t * send_buf_ptr;
|
||||
uint8_t * recv_buf_ptr;
|
||||
|
||||
vcom_app_ctx_init();
|
||||
int vcom_num = 0;
|
||||
VCDBG_STR("uart_loopback_test start \r\n");
|
||||
|
||||
while(1)
|
||||
{
|
||||
vcom_app_delay(10);
|
||||
vcom_num = vcom_num+1;
|
||||
vcom_num = vcom_num%VCOM_NUM_MAX;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (vcomx_isconnect(vcom_num) ==0)
|
||||
{
|
||||
vcom_app_delay(1000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (vcom_app_ctx_is_idlestep(vcom_num)==1)
|
||||
{
|
||||
|
||||
if (vcomx_isconnect(vcom_num) ==0)
|
||||
{
|
||||
vcom_app_delay(20);
|
||||
break;
|
||||
}
|
||||
|
||||
vcom_app_ctx_set_step(vcom_num, vcom_step_recv);
|
||||
VCDBG_STR_AND_HEX("vcom(%d) [recv] \r\n", vcom_num);
|
||||
}
|
||||
|
||||
if (vcom_app_ctx_is_recvstep(vcom_num)==1)
|
||||
{
|
||||
ret= vcom_app_recv_proc(vcom_num,
|
||||
vcom_app_get_rcvbuff_ptr(vcom_num),
|
||||
vcom_app_get_rcvbuff_size(vcom_num), 1);
|
||||
if (ret <=0)
|
||||
{
|
||||
vcom_app_delay(1);
|
||||
break;
|
||||
}
|
||||
vcom_app_update_recved_size(vcom_num, ret);
|
||||
vcom_app_update_sended_size(vcom_num, 0);
|
||||
vcom_app_ctx_set_step(vcom_num, vcom_step_send);
|
||||
|
||||
VCDBG_STR_AND_HEX("vcom(%d) [recv] ->[send] \r\n", vcom_num);
|
||||
VCDBG_STR_AND_HEX("ret %d \r\n",ret);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (vcom_app_ctx_is_sendstep(vcom_num)==1)
|
||||
{
|
||||
if (vcom_app_get_recved_size(vcom_num) <0)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom(%d) [send] recved_size <0, ->[idle] \r\n", vcom_num);
|
||||
vcom_app_ctx_set_step(vcom_num, vcom_step_idle);
|
||||
vcom_app_update_recved_size(vcom_num, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
sended_size = vcom_app_get_sended_size(vcom_num);
|
||||
recv_buf_ptr= vcom_app_get_rcvbuff_ptr(vcom_num);
|
||||
send_buf_ptr = vcom_app_get_rcvbuff_ptr(vcom_num);
|
||||
if (sended_size >=vcom_app_get_recved_size(vcom_num))
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom(%d) [send] unneeded->[idle]", vcom_num);
|
||||
VCDBG_STR_AND_HEX("recved %d\r\n",
|
||||
vcom_app_get_recved_size(vcom_num));
|
||||
VCDBG_STR_AND_HEX("sended %d\r\n",
|
||||
vcom_app_get_sended_size(vcom_num));
|
||||
break;
|
||||
}
|
||||
|
||||
txavail_cnt = vcom_app_get_sndbuff_size(vcom_num);
|
||||
if ((txavail_cnt+sended_size) > vcom_app_get_recved_size(vcom_num))
|
||||
{
|
||||
txavail_cnt = vcom_app_get_recved_size(vcom_num) - sended_size;
|
||||
}
|
||||
memcpy(send_buf_ptr+sended_size, recv_buf_ptr+sended_size, txavail_cnt);
|
||||
|
||||
ret = vcom_app_send_proc(vcom_num, send_buf_ptr+sended_size, txavail_cnt, 1);
|
||||
if (ret <0)
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom(%d) [send] , ->[idle] \r\n", vcom_num);
|
||||
VCDBG_STR_AND_HEX("fail %08x %d\r\n",ret);
|
||||
vcom_app_ctx_set_step(vcom_num, vcom_step_idle);
|
||||
vcom_app_update_recved_size(vcom_num, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
sended_size+=ret;
|
||||
|
||||
|
||||
vcom_app_update_sended_size(vcom_num, ret);
|
||||
|
||||
if (sended_size >=vcom_app_get_recved_size(vcom_num))
|
||||
{
|
||||
VCDBG_STR_AND_HEX("vcom(%d) [send] ->[idle] finish \r\n", vcom_num);
|
||||
VCDBG_STR_AND_HEX("recved %d \r\n", vcom_app_get_recved_size(vcom_num));
|
||||
VCDBG_STR_AND_HEX("sended %d \r\n", vcom_app_get_sended_size(vcom_num));
|
||||
|
||||
vcom_app_ctx_set_step(vcom_num, vcom_step_idle);
|
||||
vcom_app_update_recved_size(vcom_num, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
vcom_app_ctx_set_step(vcom_num, vcom_step_busy_sending);
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (vcom_app_ctx_is_busysending(vcom_num)==1)
|
||||
{
|
||||
vcom_app_delay(1);
|
||||
vcom_app_ctx_set_step(vcom_num, vcom_step_send);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VCDBG_STR("uart_loopback_test end \r\n");
|
||||
}
|
||||
|
||||
void vcom_urcprint_test(void)
|
||||
{
|
||||
uint8_t vcom_num = 0;
|
||||
int cnt = 0;
|
||||
while(cnt++<2000)
|
||||
{
|
||||
vcom_app_delay(10);
|
||||
vcom_num = vcom_num+1;
|
||||
vcom_num = vcom_num%VCOM_NUM_MAX;
|
||||
|
||||
SelNormalOrURCPrint(1);
|
||||
BSP_URCSetCfg(1, 115200, URCVCom0PrintType+vcom_num, vcom_num);
|
||||
printf("URC PRINT %d\r\n", vcom_num);
|
||||
|
||||
SelNormalOrURCPrint(0);
|
||||
printf("NO URC PRINT\r\n");
|
||||
|
||||
}
|
||||
}
|
||||
uint32_t BSP_UsbInit(void);
|
||||
void WDT_stop(void);
|
||||
void vcom_app_delay(uint32_t ticks);
|
||||
|
||||
void vcom_urc_test_entry(void)
|
||||
{
|
||||
WDT_stop();// stop watchdog for test
|
||||
extern uint8_t usbstack_clear_ctx_stat(void);
|
||||
extern void usbstack_set_ctx_vbus_mode(uint8_t vbus_mode_en, uint8_t vbus_pad_idx);
|
||||
|
||||
usbstack_clear_ctx_stat();
|
||||
usbstack_set_ctx_vbus_mode(0,0xf);
|
||||
BSP_UsbInit();
|
||||
|
||||
extern void vcom_urcprint_test(void);
|
||||
vcom_urcprint_test();
|
||||
|
||||
void vcom_loopback_test(void *p);
|
||||
vcom_loopback_test(NULL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copy right: 2017-, Copyrigths of AirM2M Ltd.
|
||||
* File name: wdt.c
|
||||
* Description: EC618 wdt driver source file
|
||||
* History: Rev1.0 2018-07-18
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "wdt.h"
|
||||
#include "clock.h"
|
||||
#include "slpman.h"
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
|
||||
/** \brief Internal used data structure */
|
||||
typedef struct _wdt_database
|
||||
{
|
||||
bool isInited; /**< whether wdt has been initialized */
|
||||
bool wdtStartStatus; /**< wdt enable status, used for low power restore */
|
||||
WdtConfig_t wdtConfig; /**< wdt configuration, used for low power restore */
|
||||
} WdtDatabase_t;
|
||||
|
||||
static WdtDatabase_t gWdtDataBase = {0};
|
||||
|
||||
/**
|
||||
\fn static void WDT_enterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
\brief Perform necessary preparations before sleep
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
*/
|
||||
static void WDT_enterLowPowerStatePrepare(void* pdata, slpManLpState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
if(gWdtDataBase.isInited == true)
|
||||
{
|
||||
gWdtDataBase.wdtStartStatus = WDT_getStartStatus();
|
||||
//disable clock
|
||||
CLOCK_clockDisable(PCLK_WDG);
|
||||
CLOCK_clockDisable(FCLK_WDG);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
\fn static void WDT_exitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
\brief Restore after exit from sleep
|
||||
\param[in] pdata pointer to user data, not used now
|
||||
\param[in] state low power state
|
||||
|
||||
*/
|
||||
static void WDT_exitLowPowerStateRestore(void* pdata, slpManLpState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case SLPMAN_SLEEP1_STATE:
|
||||
|
||||
if(gWdtDataBase.isInited == true)
|
||||
{
|
||||
//enable clock
|
||||
CLOCK_clockEnable(PCLK_WDG);
|
||||
CLOCK_clockEnable(FCLK_WDG);
|
||||
|
||||
WDT_unlock();
|
||||
WDT->CTRL = (WDT->CTRL &~ WDT_CTRL_MODE_Msk) | EIGEN_VAL2FLD(WDT_CTRL_MODE, gWdtDataBase.wdtConfig.mode);
|
||||
WDT_unlock();
|
||||
WDT->TOVR = gWdtDataBase.wdtConfig.timeoutValue;
|
||||
|
||||
if(gWdtDataBase.wdtStartStatus)
|
||||
WDT_start();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void WDT_unlock(void)
|
||||
{
|
||||
WDT->LOCK = 0xABABU;
|
||||
}
|
||||
|
||||
void WDT_kick(void)
|
||||
{
|
||||
uint32_t mask = SaveAndSetIRQMask();
|
||||
|
||||
WDT_unlock();
|
||||
WDT->CCR = WDT_CCR_CNT_CLR_Msk;
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
}
|
||||
|
||||
void WDT_getDefaultConfig(WdtConfig_t *config)
|
||||
{
|
||||
ASSERT(config);
|
||||
|
||||
config->mode = WDT_INTERRUPT_ONLY_MODE;
|
||||
config->timeoutValue = 0xFFFFU;
|
||||
}
|
||||
|
||||
void WDT_init(const WdtConfig_t *config)
|
||||
{
|
||||
ASSERT(config);
|
||||
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
|
||||
if(gWdtDataBase.isInited == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
slpManRegisterPredefinedBackupCb(SLP_CALLBACK_WDT_MODULE, WDT_enterLowPowerStatePrepare, NULL);
|
||||
slpManRegisterPredefinedRestoreCb(SLP_CALLBACK_WDT_MODULE, WDT_exitLowPowerStateRestore, NULL);
|
||||
|
||||
gWdtDataBase.isInited = true;
|
||||
gWdtDataBase.wdtConfig = *config;
|
||||
|
||||
#endif
|
||||
|
||||
//enable clock
|
||||
CLOCK_clockEnable(PCLK_WDG);
|
||||
CLOCK_clockEnable(FCLK_WDG);
|
||||
|
||||
|
||||
WDT_unlock();
|
||||
WDT->CTRL = (WDT->CTRL &~ WDT_CTRL_MODE_Msk) | EIGEN_VAL2FLD(WDT_CTRL_MODE, config->mode);
|
||||
WDT_unlock();
|
||||
WDT->TOVR = config->timeoutValue;
|
||||
}
|
||||
|
||||
void WDT_deInit(void)
|
||||
{
|
||||
#ifdef PM_FEATURE_ENABLE
|
||||
|
||||
if(gWdtDataBase.isInited == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
slpManUnregisterPredefinedBackupCb(SLP_CALLBACK_WDT_MODULE);
|
||||
slpManUnregisterPredefinedRestoreCb(SLP_CALLBACK_WDT_MODULE);
|
||||
|
||||
gWdtDataBase.isInited = false;
|
||||
#endif
|
||||
|
||||
//disable clock
|
||||
CLOCK_clockDisable(PCLK_WDG);
|
||||
CLOCK_clockDisable(FCLK_WDG);
|
||||
|
||||
}
|
||||
|
||||
void WDT_start(void)
|
||||
{
|
||||
uint32_t mask = SaveAndSetIRQMask();
|
||||
|
||||
WDT_unlock();
|
||||
WDT->CTRL |= WDT_CTRL_ENABLE_Msk;
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
}
|
||||
|
||||
void WDT_stop(void)
|
||||
{
|
||||
uint32_t mask = SaveAndSetIRQMask();
|
||||
|
||||
WDT_unlock();
|
||||
WDT->CTRL &= ~WDT_CTRL_ENABLE_Msk;
|
||||
|
||||
RestoreIRQMask(mask);
|
||||
|
||||
}
|
||||
|
||||
uint32_t WDT_getInterruptFlags(void)
|
||||
{
|
||||
return WDT->STAT & WDT_STAT_ISTAT_Msk;
|
||||
}
|
||||
|
||||
void WDTclearInterruptFlags(uint32_t mask)
|
||||
{
|
||||
uint32_t msk = SaveAndSetIRQMask();
|
||||
|
||||
WDT_unlock();
|
||||
WDT->ICR = WDT_ICR_ICLR_Msk;
|
||||
|
||||
RestoreIRQMask(msk);
|
||||
}
|
||||
|
||||
WdtMode_e WDT_getMode(void)
|
||||
{
|
||||
return (WdtMode_e)EIGEN_FLD2VAL(WDT_CTRL_MODE, WDT->CTRL);
|
||||
}
|
||||
|
||||
bool WDT_getStartStatus(void)
|
||||
{
|
||||
return (bool)EIGEN_FLD2VAL(WDT_CTRL_ENABLE, WDT->CTRL);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,15 @@
|
||||
#include <stdbool.h>
|
||||
bool LPUSART_IsRxActive(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LPUSART_ClearStopFlag(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LPUSART_SetStopFlag(void)
|
||||
{
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright (c) 2013 ARM Ltd
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the company may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This memcpy routine is optimised for Cortex-M3/M4 cores with/without
|
||||
unaligned access.
|
||||
|
||||
If compiled with GCC, this file should be enclosed within following
|
||||
pre-processing check:
|
||||
if defined (__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
|
||||
|
||||
Prototype: void *memcpy (void *dst, const void *src, size_t count);
|
||||
|
||||
The job will be done in 5 steps.
|
||||
Step 1: Align src/dest pointers, copy mis-aligned if fail to align both
|
||||
Step 2: Repeatedly copy big block size of __OPT_BIG_BLOCK_SIZE
|
||||
Step 3: Repeatedly copy big block size of __OPT_MID_BLOCK_SIZE
|
||||
Step 4: Copy word by word
|
||||
Step 5: Copy byte-to-byte
|
||||
|
||||
Tunable options:
|
||||
__OPT_BIG_BLOCK_SIZE: Size of big block in words. Default to 64.
|
||||
__OPT_MID_BLOCK_SIZE: Size of big block in words. Default to 16.
|
||||
*/
|
||||
#ifndef __OPT_BIG_BLOCK_SIZE
|
||||
#define __OPT_BIG_BLOCK_SIZE (4 * 16)
|
||||
#endif
|
||||
|
||||
#ifndef __OPT_MID_BLOCK_SIZE
|
||||
#define __OPT_MID_BLOCK_SIZE (4 * 4)
|
||||
#endif
|
||||
|
||||
#if __OPT_BIG_BLOCK_SIZE == 16
|
||||
#define BEGIN_UNROLL_BIG_BLOCK \
|
||||
.irp offset, 0,4,8,12
|
||||
#elif __OPT_BIG_BLOCK_SIZE == 32
|
||||
#define BEGIN_UNROLL_BIG_BLOCK \
|
||||
.irp offset, 0,4,8,12,16,20,24,28
|
||||
#elif __OPT_BIG_BLOCK_SIZE == 64
|
||||
#define BEGIN_UNROLL_BIG_BLOCK \
|
||||
.irp offset, 0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60
|
||||
#else
|
||||
#error "Illegal __OPT_BIG_BLOCK_SIZE"
|
||||
#endif
|
||||
|
||||
#if __OPT_MID_BLOCK_SIZE == 8
|
||||
#define BEGIN_UNROLL_MID_BLOCK \
|
||||
.irp offset, 0,4
|
||||
#elif __OPT_MID_BLOCK_SIZE == 16
|
||||
#define BEGIN_UNROLL_MID_BLOCK \
|
||||
.irp offset, 0,4,8,12
|
||||
#else
|
||||
#error "Illegal __OPT_MID_BLOCK_SIZE"
|
||||
#endif
|
||||
|
||||
#define END_UNROLL .endr
|
||||
|
||||
.syntax unified
|
||||
.text
|
||||
.align 2
|
||||
.global memcpy
|
||||
.thumb
|
||||
.thumb_func
|
||||
.type memcpy, %function
|
||||
memcpy:
|
||||
@ r0: dst
|
||||
@ r1: src
|
||||
@ r2: len
|
||||
#ifdef __ARM_FEATURE_UNALIGNED
|
||||
/* In case of UNALIGNED access supported, ip is not used in
|
||||
function body. */
|
||||
mov ip, r0
|
||||
#else
|
||||
push {r0}
|
||||
#endif
|
||||
orr r3, r1, r0
|
||||
ands r3, r3, #3
|
||||
bne .Lmisaligned_copy
|
||||
|
||||
.Lbig_block:
|
||||
subs r2, __OPT_BIG_BLOCK_SIZE
|
||||
blo .Lmid_block
|
||||
|
||||
/* Kernel loop for big block copy */
|
||||
.align 2
|
||||
.Lbig_block_loop:
|
||||
BEGIN_UNROLL_BIG_BLOCK
|
||||
#ifdef __ARM_ARCH_7EM__
|
||||
ldr r3, [r1], #4
|
||||
str r3, [r0], #4
|
||||
END_UNROLL
|
||||
#else /* __ARM_ARCH_7M__ */
|
||||
ldr r3, [r1, \offset]
|
||||
str r3, [r0, \offset]
|
||||
END_UNROLL
|
||||
adds r0, __OPT_BIG_BLOCK_SIZE
|
||||
adds r1, __OPT_BIG_BLOCK_SIZE
|
||||
#endif
|
||||
subs r2, __OPT_BIG_BLOCK_SIZE
|
||||
bhs .Lbig_block_loop
|
||||
|
||||
.Lmid_block:
|
||||
adds r2, __OPT_BIG_BLOCK_SIZE - __OPT_MID_BLOCK_SIZE
|
||||
blo .Lcopy_word_by_word
|
||||
|
||||
/* Kernel loop for mid-block copy */
|
||||
.align 2
|
||||
.Lmid_block_loop:
|
||||
BEGIN_UNROLL_MID_BLOCK
|
||||
#ifdef __ARM_ARCH_7EM__
|
||||
ldr r3, [r1], #4
|
||||
str r3, [r0], #4
|
||||
END_UNROLL
|
||||
#else /* __ARM_ARCH_7M__ */
|
||||
ldr r3, [r1, \offset]
|
||||
str r3, [r0, \offset]
|
||||
END_UNROLL
|
||||
adds r0, __OPT_MID_BLOCK_SIZE
|
||||
adds r1, __OPT_MID_BLOCK_SIZE
|
||||
#endif
|
||||
subs r2, __OPT_MID_BLOCK_SIZE
|
||||
bhs .Lmid_block_loop
|
||||
|
||||
.Lcopy_word_by_word:
|
||||
adds r2, __OPT_MID_BLOCK_SIZE - 4
|
||||
blo .Lcopy_less_than_4
|
||||
|
||||
/* Kernel loop for small block copy */
|
||||
.align 2
|
||||
.Lcopy_word_by_word_loop:
|
||||
ldr r3, [r1], #4
|
||||
str r3, [r0], #4
|
||||
subs r2, #4
|
||||
bhs .Lcopy_word_by_word_loop
|
||||
|
||||
.Lcopy_less_than_4:
|
||||
adds r2, #4
|
||||
beq .Ldone
|
||||
|
||||
lsls r2, r2, #31
|
||||
itt ne
|
||||
ldrbne r3, [r1], #1
|
||||
strbne r3, [r0], #1
|
||||
|
||||
bcc .Ldone
|
||||
#ifdef __ARM_FEATURE_UNALIGNED
|
||||
ldrh r3, [r1]
|
||||
strh r3, [r0]
|
||||
#else
|
||||
ldrb r3, [r1]
|
||||
strb r3, [r0]
|
||||
ldrb r3, [r1, #1]
|
||||
strb r3, [r0, #1]
|
||||
#endif /* __ARM_FEATURE_UNALIGNED */
|
||||
|
||||
.Ldone:
|
||||
#ifdef __ARM_FEATURE_UNALIGNED
|
||||
mov r0, ip
|
||||
#else
|
||||
pop {r0}
|
||||
#endif
|
||||
bx lr
|
||||
|
||||
.align 2
|
||||
.Lmisaligned_copy:
|
||||
#ifdef __ARM_FEATURE_UNALIGNED
|
||||
/* Define label DST_ALIGNED to BIG_BLOCK. It will go to aligned copy
|
||||
once destination is adjusted to aligned. */
|
||||
#define Ldst_aligned Lbig_block
|
||||
|
||||
/* Copy word by word using LDR when alignment can be done in hardware,
|
||||
i.e., SCTLR.A is set, supporting unaligned access in LDR and STR. */
|
||||
|
||||
cmp r2, #8
|
||||
blo .Lbyte_copy
|
||||
|
||||
/* if src is aligned, just go to the big block loop. */
|
||||
lsls r3, r1, #30
|
||||
beq .Ldst_aligned
|
||||
#else
|
||||
/* if len < 12, misalignment adjustment has more overhead than
|
||||
just byte-to-byte copy. Also, len must >=8 to guarantee code
|
||||
afterward work correctly. */
|
||||
cmp r2, #12
|
||||
blo .Lbyte_copy
|
||||
#endif /* __ARM_FEATURE_UNALIGNED */
|
||||
|
||||
/* Align dst only, not trying to align src. That is the because
|
||||
handling of aligned src and misaligned dst need more overhead than
|
||||
otherwise. By doing this the worst case is when initial src is aligned,
|
||||
additional up to 4 byte additional copy will executed, which is
|
||||
acceptable. */
|
||||
|
||||
ands r3, r0, #3
|
||||
beq .Ldst_aligned
|
||||
|
||||
rsb r3, #4
|
||||
subs r2, r3
|
||||
|
||||
lsls r3, r3, #31
|
||||
itt ne
|
||||
ldrbne r3, [r1], #1
|
||||
strbne r3, [r0], #1
|
||||
|
||||
bcc .Ldst_aligned
|
||||
|
||||
#ifdef __ARM_FEATURE_UNALIGNED
|
||||
ldrh r3, [r1], #2
|
||||
strh r3, [r0], #2
|
||||
b .Ldst_aligned
|
||||
#else
|
||||
ldrb r3, [r1], #1
|
||||
strb r3, [r0], #1
|
||||
ldrb r3, [r1], #1
|
||||
strb r3, [r0], #1
|
||||
/* Now that dst is aligned */
|
||||
.Ldst_aligned:
|
||||
/* if r1 is aligned now, it means r0/r1 has the same misalignment,
|
||||
and they are both aligned now. Go aligned copy. */
|
||||
ands r3, r1, #3
|
||||
beq .Lbig_block
|
||||
|
||||
/* dst is aligned, but src isn't. Misaligned copy. */
|
||||
|
||||
push {r4, r5}
|
||||
subs r2, #4
|
||||
|
||||
/* Backward r1 by misaligned bytes, to make r1 aligned.
|
||||
Since we need to restore r1 to unaligned address after the loop,
|
||||
we need keep the offset bytes to ip and sub it from r1 afterward. */
|
||||
subs r1, r3
|
||||
rsb ip, r3, #4
|
||||
|
||||
/* Pre-load on word */
|
||||
ldr r4, [r1], #4
|
||||
|
||||
cmp r3, #2
|
||||
beq .Lmisaligned_copy_2_2
|
||||
cmp r3, #3
|
||||
beq .Lmisaligned_copy_3_1
|
||||
|
||||
.macro mis_src_copy shift
|
||||
1:
|
||||
#ifdef __ARM_BIG_ENDIAN
|
||||
lsls r4, r4, \shift
|
||||
#else
|
||||
lsrs r4, r4, \shift
|
||||
#endif
|
||||
ldr r3, [r1], #4
|
||||
#ifdef __ARM_BIG_ENDIAN
|
||||
lsrs r5, r3, 32-\shift
|
||||
#else
|
||||
lsls r5, r3, 32-\shift
|
||||
#endif
|
||||
orr r4, r4, r5
|
||||
str r4, [r0], #4
|
||||
mov r4, r3
|
||||
subs r2, #4
|
||||
bhs 1b
|
||||
.endm
|
||||
|
||||
.Lmisaligned_copy_1_3:
|
||||
mis_src_copy shift=8
|
||||
b .Lsrc_misaligned_tail
|
||||
|
||||
.Lmisaligned_copy_3_1:
|
||||
mis_src_copy shift=24
|
||||
b .Lsrc_misaligned_tail
|
||||
|
||||
.Lmisaligned_copy_2_2:
|
||||
/* For 2_2 misalignment, ldr is still faster than 2 x ldrh. */
|
||||
mis_src_copy shift=16
|
||||
|
||||
.Lsrc_misaligned_tail:
|
||||
adds r2, #4
|
||||
subs r1, ip
|
||||
pop {r4, r5}
|
||||
|
||||
#endif /* __ARM_FEATURE_UNALIGNED */
|
||||
|
||||
.Lbyte_copy:
|
||||
subs r2, #4
|
||||
blo .Lcopy_less_than_4
|
||||
|
||||
.Lbyte_copy_loop:
|
||||
subs r2, #1
|
||||
ldrb r3, [r1], #1
|
||||
strb r3, [r0], #1
|
||||
bhs .Lbyte_copy_loop
|
||||
|
||||
ldrb r3, [r1]
|
||||
strb r3, [r0]
|
||||
ldrb r3, [r1, #1]
|
||||
strb r3, [r0, #1]
|
||||
ldrb r3, [r1, #2]
|
||||
strb r3, [r0, #2]
|
||||
|
||||
#ifdef __ARM_FEATURE_UNALIGNED
|
||||
mov r0, ip
|
||||
#else
|
||||
pop {r0}
|
||||
#endif
|
||||
bx lr
|
||||
|
||||
.size memcpy, .-memcpy
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user