Introduce a port for T-HEAD CK802. A simple demo for T-HEAD CB2201 is also included.

This commit is contained in:
Yuhui.Zheng 2020-01-10 07:53:14 +00:00
parent d2914041f8
commit 0d95aca202
125 changed files with 23809 additions and 0 deletions

View file

@ -0,0 +1,7 @@
if CONFIG_CSKY
source "../../csi/csi_driver/csky/Kconfig"
endif
if CONFIG_SANECHIPS
source "../../csi/csi_driver/sanechips/Kconfig"
endif

View file

@ -0,0 +1,9 @@
TEE_INC += -I$(CSI_DIR)/csi_driver/include
ifeq ($(CONFIG_CSKY), y)
include $(CSI_DIR)/csi_driver/csky/csi.mk
endif
ifeq ($(CONFIG_SANECHIPS), y)
include $(CSI_DIR)/csi_driver/sanechips/csi.mk
endif

View file

@ -0,0 +1,9 @@
source "../../csi/csi_driver/csky/common/Kconfig"
if CONFIG_PLATFORM_PHOBOS
source "../../csi/csi_driver/csky/phobos/Kconfig"
endif
if CONFIG_PLATFORM_HOBBIT1_2
source "../../csi/csi_driver/csky/hobbit1_2/Kconfig"
endif

View file

@ -0,0 +1 @@
v1.0

View file

@ -0,0 +1,525 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_aes.c
* @brief CSI Source File for aes driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <string.h>
#include "csi_core.h"
#include "drv_aes.h"
#include "ck_aes.h"
#define ERR_AES(errno) (CSI_DRV_ERRNO_AES_BASE | errno)
#define AES_NULL_PARA_CHK(para) \
do { \
if (para == NULL) { \
return ERR_AES(EDRV_PARAMETER); \
} \
} while (0)
static ck_aes_reg_t *aes_reg = NULL;
volatile static uint8_t block_cal_done = 0;
typedef struct {
uint32_t base;
uint32_t irq;
void *iv;
uint8_t *result_out;
uint32_t len;
aes_event_cb_t cb;
aes_mode_e mode;
aes_key_len_bits_e keylen;
aes_endian_mode_e endian;
aes_crypto_mode_e enc;
aes_status_t status;
} ck_aes_priv_t;
extern int32_t target_get_aes_count(void);
extern int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq);
static ck_aes_priv_t aes_handle[CONFIG_AES_NUM];
/* Driver Capabilities */
static const aes_capabilities_t driver_capabilities = {
.ecb_mode = 1, /* ECB mode */
.cbc_mode = 1, /* CBC mode */
.cfb_mode = 0, /* CFB mode */
.ofb_mode = 0, /* OFB mode */
.ctr_mode = 0, /* CTR mode */
.bits_128 = 1, /* 128bits key length mode */
.bits_192 = 1, /* 192bits key lenght mode */
.bits_256 = 1 /* 256bits key length mode */
};
extern int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq);
extern int32_t target_get_aes_count(void);
//
// Functions
//
static inline void aes_set_opcode(aes_crypto_mode_e opcode)
{
aes_reg->ctrl &= ~(3 << AES_OPCODE_OFFSET); //clear bit[7:6]
aes_reg->ctrl |= (opcode << AES_OPCODE_OFFSET); //set opcode
}
static inline void aes_set_endian(aes_endian_mode_e endian)
{
if (endian == AES_ENDIAN_LITTLE) {
aes_reg->ctrl &= ~AES_LITTLE_ENDIAN;
} else {
aes_reg->ctrl |= AES_LITTLE_ENDIAN;
}
}
static inline uint32_t aes_set_keylen(aes_key_len_bits_e keylength)
{
aes_reg->ctrl &= ~(3 << AES_KEY_LEN_OFFSET); //clear bit[5:4]
aes_reg->ctrl |= (keylength << AES_KEY_LEN_OFFSET);// Set key length
return 0;
}
static inline void aes_set_mode(aes_mode_e mode)
{
aes_reg->ctrl &= ~(1 << AES_MODE_OFFSET); //clear bit 3
aes_reg->ctrl |= (mode << AES_MODE_OFFSET); //set mode
}
static inline void aes_enable(void)
{
aes_reg->ctrl |= (1 << AES_WORK_ENABLE_OFFSET);
}
static inline void aes_disable(void)
{
aes_reg->ctrl &= ~(1 << AES_WORK_ENABLE_OFFSET);
}
static inline void aes_enable_interrupt(void)
{
aes_reg->ctrl |= (1 << AES_INT_ENABLE_OFFSET);
}
static inline void aes_disable_interrupt(void)
{
aes_reg->ctrl &= ~(1 << AES_INT_ENABLE_OFFSET);
}
static inline void aes_clear_interrupt(void)
{
aes_reg->state = 0x0;
}
static inline uint32_t aes_get_intstatus(uint32_t AES_IT)
{
return (aes_reg->state & AES_IT) ? 1 : 0;
}
static void aes_set_key(void *context, uint8_t *key, aes_key_len_bits_e keylen, uint32_t enc, uint32_t endian)
{
uint8_t keynum = 0;
if (keylen == AES_KEY_LEN_BITS_128) {
keynum = 4;
} else if (keylen == AES_KEY_LEN_BITS_192) {
keynum = 6;
} else if (keylen == AES_KEY_LEN_BITS_256) {
keynum = 8;
}
uint32_t i;
uint32_t temp = 0;
/* set key according to the endian mode */
if (endian == AES_ENDIAN_LITTLE) {
for (i = 0; i < keynum; i++) {
temp = key[3] << 24 | key[2] << 16 | key[1] << 8 | key[0];
aes_reg->key[keynum - 1 - i] = temp;
key += 4;
}
} else if (endian == AES_ENDIAN_BIG) {
for (i = 0; i < keynum; i++) {
temp = key[3] << 24 | key[2] << 16 | key[1] << 8 | key[0];
aes_reg->key[i] = temp;
key += 4;
}
}
if (enc == AES_CRYPTO_MODE_DECRYPT) {
aes_set_opcode(AES_CRYPTO_KEYEXP); /* if the mode is decrypt before decrypt you have to keyexpand */
aes_enable();
// while(block_cal_done == 0);
// block_cal_done = 0;
while (aes_get_intstatus(AES_IT_KEYINT));
aes_set_opcode(AES_CRYPTO_MODE_DECRYPT);
} else if (enc == AES_CRYPTO_MODE_ENCRYPT) {
aes_set_opcode(AES_CRYPTO_MODE_ENCRYPT);
}
aes_disable();
}
static void aes_set_iv(uint32_t mode, uint32_t endian, uint8_t *iv)
{
uint32_t temp;
uint32_t i;
/* set iv if the mode is CBC */
if (mode == AES_MODE_CBC) {
if (endian == AES_ENDIAN_BIG) {
for (i = 0; i < 4; i++) {
temp = iv[3] << 24 | iv[2] << 16 | iv[1] << 8 | iv[0];
aes_reg->iv[i] = temp;
iv += 4;
}
} else if (endian == AES_ENDIAN_LITTLE) {
for (i = 0; i < 4; i++) {
temp = iv[3] << 24 | iv[2] << 16 | iv[1] << 8 | iv[0];
aes_reg->iv[3 - i] = temp;
iv += 4;
}
}
}
}
static int aes_crypto(void *context, uint8_t *in, uint8_t *out,
uint32_t len, uint8_t *iv, uint32_t mode, uint32_t endian, uint32_t enc)
{
uint32_t temp[4];
aes_set_iv(mode, endian, iv);
uint32_t i = 0;
uint32_t j = 0;
/* set the text before aes calculating */
for (i = 0; i < len; i = i + 16) {
for (j = 0; j < 4; j++) {
temp[j] = in[3] << 24 | in[2] << 16 | in[1] << 8 | in[0];
if (endian == AES_ENDIAN_BIG) {
aes_reg->datain[j] = temp[j];
} else if (endian == AES_ENDIAN_LITTLE) {
aes_reg->datain[3 - j] = temp[j];
}
in += 4;
}
aes_enable();
while(block_cal_done == 0);
block_cal_done = 0;
if (enc == AES_CRYPTO_MODE_ENCRYPT && mode == AES_MODE_CBC) {
aes_set_iv(mode, endian, out);
memcpy(iv, out, 16);
out += 16;
} else if (enc == AES_CRYPTO_MODE_DECRYPT && mode == AES_MODE_CBC) {
aes_set_iv(mode, endian, (uint8_t *)&temp);
memcpy(iv, temp, 16);
}
}
return 0;
}
void ck_aes_irqhandler(int32_t idx)
{
ck_aes_priv_t *aes_priv = &aes_handle[idx];
volatile uint32_t j;
uint32_t tmp = 0;
/* get the result after aes calculating*/
if (aes_priv->result_out != NULL) {
for (j = 0; j < 4; j++) {
if (aes_priv->endian == AES_ENDIAN_BIG) {
tmp = aes_reg->dataout[j];
} else if (aes_priv->endian == AES_ENDIAN_LITTLE) {
tmp = aes_reg->dataout[3 - j];
}
memcpy(aes_priv->result_out, &tmp, 4);
aes_priv->result_out += 4;
aes_priv->len -= 4;
}
}
block_cal_done = 1;
/* disable aes and clear the aes interrupt */
aes_disable();
aes_clear_interrupt();
/* execute the callback function */
if (aes_priv->len == 0) {
if (aes_priv->cb) {
aes_priv->cb(AES_EVENT_CRYPTO_COMPLETE);
}
}
}
/**
\brief get aes instance count.
\return aes handle count
*/
int32_t csi_aes_get_instance_count(void)
{
return target_get_aes_count();
}
/**
\brief Initialize AES Interface. 1. Initializes the resources needed for the AES interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_aes_get_instance_count().
\param[in] cb_event Pointer to \ref aes_event_cb_t
\return return aes handle if success
*/
aes_handle_t csi_aes_initialize(int32_t idx, aes_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_AES_NUM) {
return NULL;
}
uint32_t irq = 0u;
uint32_t base = 0u;
/* obtain the aes information */
int32_t real_idx = target_get_aes(idx, &base, &irq);
if (real_idx != idx) {
return NULL;
}
ck_aes_priv_t *aes_priv = &aes_handle[idx];
aes_priv->base = base;
aes_priv->irq = irq;
/* initialize the aes context */
aes_reg = (ck_aes_reg_t *)(aes_priv->base);
aes_priv->cb = cb_event;
aes_priv->iv = NULL;
aes_priv->len = 16;
aes_priv->result_out = NULL;
aes_priv->mode = AES_MODE_CBC;
aes_priv->keylen = AES_KEY_LEN_BITS_128;
aes_priv->endian = AES_ENDIAN_LITTLE;
aes_priv->status.busy = 0;
aes_enable_interrupt(); /* enable the aes interrupt */
drv_nvic_enable_irq(aes_priv->irq); /* enable the aes bit in nvic */
return (aes_handle_t)aes_priv;
}
/**
\brief De-initialize AES Interface. stops operation and releases the software resources used by the interface
\param[in] handle aes handle to operate.
\return error code
*/
int32_t csi_aes_uninitialize(aes_handle_t handle)
{
AES_NULL_PARA_CHK(handle);
ck_aes_priv_t *aes_priv = handle;
aes_priv->cb = NULL;
aes_disable_interrupt(); /* disable the aes interrupt */
drv_nvic_disable_irq(aes_priv->irq);
return 0;
}
/**
\brief Get driver capabilities.
\param[in] handle aes handle to operate.
\return \ref aes_capabilities_t
*/
aes_capabilities_t csi_aes_get_capabilities(aes_handle_t handle)
{
return driver_capabilities;
}
/**
\brief config aes mode.
\param[in] handle aes handle to operate.
\param[in] mode \ref aes_mode_e
\param[in] keylen_bits \ref aes_key_len_bits_e
\param[in] endian \ref aes_endian_mode_e
\param[in] arg Pointer to the iv address when mode is cbc_mode
\return error code
*/
int32_t csi_aes_config(aes_handle_t handle, aes_mode_e mode, aes_key_len_bits_e keylen_bits, aes_endian_mode_e endian, uint32_t arg)
{
AES_NULL_PARA_CHK(handle);
ck_aes_priv_t *aes_priv = handle;
aes_reg = (ck_aes_reg_t *)(aes_priv->base);
/* config the aes mode */
switch (mode) {
case AES_MODE_CBC:
aes_priv->iv = (void *)arg;
aes_priv->mode = mode;
aes_set_mode(mode);
break;
case AES_MODE_ECB:
aes_priv->mode = mode;
aes_set_mode(mode);
break;
case AES_MODE_CFB:
case AES_MODE_OFB:
case AES_MODE_CTR:
return ERR_AES(EDRV_UNSUPPORTED);
default:
return ERR_AES(EDRV_PARAMETER);
}
/* config the key length */
switch (keylen_bits) {
case AES_KEY_LEN_BITS_128:
case AES_KEY_LEN_BITS_192:
case AES_KEY_LEN_BITS_256:
aes_priv->keylen = keylen_bits;
aes_set_keylen(keylen_bits);
break;
default:
return ERR_AES(EDRV_PARAMETER);
}
/* config the endian mode */
switch (endian) {
case AES_ENDIAN_LITTLE:
aes_priv->endian = endian;
aes_set_endian(endian);
break;
case AES_ENDIAN_BIG:
aes_priv->endian = endian;
aes_set_endian(endian);
break;
default:
return ERR_AES(EDRV_PARAMETER);
}
return 0;
}
/**
\brief set crypto key.
\param[in] handle aes handle to operate.
\param[in] context aes information context(NULL when hardware implementation)
\param[in] key Pointer to the key buf
\param[in] key_len Pointer to the aes_key_len_bits_e
\param[in] enc \ref aes_crypto_mode_e
\return error code
*/
int32_t csi_aes_set_key(aes_handle_t handle, void *context, void *key, aes_key_len_bits_e key_len, aes_crypto_mode_e enc)
{
AES_NULL_PARA_CHK(handle);
AES_NULL_PARA_CHK(key);
if ((key_len != AES_KEY_LEN_BITS_128 &&
key_len != AES_KEY_LEN_BITS_192 &&
key_len != AES_KEY_LEN_BITS_256) ||
(enc != AES_CRYPTO_MODE_ENCRYPT &&
enc != AES_CRYPTO_MODE_DECRYPT)) {
return ERR_AES(EDRV_PARAMETER);
}
ck_aes_priv_t *aes_priv = handle;
aes_priv->enc = enc;
aes_set_key(context, key, key_len, enc, aes_priv->endian);
return 0;
}
/**
\brief encrypt or decrypt
\param[in] handle aes handle to operate.
\param[in] context aes information context(NULL when hardware implementation)
\param[in] in Pointer to the Source data
\param[out] out Pointer to the Result data.
\param[in] len the Source data len.
\param[in] padding \ref aes_padding_mode_e.
\return error code
*/
int32_t csi_aes_crypto(aes_handle_t handle, void *context, void *in, void *out, uint32_t len, aes_padding_mode_e padding)
{
AES_NULL_PARA_CHK(handle);
AES_NULL_PARA_CHK(in);
AES_NULL_PARA_CHK(out);
AES_NULL_PARA_CHK(len);
ck_aes_priv_t *aes_priv = handle;
aes_priv->status.busy = 1;
uint8_t left_len = len & 0xf;
switch (padding) {
case AES_PADDING_MODE_NO:
if (left_len) {
return ERR_AES(EDRV_PARAMETER);
}
/* crypto in padding no mode */
aes_priv->result_out = out;
aes_priv->len = len;
aes_crypto(context, in, out, len, aes_priv->iv, aes_priv->mode, aes_priv->endian, aes_priv->enc);
break;
case AES_PADDING_MODE_ZERO:
if (left_len == 0) {
return ERR_AES(EDRV_PARAMETER);
}
uint8_t i = 0;
for (i = 0; i < (16 - left_len); i++) {
*((uint8_t *)in + len + i) = 0x0;
}
/* crypto in padding zero mode */
aes_priv->result_out = out;
aes_priv->len = len + 16 -left_len;
aes_crypto(context, in, out, len + 16 - left_len, aes_priv->iv, aes_priv->mode, aes_priv->endian, aes_priv->enc);
break;
case AES_PADDING_MODE_PKCS5:
return ERR_AES(EDRV_UNSUPPORTED);
default:
return ERR_AES(EDRV_PARAMETER);
}
aes_priv->status.busy = 0;
return 0;
}
/**
\brief Get AES status.
\param[in] handle aes handle to operate.
\return AES status \ref aes_status_t
*/
aes_status_t csi_aes_get_status(aes_handle_t handle)
{
ck_aes_priv_t *aes_priv = handle;
return aes_priv->status;
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_aes.h
* @brief header file for aes driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CK_AES_H_
#define _CK_AES_H_
#include <stdio.h>
#include "drv_aes.h"
#include "soc.h"
#define AES_LITTLE_ENDIAN 0x00000100
#define AES_MAX_KEY_LENGTH 32
#define AES_IT_DATAINT 0x4
#define AES_IT_KEYINT 0x2
#define AES_IT_BUSY 0x1
#define AES_IT_ALL 0x7
#define AES_CRYPTO_KEYEXP 0x2
#define AES_WORK_ENABLE_OFFSET 0
#define AES_INT_ENABLE_OFFSET 2
#define AES_MODE_OFFSET 3
#define AES_KEY_LEN_OFFSET 4
#define AES_OPCODE_OFFSET 6
typedef struct {
__IOM uint32_t datain[4]; /* Offset: 0x000 (R/W) Data input 0~127 */
__IOM uint32_t key[8]; /* Offset: 0x010 (R/W) Key 0~255 */
__IOM uint32_t iv[4]; /* Offset: 0x030 (R/W) Initial Vector: 0~127 */
__IOM uint32_t ctrl; /* Offset: 0x040 (R/W) AES Control Register */
__IOM uint32_t state; /* Offset: 0x044 (R/W) AES State Register */
__IOM uint32_t dataout[4]; /* Offset: 0x048 (R/W) Data Output 0~31 */
} ck_aes_reg_t;
#endif

View file

@ -0,0 +1,52 @@
ifeq ($(CONFIG_SHA), y)
TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/sha/
ifeq ($(CONFIG_PLATFORM_PHOBOS), y)
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/sha/ck_sha_v2.c
endif
ifeq ($(CONFIG_PLATFORM_HOBBIT3), y)
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/sha/ck_sha_v2.c
endif
ifeq ($(CONFIG_PLATFORM_HOBBIT1_2), y)
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/sha/ck_sha_v1.c
endif
endif
ifeq ($(CONFIG_TRNG), y)
ifeq ($(CONFIG_PLATFORM_HOBBIT3), y)
TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/trng/
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/trng/osr_trng.c
endif
ifeq ($(CONFIG_PLATFORM_PHOBOS), y)
TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/trng/
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/trng/ck_trng.c
endif
ifeq ($(CONFIG_PLATFORM_HOBBIT1_2), y)
TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/trng/
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/trng/ck_trng.c
endif
endif
ifeq ($(CONFIG_AES), y)
TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/aes/
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/aes/ck_aes.c
endif
ifeq ($(CONFIG_RSA), y)
TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/rsa/
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/rsa/ck_rsa.c
endif
ifeq ($(CONFIG_USART), y)
TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/usart/
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/usart/dw_usart.c
endif
ifeq ($(CONFIG_PMU), y)
TEE_INC += -I$(CSI_DIR)/csi_driver/csky/common/pmu/
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/pmu/ck_pmu.c
endif
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/wdt/dw_wdt.c
TEE_SRC += $(CSI_DIR)/csi_driver/csky/common/eflash/ck_eflash.c

View file

@ -0,0 +1,441 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_eflash.c
* @brief CSI Source File for Embedded Flash Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include "csi_core.h"
#include "drv_eflash.h"
#include "ck_eflash.h"
#define ERR_EFLASH(errno) (CSI_DRV_ERRNO_EFLASH_BASE | errno)
#define EFLASH_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_EFLASH(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
eflash_info_t eflashinfo;
eflash_event_cb_t cb;
eflash_status_t status;
} ck_eflash_priv_t;
extern int32_t target_get_eflash_count(void);
extern int32_t target_get_eflash(int32_t idx, uint32_t *base, eflash_info_t *info);
static ck_eflash_priv_t eflash_handle[CONFIG_EFLASH_NUM];
/* Driver Capabilities */
static const eflash_capabilities_t driver_capabilities = {
.event_ready = 1, /* event_ready */
.data_width = 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
.erase_chip = 0 /* erase_chip */
};
//
// Functions
//
static int32_t eflash_program_word(eflash_handle_t handle, uint32_t dstaddr, uint32_t *srcbuf, uint32_t len)
{
ck_eflash_priv_t *eflash_priv = handle;
uint32_t fbase = eflash_priv->base;
uint32_t i;
for (i = 0; i < len; i++) {
*(volatile uint32_t *)(fbase + 0x04) = dstaddr;
*(volatile uint32_t *)(fbase + 0x1c) = *srcbuf;
*(volatile uint32_t *)(fbase + 0x18) = 1;
srcbuf++;
dstaddr += 4;
}
return (i << 2);
}
#ifdef CONFIG_CHIP_CH2201
static uint32_t context[EFLASH_SECTOR_SIZE >> 2] = {0x0};
static int32_t eflash_verify(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt)
{
uint32_t i;
uint8_t error_flag = 1;
uint8_t *block_addr = (uint8_t *)(addr & ~(EFLASH_SECTOR_SIZE - 1));
uint32_t pre_offset = addr - (uint32_t)block_addr;
uint32_t pre_count = (cnt > (EFLASH_SECTOR_SIZE - pre_offset)) ? (EFLASH_SECTOR_SIZE - pre_offset) : cnt;
uint8_t *p = NULL;
uint8_t *dst = NULL;
p = (uint8_t *)data;
dst = (uint8_t *)addr;
uint32_t len = cnt;
volatile uint8_t verify_count = 100;
while (error_flag) {
for (i = 0; i < pre_count; i++) {
if (*((uint8_t *)dst + i) != *((uint8_t *)p + i)) {
*(volatile uint32_t *) 0x50004000 = 'E'; /* for debug */
*(volatile uint32_t *) 0x50004000 = 'E';
*(volatile uint32_t *) 0x50004000 = 'E';
*(volatile uint32_t *) 0x50004000 = 'E';
*(volatile uint32_t *) 0x50004000 = '\n';
memcpy(context, block_addr, EFLASH_SECTOR_SIZE);
memcpy((uint8_t *)context + pre_offset, p, pre_count);
csi_eflash_erase_sector(handle, (uint32_t)dst);
eflash_program_word(handle, (uint32_t)block_addr, context, EFLASH_SECTOR_SIZE >> 2);
break;
}
}
if (i == pre_count || !(verify_count--)) {
error_flag = 0;
}
}
if (!verify_count) {
return ERR_EFLASH(EDRV_TIMEOUT);
}
verify_count = 100;
error_flag = 1;
p += pre_count;
dst += pre_count;
len -= pre_count;
while (len >= EFLASH_SECTOR_SIZE) {
while (error_flag) {
for (i = 0; i < EFLASH_SECTOR_SIZE; i++) {
if (*((uint8_t *)dst + i) != *((uint8_t *)p + i)) {
*(volatile uint32_t *) 0x50004000 = 'E'; /* for debug */
*(volatile uint32_t *) 0x50004000 = 'E';
*(volatile uint32_t *) 0x50004000 = 'E';
*(volatile uint32_t *) 0x50004000 = 'E';
*(volatile uint32_t *) 0x50004000 = '\n';
memcpy((uint8_t *)context, p, EFLASH_SECTOR_SIZE);
csi_eflash_erase_sector(handle, (uint32_t)dst);
eflash_program_word(handle, (uint32_t)dst, context, EFLASH_SECTOR_SIZE >> 2);
break;
}
}
if (i == EFLASH_SECTOR_SIZE || !(verify_count--)) {
error_flag = 0;
}
}
if (!verify_count) {
return ERR_EFLASH(EDRV_TIMEOUT);
}
verify_count = 100;
error_flag = 1;
dst += EFLASH_SECTOR_SIZE;
p += EFLASH_SECTOR_SIZE;
len -= EFLASH_SECTOR_SIZE;
}
if (len > 0) {
while (error_flag) {
for (i = 0; i < len; i++) {
if (*((uint8_t *)dst + i) != *((uint8_t *)p + i)) {
*(volatile uint32_t *) 0x50004000 = 'E'; /* for debug */
*(volatile uint32_t *) 0x50004000 = 'E';
*(volatile uint32_t *) 0x50004000 = 'E';
*(volatile uint32_t *) 0x50004000 = 'E';
*(volatile uint32_t *) 0x50004000 = '\n';
memcpy(context, dst, EFLASH_SECTOR_SIZE);
memcpy((uint8_t *)context + i, p + i, len - i);
csi_eflash_erase_sector(handle, (uint32_t)dst);
eflash_program_word(handle, (uint32_t)dst, context, EFLASH_SECTOR_SIZE >> 2);
break;
}
}
if (i == len || !(verify_count--)) {
error_flag = 0;
}
}
if (!verify_count) {
return ERR_EFLASH(EDRV_TIMEOUT);
}
verify_count = 100;
}
return 0;
}
#endif
/**
\brief Initialize EFLASH Interface. 1. Initializes the resources needed for the EFLASH interface 2.registers event callback function
\param[in] idx device id
\param[in] cb_event Pointer to \ref eflash_event_cb_t
\return pointer to eflash handle
*/
eflash_handle_t csi_eflash_initialize(int32_t idx, eflash_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_EFLASH_NUM) {
return NULL;
}
/* obtain the eflash information */
uint32_t base = 0u;
eflash_info_t info;
int32_t real_idx = target_get_eflash(idx, &base, &info);
if (real_idx != idx) {
return NULL;
}
ck_eflash_priv_t *eflash_priv = &eflash_handle[idx];
eflash_priv->base = base;
eflash_priv->eflashinfo.start = info.start;
eflash_priv->eflashinfo.end = info.end;
eflash_priv->eflashinfo.sector_count = info.sector_count;
/* initialize the eflash context */
eflash_priv->cb = cb_event;
eflash_priv->status.busy = 0;
eflash_priv->status.error = 0U;
eflash_priv->eflashinfo.sector_size = EFLASH_SECTOR_SIZE;
eflash_priv->eflashinfo.page_size = EFLASH_PAGE_SIZE;
eflash_priv->eflashinfo.program_unit = EFLASH_PROGRAM_UINT;
eflash_priv->eflashinfo.erased_value = EFLASH_ERASED_VALUE;
return (eflash_handle_t)eflash_priv;
}
/**
\brief De-initialize EFLASH Interface. stops operation and releases the software resources used by the interface
\param[in] handle eflash handle to operate.
\return error code
*/
int32_t csi_eflash_uninitialize(eflash_handle_t handle)
{
EFLASH_NULL_PARAM_CHK(handle);
ck_eflash_priv_t *eflash_priv = handle;
eflash_priv->cb = NULL;
return 0;
}
/**
\brief Get driver capabilities.
\param[in] idx device id
\return \ref eflash_capabilities_t
*/
eflash_capabilities_t csi_eflash_get_capabilities(eflash_handle_t handle)
{
return driver_capabilities;
}
/**
\brief Read data from Flash.
\param[in] handle eflash handle to operate.
\param[in] addr Data address.
\param[out] data Pointer to a buffer storing the data read from Flash.
\param[in] cnt Number of data items to read.
\return number of data items read or error code
*/
int32_t csi_eflash_read(eflash_handle_t handle, uint32_t addr, void *data, uint32_t cnt)
{
EFLASH_NULL_PARAM_CHK(handle);
EFLASH_NULL_PARAM_CHK(data);
EFLASH_NULL_PARAM_CHK(cnt);
volatile uint8_t *src_addr = (uint8_t *)addr;
ck_eflash_priv_t *eflash_priv = handle;
if (eflash_priv->eflashinfo.start > addr || eflash_priv->eflashinfo.end < addr || eflash_priv->eflashinfo.start > (addr + cnt - 1) || eflash_priv->eflashinfo.end < (addr + cnt - 1)) {
return ERR_EFLASH(EDRV_PARAMETER);
}
if (eflash_priv->status.busy) {
return ERR_EFLASH(EDRV_BUSY);
}
eflash_priv->status.error = 0U;
int i;
for (i = 0; i < cnt; i++) {
*((uint8_t *)data + i) = *(src_addr + i);
}
return i;
}
/**
\brief Program data to Flash.
\param[in] handle eflash handle to operate.
\param[in] addr Data address.
\param[in] data Pointer to a buffer containing the data to be programmed to Flash..
\param[in] cnt Number of data items to program.
\return number of data items programmed or error code
*/
int32_t csi_eflash_program(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt)
{
EFLASH_NULL_PARAM_CHK(handle);
EFLASH_NULL_PARAM_CHK(data);
EFLASH_NULL_PARAM_CHK(cnt);
ck_eflash_priv_t *eflash_priv = handle;
if (eflash_priv->eflashinfo.start > addr || eflash_priv->eflashinfo.end < addr || eflash_priv->eflashinfo.start > (addr + cnt - 1) || eflash_priv->eflashinfo.end < (addr + cnt - 1)) {
return ERR_EFLASH(EDRV_PARAMETER);
}
uint32_t cur = 0;
uint32_t pad_buf;
if (addr & 0x3) {
return ERR_EFLASH(EDRV_PARAMETER);
}
if (eflash_priv->status.busy) {
return ERR_EFLASH(EDRV_BUSY);
}
eflash_priv->status.busy = 1U;
eflash_priv->status.error = 0U;
if (((uint32_t)data & 0x3) == 0) {
cur = cnt - (cnt & 0x3);
eflash_program_word(handle, addr, (uint32_t *)data, cur >> 2);
} else {
uint8_t *buffer_b = (uint8_t *)data;
for (; cur < cnt - 3; cur += 4, buffer_b += 4) {
pad_buf = buffer_b[0] | (buffer_b[1] << 8) | (buffer_b[2] << 16) | (buffer_b[3] << 24);
eflash_program_word(handle, addr + cur, &pad_buf, 1);
}
}
if (cur < cnt) {
pad_buf = *((volatile uint32_t *)(addr + cur));
uint8_t *pad = (uint8_t *)&pad_buf;
uint8_t *buff = (uint8_t *)data;
uint8_t i;
for (i = 0; i < (cnt - cur); i++) {
pad[i] = buff[cur + i];
}
eflash_program_word(handle, addr + cur, &pad_buf, 1);
}
eflash_priv->status.busy = 0U;
#ifdef CONFIG_CHIP_CH2201
eflash_verify(handle, addr, data, cnt);
#endif
return cnt;
}
/**
\brief Erase Flash Sector.
\param[in] handle eflash handle to operate.
\param[in] addr Sector address
\return error code
*/
int32_t csi_eflash_erase_sector(eflash_handle_t handle, uint32_t addr)
{
EFLASH_NULL_PARAM_CHK(handle);
ck_eflash_priv_t *eflash_priv = handle;
if (eflash_priv->eflashinfo.start > addr || eflash_priv->eflashinfo.end < addr) {
return ERR_EFLASH(EDRV_PARAMETER);
}
addr = addr & ~(EFLASH_SECTOR_SIZE - 1);
uint32_t fbase = eflash_priv->base;
if (eflash_priv->status.busy) {
return ERR_EFLASH(EDRV_BUSY);
}
eflash_priv->status.busy = 1U;
eflash_priv->status.error = 0U;
*(volatile uint32_t *)(fbase + 0x4) = addr;
*(volatile uint32_t *)(fbase + 0x10) = 0x1;
eflash_priv->status.busy = 0U;
return 0;
}
/**
\brief Erase complete Flash.
\param[in] handle eflash handle to operate.
\return error code
*/
int32_t csi_eflash_erase_chip(eflash_handle_t handle)
{
EFLASH_NULL_PARAM_CHK(handle);
return ERR_EFLASH(EDRV_UNSUPPORTED);
}
/**
\brief Get Flash information.
\param[in] handle eflash handle to operate.
\return Pointer to Flash information \ref eflash_info_t
*/
eflash_info_t *csi_eflash_get_info(eflash_handle_t handle)
{
if (handle == NULL) {
return NULL;
}
ck_eflash_priv_t *eflash_priv = handle;
eflash_info_t *eflash_info = &(eflash_priv->eflashinfo);
return eflash_info;
}
/**
\brief Get EFLASH status.
\param[in] handle eflash handle to operate.
\return EFLASH status \ref eflash_status_t
*/
eflash_status_t csi_eflash_get_status(eflash_handle_t handle)
{
if (handle == NULL) {
eflash_status_t ret;
memset(&ret, 0, sizeof(eflash_status_t));
return ret;
}
ck_eflash_priv_t *eflash_priv = handle;
return eflash_priv->status;
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_eflash.h
* @brief head file for ck eflash
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CK_EFLASH_H_
#define _CK_EFLASH_H_
#include "drv_eflash.h"
#include "soc.h"
#define EFLASH_SECTOR_SIZE 0x200
#define EFLASH_ERASED_VALUE 0xff
#define EFLASH_PROGRAM_UINT 0x4
#define EFLASH_PAGE_SIZE 0
#endif

View file

@ -0,0 +1,366 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_pmu.c
* @brief CSI Source File for Embedded Flash Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include "drv_pmu.h"
#include "drv_tee.h"
#include "drv_eflash.h"
#include "ck_pmu.h"
#define ERR_PMU(errno) (CSI_DRV_ERRNO_PMU_BASE | errno)
#define PMU_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_PMU(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint8_t idx;
uint32_t base;
uint32_t irq;
pmu_event_cb_t cb;
pmu_action_cb_t callback[32];
} ck_pmu_priv_t;
extern int32_t target_get_pmu(int32_t idx, uint32_t *base, uint32_t *irq);
extern int32_t arch_do_cpu_save(void);
extern int32_t arch_do_cpu_resume(void);
extern int32_t arch_resume_context(void);
static ck_pmu_priv_t pmu_handle[CONFIG_PMU_NUM];
static uint32_t s_callback_count = 0;
#define CONFIG_PMU_REGISTER_NUM_SAVE 19
static uint32_t pmu_regs_saved[CONFIG_PMU_REGISTER_NUM_SAVE];
#define CONFIG_CPU_REGISTER_NUM_SAVE 27
uint32_t arch_cpu_saved[CONFIG_CPU_REGISTER_NUM_SAVE];
/* Driver Capabilities */
#if 0
static const pmu_capabilities_t driver_capabilities = {
.event_ready = 1, /* event_ready */
.data_width = 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
.erase_chip = 0 /* erase_chip */
};
#endif
//
// Functions
//
static void do_prepare_sleep_action(int32_t idx)
{
uint8_t i;
volatile ck_pmu_reg_t *pbase = (ck_pmu_reg_t *)pmu_handle[idx].base;
for (i = 0; i < sizeof(pmu_regs_saved)/4; i++) {
pmu_regs_saved[i] = *((volatile uint32_t *)pbase + i);
}
}
static void do_wakeup_sleep_action(int32_t idx)
{
uint8_t i;
volatile ck_pmu_reg_t *pbase = (ck_pmu_reg_t *)pmu_handle[idx].base;
*((volatile uint32_t *)pbase + 5) = pmu_regs_saved[5];
while((*((volatile uint32_t *)pbase + 6) & 0xf) != 0xf);
*((volatile uint32_t *)pbase + 11) = pmu_regs_saved[11];
while((*((volatile uint32_t *)pbase + 6) & 0x1f) != 0x1f);
for (i = 0; i < sizeof(pmu_regs_saved)/4; i++) {
if (i != 5 && i != 11) {
*((volatile uint32_t *)pbase + i) = pmu_regs_saved[i];
}
}
}
static uint8_t s_action[CONFIG_PMU_NUM] = {0x0};
int32_t ck_pmu_power_manager(int32_t idx)
{
if (!(s_action[idx] % 2)) {
do_prepare_sleep_action(idx);
s_action[idx]++;
} else {
do_wakeup_sleep_action(idx);
s_action[idx]--;
}
return 0;
}
int32_t ck_pmu_act_callback(pmu_handle_t handle, pmu_event_e event)
{
ck_pmu_priv_t *pmu_priv = handle;
uint32_t i;
for (i = 0; i < s_callback_count; i++) {
if (pmu_priv->callback[i]) {
pmu_priv->callback[i](event);
}
}
if (i != s_callback_count) {
return -1;
}
return 0;
}
void resume_context_from_stop_mode(void)
{
ck_pmu_priv_t *pmu_priv = &pmu_handle[0];
// ck_pmu_power_manager(PMU_EVENT_SLEEP_DONE);
// ck_pmu_act_callback(pmu_priv, PMU_EVENT_SLEEP_DONE);
*((volatile uint32_t *)0x50006100) |= 0xa0000000;
if (pmu_priv->cb) {
pmu_priv->cb(pmu_priv->idx, PMU_EVENT_SLEEP_DONE, PMU_MODE_STDBY);
}
arch_do_cpu_resume();
}
#define CONFIG_LPM_RESUME_ADDR 0x1003f7f0
void set_resume_func(uint32_t *func)
{
eflash_handle_t eflash = csi_eflash_initialize(0, NULL);
csi_eflash_erase_sector(eflash, CONFIG_LPM_RESUME_ADDR);
csi_eflash_program(eflash, CONFIG_LPM_RESUME_ADDR, &func, 4);
}
typedef enum {
WAIT_MODE = 0,
DOZE_MODE,
STOP_MODE,
STANDBY_MODE,
SLEEP_MODE
} lpm_mode_t;
void soc_sleep(pmu_handle_t handle, lpm_mode_t mode)
{
#ifdef CONFIG_TEE_CA
tee_lpm_mode_e lpm_mode = 0;
if (mode == WAIT_MODE) {
lpm_mode = TEE_LPM_MODE_WAIT;
} else if (mode == DOZE_MODE) {
lpm_mode = TEE_LPM_MODE_DOZE;
} else if (mode == STOP_MODE) {
lpm_mode = TEE_LPM_MODE_STOP;
} else if (mode == STANDBY_MODE) {
lpm_mode = TEE_LPM_MODE_STANDBY;
} else {
lpm_mode = TEE_LPM_MODE_WAIT;
}
csi_tee_enter_lpm(0, 0, lpm_mode);
if (mode == STOP_MODE) {
resume_context_from_stop_mode();
}
#else
ck_pmu_priv_t *pmu_priv = handle;
ck_pmu_reg_t *pmu_reg = (ck_pmu_reg_t *)pmu_priv->base;
if (mode == WAIT_MODE) {
pmu_reg->LPCR |= CONFIG_PMU_ENTER_WAIT_MODE;
__WFI();
} else if (mode == DOZE_MODE) {
pmu_reg->LPCR |= CONFIG_PMU_ENTER_DOZE_MODE;
__DOZE();
} else if (mode == STOP_MODE) {
pmu_reg->LPCR |= CONFIG_PMU_ENTER_STOP_MODE;
__STOP();
} else if (mode == STANDBY_MODE) {
pmu_reg->LPCR |= CONFIG_PMU_ENTER_STANDBY_MODE;
__STOP();
} else {
pmu_reg->LPCR |= CONFIG_PMU_ENTER_WAIT_MODE;
__WFI();
}
#endif
}
/**
\brief Initialize PMU Interface. 1. Initializes the resources needed for the PMU interface 2.registers event callback function
\param[in] idx device id
\param[in] cb_event Pointer to \ref pmu_event_cb_t
\return pointer to pmu handle
*/
pmu_handle_t drv_pmu_initialize(int32_t idx, pmu_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_PMU_NUM) {
return NULL;
}
/* obtain the pmu information */
uint32_t base = 0u;
uint32_t irq = 0u;
int32_t real_idx = target_get_pmu(idx, &base, &irq);
if (real_idx != idx) {
return NULL;
}
ck_pmu_priv_t *pmu_priv = &pmu_handle[idx];
/* initialize the pmu context */
pmu_priv->idx = idx;
pmu_priv->base = base;
pmu_priv->irq = irq;
pmu_priv->cb = cb_event;
return (pmu_handle_t)pmu_priv;
}
/**
\brief De-initialize PMU Interface. stops operation and releases the software resources used by the interface
\param[in] handle pmu handle to operate.
\return error code
*/
int32_t drv_pmu_uninitialize(pmu_handle_t handle)
{
PMU_NULL_PARAM_CHK(handle);
ck_pmu_priv_t *pmu_priv = handle;
pmu_priv->cb = NULL;
return 0;
}
int32_t drv_pmu_power_control(int32_t idx, csi_power_stat_e state)
{
switch (state) {
case DRV_POWER_LOW:
break;
case DRV_POWER_FULL:
break;
case DRV_POWER_OFF:
ck_pmu_power_manager(idx);
// csi_pmu_register_module(dw_usart_power_manager);
break;
default:
break;
}
return 0;
}
/**
\brief Get driver capabilities.
\param[in] idx device id
\return \ref pmu_capabilities_t
*/
#if 0
pmu_capabilities_t csi_pmu_get_capabilities(int32_t idx)
{
if (idx < 0 || idx >= CONFIG_PMU_NUM) {
pmu_capabilities_t ret;
memset(&ret, 0, sizeof(pmu_capabilities_t));
return ret;
}
return driver_capabilities;
}
#endif
/**
\brief choose the pmu mode to enter
\param[in] handle pmu handle to operate.
\param[in] mode \ref pmu_mode_e
\return error code
*/
int32_t drv_pmu_enter_sleep(pmu_handle_t handle, pmu_mode_e mode)
{
PMU_NULL_PARAM_CHK(handle);
switch (mode) {
case PMU_MODE_RUN:
break;
case PMU_MODE_SLEEP:
soc_sleep(handle, WAIT_MODE);
break;
case PMU_MODE_DORMANT:
// soc_sleep(handle, DOZE_MODE);
if (arch_do_cpu_save() == 0) {
*(volatile unsigned int *)(0xe000e1c0) = 0xffffffff; // reload wakeup_IRQ
*(volatile unsigned int *)(0xe000e280) = 0xffffffff; // clear pend IRQ
soc_sleep(handle, STOP_MODE);
}
break;
case PMU_MODE_STDBY:
*(volatile unsigned int *)(0xe000e1c0) = 0xffffffff; // reload wakeup_IRQ
*(volatile unsigned int *)(0xe000e280) = 0xffffffff; // clear pend IRQ
soc_sleep(handle, STANDBY_MODE);
break;
case PMU_MODE_SHUTDOWN:
*(volatile unsigned int *)(0xe000e1c0) = 0xffffffff; // reload wakeup_IRQ
*(volatile unsigned int *)(0xe000e280) = 0xffffffff; // clear pend IRQ
soc_sleep(handle, STANDBY_MODE);
break;
default:
return ERR_PMU(EDRV_PARAMETER);
}
return 0;
}
/**
\brief register module to action pmu event
\param[in] handle pmu handle to operate.
\param[in] callback Pointer to \ref pmu_action_cb_t
\return error code
*/
int32_t drv_pmu_register_module(pmu_action_cb_t callback)
{
ck_pmu_priv_t *pmu_priv = (ck_pmu_priv_t *)&pmu_handle[0];
if (callback == NULL) {
return ERR_PMU(EDRV_PARAMETER);
}
pmu_priv->callback[s_callback_count] = callback;
s_callback_count++;
return 0;
}
/**
\brief Config the wakeup source.
\param[in] handle pmu handle to operate
\param[in] type \ref pmu_wakeup_type
\param[in] pol \ref pmu_wakeup_pol
\param[in] enable flag control the wakeup source is enable or not
\return error code
*/
int32_t drv_pmu_config_wakeup_source(pmu_handle_t handle, uint32_t irq_num, pmu_wakeup_type_e type, pmu_wakeup_pol_e pol, uint8_t enable)
{
PMU_NULL_PARAM_CHK(handle);
if (enable) {
// csi_vic_enable_irq(irq_num);
// csi_vic_enable_sirq(irq_num);
// csi_vic_set_wakeup_irq(irq_num);
drv_nvic_set_wakeup_irq(irq_num);
} else {
// csi_vic_disable_irq(irq_num);
// csi_vic_disable_sirq(irq_num);
drv_nvic_clear_wakeup_irq(irq_num);
// csi_vic_clear_wakeup_irq(irq_num);
}
return 0;
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_pmu.h
* @brief head file for ck pmu
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CK_PMU_H_
#define _CK_PMU_H_
#include "drv_pmu.h"
#include "soc.h"
#define CONFIG_PMU_ENTER_WAIT_MODE 0x4
#define CONFIG_PMU_ENTER_DOZE_MODE 0x4
#define CONFIG_PMU_ENTER_STOP_MODE 0xc
#define CONFIG_PMU_ENTER_STANDBY_MODE 0x14
typedef struct {
__IOM uint32_t LPCR; /* Offset: 0x000 (R/W) low power control register */
__IOM uint32_t MCLKSEL; /* Offset: 0x004 (R/W) MCLK select register */
__IOM uint32_t CRCR; /* Offset: 0x008 (R/W) clock ratio control register */
__IOM uint32_t CGCR; /* Offset: 0x00c (R/W) clock gate control register */
__IOM uint32_t CGSR; /* Offset: 0x010 (R/W) clock gate status register */
__IOM uint32_t CLKDSENR; /* Offset: 0x014 (R/W) clock disable register */
__IOM uint32_t CLKSTBR; /* Offset: 0x018 (R/W) clock stable register */
__IOM uint32_t CLKSTBST; /* Offset: 0x01c (R/W) clock stable interrupt statue register */
__IOM uint32_t CLKSTBMK; /* Offset: 0x020 (R/W) clock stable interrupt mask register */
__IOM uint32_t CSSCR; /* Offset: 0x024 (R/W) clock source stable counter register */
__IOM uint32_t DFCC; /* Offset: 0x028 (R/W) dynamic frequence conversion control register */
__IOM uint32_t PCR; /* Offset: 0x02c (R/W) pll control register */
__IOM uint32_t PLTR; /* Offset: 0x030 (R/W) pll lock timer register */
__IOM uint32_t SWHRC; /* Offset: 0x034 (R/W) software HRST control register */
__IOM uint32_t SWHRD; /* Offset: 0x038 (R/W) software HRST duration register */
__IOM uint32_t SWPRC; /* Offset: 0x03c (R/W) software PRST control register */
__IOM uint32_t SWPRD; /* Offset: 0x040 (R/W) software PRST duration register */
__IOM uint32_t SWRE; /* Offset: 0x044 (R/W) software reset enable register */
__IOM uint32_t BOOTSEL; /* Offset: 0x048 (R/W) boot selection register */
__IOM uint32_t SCGCR; /* Offset: 0x04c (R/W) security clock gate control register */
__IOM uint32_t SCGSR; /* Offset: 0x050 (R/W) security clock gate status register */
} ck_pmu_reg_t;
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,91 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_rsa.h
* @brief header file for rsa driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CK_RSA_H_
#define _CK_RSA_H_
#include <stdio.h>
#include "drv_rsa.h"
#include "soc.h"
#define RSA_KEY_LEN 2048
#define RSA_KEY_BYTE (RSA_KEY_LEN >> 3)
#define RSA_KEY_WORD (RSA_KEY_LEN >> 5)
#define BN_MAX_BITS ((RSA_KEY_LEN << 1) + 32)
#define BN_MAX_BYTES ((BN_MAX_BITS + 7) >> 3)
#define BN_MAX_WORDS ((BN_MAX_BYTES + 3) >> 2)
#define MAX_RSA_LP_CNT 10000
#define GET_KEY_BYTE(k) (k >> 3)
#define GET_KEY_WORD(k) (k >> 5)
#define UINT32_TO_UINT64(data) ((uint64_t)(((uint64_t)(data)) & 0x00000000ffffffffU))
#define UINT64L_TO_UINT32(data) ((uint32_t)(((uint64_t)(data)) & 0x00000000ffffffffU))
#define UINT64H_TO_UINT32(data) ((uint32_t)((((uint64_t)(data)) >> 32) & 0x00000000ffffffffU))
#define PKCS1_PADDING 0x01
#define NO_PADDING 0x02
#define MD5_PADDING 0x00
#define SHA1_PADDING 0x01
#define SHA256_PADDING 0x03
#define MD5_HASH_SZ 16
#define SHA1_HASH_SZ 20
#define SHA256_HASH_SZ 32
#define RAS_CALCULATE_Q 0x6
#define RSA_ENABLE_MODULE 0x3
#define RSA_ENDIAN_MODE 0x8
#define RSA_RESET 0x1
#define RSA_CAL_Q_DONE_OFFSET 0x5
typedef struct bignum {
uint32_t pdata[BN_MAX_WORDS];
uint32_t words;
} bignum_t;
typedef struct {
__IOM uint32_t rsa_mwid; /* Offset: 0x000 (R/W) Width of M register */
__IOM uint32_t rsa_ckid; /* Offset: 0x004 (R/W) Width of D register */
__IOM uint32_t rsa_bwid; /* Offset: 0x008 (R/W) Width of B register */
__IOM uint32_t rsa_ctrl; /* Offset: 0x00c (R/W) RSA control register */
__OM uint32_t rsa_rst; /* Offset: 0x010 (W) RSA reset register */
__IM uint32_t rsa_lp_cnt; /* Offset: 0x014 (R) Loop counter for inquiry register*/
__IM uint32_t rsa_q0; /* Offset: 0x018 (R) High-radix MM algorithm assistant register,part 1*/
__IM uint32_t rsa_q1; /* Offset: 0x01c (R) High-radix MM algorithm assistant register,part 2*/
__IOM uint32_t rsa_isr; /* Offset: 0x020 (W/R) Interrupt raw status register */
__IOM uint32_t rsa_imr; /* Offset: 0x024 (W/R) Interrupt mask register */
__IOM uint32_t rev1[54]; /* Reserve regiser */
__IOM uint32_t rsa_rfm; /* Offset: 0x100 (W/R) Register file for modulus M */
__IOM uint32_t rev2[63]; /* Reserve regiser */
__IOM uint32_t rsa_rfd; /* Offset: 0x200 (W/R) Register file for exponent D */
__IOM uint32_t rev3[63]; /* Reserve regiser */
__IOM uint32_t rsa_rfc; /* Offset: 0x300 (W/R) Register file for hard C */
__IOM uint32_t rev4[63]; /* Reserve regiser */
__IOM uint32_t rsa_rfb; /* Offset: 0x400 (W/R) Register file for data B */
__IOM uint32_t rev5[63]; /* Reserve regiser */
__IM uint32_t rsa_rfr; /* Offset: 0x500 (R) Register file for storing the result */
} ck_rsa_reg_t;
#endif

View file

@ -0,0 +1,20 @@
choice
prompt "select sha type "
help
select sha type
config SHA_CK_V2
bool "csky v2 sha"
help
select the ck sha driver
config SHA_CK_V1
bool "csky v1 sha"
help
select the ck sha driver
config SHA_ZX29
bool "csky zx29 sha"
help
select the zx29 sha driver
endchoice

View file

@ -0,0 +1,559 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_sha.c
* @brief CSI Source File for SHA Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "csi_core.h"
#include "drv_sha.h"
#include "ck_sha_v1.h"
#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD
#define CONFIG_SHA_SUPPORT_MUL_THREAD 1
#endif
typedef struct {
uint32_t base;
uint32_t irq;
sha_event_cb_t cb;
sha_status_t status;
sha_mode_e mode;
sha_endian_mode_e endian;
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
uint32_t state[16];
uint32_t sha_buffer[32];
uint32_t total;
uint8_t first_cal;
#endif
} ck_sha_priv_t;
#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD
static ck_sha_priv_t sha_handle[CONFIG_SHA_NUM];
#endif
bool finish_flag = 0;
/* Driver Capabilities */
static const sha_capabilities_t driver_capabilities = {
.sha1 = 1, /* sha1 mode */
.sha224 = 1, /* sha224 mode */
.sha256 = 1, /* sha256 mode */
.sha384 = 1, /* sha384 mode */
.sha512 = 1, /* sha512 mode */
.sha512_224 = 1, /* sha512_224 mode */
.sha512_256 = 1, /* sha512_256 mode */
.endianmode = 1, /* endian mode */
.interruptmode = 1 /* interrupt mode */
};
#define ERR_SHA(errno) (CSI_DRV_ERRNO_SHA_BASE | errno)
#define SHA_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_SHA(EDRV_PARAMETER); \
} \
} while (0)
extern int32_t target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq);
extern int32_t target_get_sha_count(void);
//
// Functions
//
ck_sha_reg_t *sha_reg = NULL;
#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD
static uint32_t sha_buffer[32];
static uint32_t total[2] = {0x0};
static uint8_t first_cal = 1;
#endif
static uint8_t sha_result[64] = {0x0};
static int32_t sha_set_mode(sha_mode_e mode)
{
sha_reg->SHA_MODE &= ~0x7;
sha_reg->SHA_MODE |= mode;
return 0;
}
static void sha_set_source_message(uint32_t baseaddr)
{
sha_reg->SHA_BASEADDR = baseaddr;
}
static void sha_set_dest_message(uint32_t destaddr)
{
sha_reg->SHA_DESTADDR = destaddr;
}
static void sha_enable_without_count(void)
{
sha_reg->SHA_MODE |= 1<<25;
}
static void sha_disable_without_count(void)
{
sha_reg->SHA_MODE &= ~(1<<25);
}
static void sha_set_message_count(uint32_t count)
{
sha_reg->SHA_COUNTER0 = count;
sha_reg->SHA_COUNTER1 = 0;
}
static int32_t sha_enable_initial(void)
{
sha_reg->SHA_MODE |= 1 << SHA_INIT_OFFSET;
return 0;
}
static int32_t sha_disable_initial(void)
{
sha_reg->SHA_MODE &= ~(1 << SHA_INIT_OFFSET);
return 0;
}
static int32_t sha_enable_calculate(void)
{
sha_reg->SHA_CON |= 1;
return 0;
}
static int32_t sha_message_done(void)
{
while(sha_reg->SHA_CON & 0x1);
return 0;
}
static void sha_new_encode(void)
{
sha_reg->SHA_INTSTATE = 0;
sha_reg->SHA_MODE = 0;
}
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
static int32_t sha_restore_context(sha_handle_t handle, uint32_t *data)
{
uint32_t *result = (uint32_t *)&sha_reg->SHA_H0L;
uint8_t i;
for (i = 0; i < 16; i++) {
result[i] = data[i];
}
return 0;
}
static int32_t sha_save_context(sha_handle_t handle, uint32_t *data)
{
uint32_t *result = (uint32_t *)&sha_reg->SHA_H0L;
uint8_t i;
for (i = 0; i < 16; i++) {
data[i] = result[i];
}
return 0;
}
#endif
static inline void sha_reverse_order(uint8_t *pdata, int32_t length)
{
uint8_t input_data[length];
uint8_t result[length];
uint32_t tmp = 0;
int32_t i = 0;
memcpy((void *)input_data, (void *)pdata, length);
for (i = 0; i < length; i++) {
tmp = i >> 2;
tmp = tmp << 3;
result[i] = input_data[tmp + 3 - i];
}
memcpy((void *)pdata, (void *)result, length);
}
/**
\brief get sha handle count.
\return sha handle count
*/
int32_t csi_sha_get_instance_count(void)
{
return target_get_sha_count();
}
/**
\brief Initialize SHA Interface. 1. Initializes the resources needed for the SHA interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_sha_get_instance_count()
\param[in] cb_event Pointer to \ref sha_event_cb_t
\return return sha handle if success
*/
sha_handle_t csi_sha_initialize(sha_handle_t handle, sha_event_cb_t cb_event)
{
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
uint32_t base = 0u;
uint32_t irq;
/* obtain the sha information */
target_get_sha(0, &base, &irq);
ck_sha_priv_t *sha_priv = handle;
memset(sha_priv->state, 0, sizeof(sha_priv->state));
sha_priv->total = 0;
sha_priv->first_cal = 1;
#else
if (idx < 0 || idx >= CONFIG_SHA_NUM) {
return NULL;
}
uint32_t base = 0u;
uint32_t irq;
/* obtain the sha information */
int32_t real_idx = target_get_sha(idx, &base, &irq);
if (real_idx != idx) {
return NULL;
}
ck_sha_priv_t *sha_priv = &sha_handle[idx];
#endif
sha_priv->base = base;
sha_priv->irq = irq;
/* initialize the sha context */
sha_priv->cb = cb_event;
sha_priv->status.busy = 0;
return (sha_handle_t)sha_priv;
}
/**
\brief De-initialize SHA Interface. stops operation and releases the software resources used by the interface
\param[in] handle sha handle to operate.
\return error code
*/
int32_t csi_sha_uninitialize(sha_handle_t handle)
{
SHA_NULL_PARAM_CHK(handle);
ck_sha_priv_t *sha_priv = handle;
sha_priv->cb = NULL;
return 0;
}
/**
\brief Get driver capabilities.
\param[in] handle sha handle to operate.
\return \ref sha_capabilities_t
*/
sha_capabilities_t csi_sha_get_capabilities(sha_handle_t handle)
{
return driver_capabilities;
}
/**
\brief config sha mode.
\param[in] handle sha handle to operate.
\param[in] mode \ref sha_mode_e
\param[in] endian \ref sha_endian_mode_e
\return error code
*/
int32_t csi_sha_config(sha_handle_t handle, sha_mode_e mode, sha_endian_mode_e endian_mode)
{
SHA_NULL_PARAM_CHK(handle);
ck_sha_priv_t *sha_priv = handle;
sha_reg = (ck_sha_reg_t *)(sha_priv->base);
/* config the sha mode */
switch (mode) {
case SHA_MODE_512_256:
case SHA_MODE_512_224:
return ERR_SHA(EDRV_UNSUPPORTED);
case SHA_MODE_1:
case SHA_MODE_224:
case SHA_MODE_256:
case SHA_MODE_384:
case SHA_MODE_512:
sha_priv->mode = mode;
break;
default:
return ERR_SHA(EDRV_PARAMETER);
}
return 0;
}
/**
\brief start the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\return error code
*/
int32_t csi_sha_starts(sha_handle_t handle, void *context)
{
SHA_NULL_PARAM_CHK(handle);
ck_sha_priv_t *sha_priv = handle;
sha_priv->status.busy = 1;
sha_new_encode();
sha_set_mode(sha_priv->mode);
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
memset(sha_priv->sha_buffer, 0, sizeof(sha_priv->sha_buffer));
memset(sha_priv->state, 0, sizeof(sha_priv->state));
sha_priv->first_cal = 1;
sha_priv->total = 0;
#endif
return 0;
}
/**
\brief updata the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\param[in] input Pointer to the Source data
\param[in] len the data len
\return error code
*/
int32_t csi_sha_update(sha_handle_t handle, void *context, const void *input, uint32_t len)
{
SHA_NULL_PARAM_CHK(handle);
SHA_NULL_PARAM_CHK(input);
if (len <= 0) {
return ERR_SHA(EDRV_PARAMETER);
}
ck_sha_priv_t *sha_priv = handle;
sha_reg = (ck_sha_reg_t *)(sha_priv->base);
uint8_t total_len_num;
uint32_t block_size;
if (sha_priv->mode < 4) {
block_size = 64;
total_len_num = 2;
} else {
block_size = 128;
total_len_num = 4;
}
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
uint32_t *sha_buffer = sha_priv->sha_buffer;
uint8_t first_cal = sha_priv->first_cal;
sha_set_mode(sha_priv->mode);
uint32_t left = sha_priv->total & (block_size - 1);
uint32_t fill = block_size - left;
uint32_t total_length = sha_priv->total << 3;
uint32_t index = left >> 2;
if (left & 0x3) {
index++;
}
sha_priv->total += len;
sha_priv->total &= 0xffffffff;
#else
uint32_t left = total[0] & (block_size - 1);
uint32_t fill = block_size - left;
uint32_t total_length = total[0] << 3;
uint32_t index = left >> 2;
if (left & 0x3) {
index++;
}
total[0] += len;
total[0] &= 0xffffffff;
#endif
uint8_t *p = (uint8_t *)input;
/* when the text is not aligned by block and len > fill */
if (left && len >= fill) {
if (finish_flag) {
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
memset(((uint8_t *)sha_buffer + left), 0x0, sizeof(sha_priv->sha_buffer) - left);
#else
memset(((uint8_t *)sha_buffer + left), 0x0, sizeof(sha_buffer) - left);
#endif
sha_buffer[index + total_len_num - 1] = total_length;
sha_disable_without_count();
sha_set_message_count(left << 3);
} else {
memcpy((void *)(((uint8_t *)sha_buffer) + left), p, fill);
p += fill;
sha_enable_without_count();
sha_set_message_count(block_size << 3);
}
sha_set_source_message((uint32_t)sha_buffer);
sha_set_dest_message((uint32_t)sha_result);
if (first_cal == 0) {
sha_enable_initial();
} else {
sha_disable_initial();
}
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_restore_context(handle, (uint32_t *)sha_priv->state);
#endif
sha_enable_calculate();
sha_message_done();
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_save_context(handle, (uint32_t *)sha_priv->state);
#endif
len -= fill;
left = 0;
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_priv->first_cal = 0;
first_cal = 0;
#else
first_cal = 0;
#endif
}
/* calculate the hash by block */
while (len >= block_size) {
if (finish_flag) {
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
memset(sha_buffer, 0, sizeof(sha_priv->sha_buffer));
#else
memset(sha_buffer, 0, sizeof(sha_buffer));
#endif
sha_buffer[total_len_num - 1] = total_length;
sha_set_source_message((uint32_t)sha_buffer);
sha_disable_without_count();
sha_set_message_count(0);
} else {
memcpy(sha_buffer, p, block_size);
sha_set_source_message((uint32_t)sha_buffer);
sha_enable_without_count();
sha_set_message_count(block_size << 3);
p += block_size;
}
sha_set_dest_message((uint32_t)sha_result);
if (first_cal == 0) {
sha_enable_initial();
} else {
sha_disable_initial();
}
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_restore_context(handle, (uint32_t *)sha_priv->state);
#endif
sha_enable_calculate();
sha_message_done();
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_save_context(handle, (uint32_t *)sha_priv->state);
#endif
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_priv->first_cal = 0;
first_cal = 0;
#else
first_cal = 0;
#endif
len -= block_size;
}
/* when the text is not aligned by block and len < fill */
if (len > 0) {
memcpy((void *)(((uint8_t *)sha_buffer) + left), p, len);
}
sha_priv->status.busy = 0;
return 0;
}
/**
\brief finish the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\param[out] output Pointer to the dest data
\return error code
*/
int32_t csi_sha_finish(sha_handle_t handle, void *context, void *output)
{
SHA_NULL_PARAM_CHK(handle);
SHA_NULL_PARAM_CHK(output);
ck_sha_priv_t *sha_priv = handle;
uint32_t block_size;
if (sha_priv->mode < 4) {
block_size = 64;
} else {
block_size = 128;
}
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
uint32_t last = sha_priv->total & (block_size - 1);
#else
uint32_t last = total[0] & (block_size - 1);
#endif
uint32_t padn = block_size - last;
finish_flag = 1;
csi_sha_update(handle, NULL, output, padn);
uint8_t result_len = 20;
/* convert the data endian according the sha mode */
if (sha_priv->mode == SHA_MODE_1) {
result_len = 20;
} else if (sha_priv->mode == SHA_MODE_224) {
result_len = 28;
} else if (sha_priv->mode == SHA_MODE_256) {
result_len = 32;
} else if (sha_priv->mode == SHA_MODE_512) {
result_len = 64;
} else if (sha_priv->mode == SHA_MODE_384) {
result_len = 48;
}
sha_reverse_order(sha_result, result_len);
memcpy((uint8_t*)output, sha_result, result_len);
finish_flag = 0;
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
memset(sha_priv->sha_buffer, 0, sizeof(sha_priv->sha_buffer));
sha_priv->first_cal = 1;
sha_priv->total = 0;
#else
memset(sha_buffer, 0, sizeof(sha_buffer));
first_cal = 1;
total[0] = 0;
#endif
return 0;
}
/**
\brief Get SHA status.
\param[in] handle sha handle to operate.
\return SHA status \ref sha_status_t
*/
sha_status_t csi_sha_get_status(sha_handle_t handle)
{
ck_sha_priv_t *sha_priv = handle;
return sha_priv->status;
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_sha.h
* @brief header file for sha driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CK_SHA_H_
#define _CK_SHA_H_
#include <stdio.h>
#include "drv_sha.h"
#include "soc.h"
#define SHA_INIT_OFFSET 3
#define SHA_INT_ENABLE_OFFSET 4
#define SHA_ENDIAN_OFFSET 5
#define SHA_CAL_OFFSET 6
typedef struct {
__IOM uint32_t SHA_CON; /* Offset: 0x000 (R/W) Control register */
__IOM uint32_t SHA_MODE; /* Offset: 0x004 (R/W) Mode register */
__IOM uint32_t SHA_INTSTATE; /* Offset: 0x008 (R/W) Instatus register */
__IOM uint32_t SHA_BASEADDR; /* Offset: 0x00c (R/W) Baseaddr register */
__IOM uint32_t SHA_DESTADDR; /* Offset: 0x010 (R/W) Dest addr register */
__IOM uint32_t SHA_COUNTER0; /* Offset: 0x014 (R/W) count0 register */
__IOM uint32_t SHA_COUNTER1; /* Offset: 0x018 (R/W) count1 register */
__IOM uint32_t SHA_COUNTER2; /* Offset: 0x01c (R/W) count2 register */
__IOM uint32_t SHA_COUNTER3; /* Offset: 0x020 (R/W) count3 register */
__IOM uint32_t SHA_H0L; /* Offset: 0x024 (R/W) H0L register */
__IOM uint32_t SHA_H1L; /* Offset: 0x028 (R/W) H1L register */
__IOM uint32_t SHA_H2L; /* Offset: 0x02c (R/W) H2L register */
__IOM uint32_t SHA_H3L; /* Offset: 0x030 (R/W) H3L register */
__IOM uint32_t SHA_H4L; /* Offset: 0x034 (R/W) H4L register */
__IOM uint32_t SHA_H5L; /* Offset: 0x038 (R/W) H5L register */
__IOM uint32_t SHA_H6L; /* Offset: 0x03c (R/W) H6L register */
__IOM uint32_t SHA_H7L; /* Offset: 0x040 (R/W) H7L register */
__IOM uint32_t SHA_H0H; /* Offset: 0x044 (R/W) H0H register */
__IOM uint32_t SHA_H1H; /* Offset: 0x048 (R/W) H1H register */
__IOM uint32_t SHA_H2H; /* Offset: 0x04c (R/W) H2H register */
__IOM uint32_t SHA_H3H; /* Offset: 0x050 (R/W) H3H register */
__IOM uint32_t SHA_H4H; /* Offset: 0x054 (R/W) H4H register */
__IOM uint32_t SHA_H5H; /* Offset: 0x058 (R/W) H5H register */
__IOM uint32_t SHA_H6H; /* Offset: 0x05c (R/W) H6H register */
__IOM uint32_t SHA_H7H; /* Offset: 0x060 (R/W) H7H register */
} ck_sha_reg_t;
#endif

View file

@ -0,0 +1,700 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_sha.c
* @brief CSI Source File for SHA Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "csi_core.h"
#include "drv_sha.h"
#include "ck_sha_v2.h"
#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD
#define CONFIG_SHA_SUPPORT_MUL_THREAD 1
#endif
typedef struct {
uint32_t base;
uint32_t irq;
sha_event_cb_t cb;
sha_status_t status;
sha_mode_e mode;
sha_endian_mode_e endian;
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
uint8_t state[64];
uint8_t sha_buffer[128];
uint32_t total;
uint32_t last_left;
#endif
} ck_sha_priv_t;
#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD
static ck_sha_priv_t sha_handle[CONFIG_SHA_NUM];
#endif
static uint32_t g_sha_context[CONFIG_SHA_NUM];
bool finish_flag = 0;
/* Driver Capabilities */
static const sha_capabilities_t driver_capabilities = {
.sha1 = 1, /* sha1 mode */
.sha224 = 1, /* sha224 mode */
.sha256 = 1, /* sha256 mode */
.sha384 = 1, /* sha384 mode */
.sha512 = 1, /* sha512 mode */
.sha512_224 = 1, /* sha512_224 mode */
.sha512_256 = 1, /* sha512_256 mode */
.endianmode = 1, /* endian mode */
.interruptmode = 1 /* interrupt mode */
};
#define ERR_SHA(errno) (CSI_DRV_ERRNO_SHA_BASE | errno)
#define SHA_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_SHA(EDRV_PARAMETER); \
} \
} while (0)
//
// Functions
//
ck_sha_reg_t *sha_reg = NULL;
volatile static uint8_t sha_int_flag = 1;
extern int32_t target_get_sha_count(void);
extern int32_t target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq);
static int32_t sha_set_mode(sha_mode_e mode)
{
sha_reg->SHA_CON &= ~0x7;
sha_reg->SHA_CON |= mode;
return 0;
}
#ifndef CONFIG_SHA_BLOCK_MODE
static int32_t sha_enable_interrupt(void)
{
sha_reg->SHA_CON |= 1 << SHA_INT_ENABLE_OFFSET;
return 0;
}
#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD
static int32_t sha_disable_interrupt(void)
{
sha_reg->SHA_CON &= ~(1 << SHA_INT_ENABLE_OFFSET);
return 0;
}
#endif
#endif
static void sha_clear_interrupt(void)
{
sha_reg->SHA_INTSTATE = 0;
}
static int32_t sha_enable_initial(void)
{
sha_reg->SHA_CON |= 1 << SHA_INIT_OFFSET;
return 0;
}
static int32_t sha_enable_calculate(void)
{
sha_reg->SHA_CON |= 1 << SHA_CAL_OFFSET;
return 0;
}
#ifdef CONFIG_SHA_BLOCK_MODE
static int32_t sha_message_done(void)
{
while((sha_reg->SHA_CON & 0x40));
return 0;
}
#endif
static int32_t sha_select_endian_mode(sha_endian_mode_e mode)
{
sha_reg->SHA_CON &= ~(1 << SHA_ENDIAN_OFFSET);
sha_reg->SHA_CON |= mode << SHA_ENDIAN_OFFSET;
return 0;
}
static int32_t sha_input_data(uint32_t *data, uint32_t length)
{
uint8_t i;
uint32_t tmp;
uint32_t *input_data = (uint32_t *) & (sha_reg->SHA_DATA1);
for (i = 0; i < length; i++) {
memcpy(&tmp, (uint8_t *)(data+i), 4);
*(input_data + i) = tmp;
}
return 0;
}
static int32_t sha_get_data(sha_handle_t handle, uint32_t *data)
{
ck_sha_priv_t *sha_priv = handle;
uint8_t len = 0;
uint8_t i;
uint32_t temp;
uint32_t *result = (uint32_t *)&sha_reg->SHA_H0L;
/* according to different mode to obtain the hash result */
if (sha_priv->mode == SHA_MODE_1 || sha_priv->mode == SHA_MODE_224 || sha_priv->mode == SHA_MODE_256) {
if (sha_priv->mode == SHA_MODE_1) {
len = 5;
} else if (sha_priv->mode == SHA_MODE_224) {
len = 7;
} else if (sha_priv->mode == SHA_MODE_256) {
len = 8;
}
for (i = 0; i < len; i++) {
temp = *(result + i);
memcpy(&data[i], &temp, 4);
}
} else {
if (sha_priv->mode == SHA_MODE_384) {
len = 6;
} else if (sha_priv->mode == SHA_MODE_512) {
len = 8;
}
uint32_t *resulth = (uint32_t *)&sha_reg->SHA_H0H;
for (i = 0; i < len; i++) {
// data[i << 1] = *(resulth + i);
// data[(i << 1) + 1] = *(result + i);
temp = *(resulth + i);
memcpy(&data[i<<1], &temp, 4);
temp = *(result + i);
memcpy(&data[(i<<1)+1], &temp, 4);
}
}
return 0;
}
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
static int32_t sha_set_data(sha_handle_t handle, uint32_t *data)
{
ck_sha_priv_t *sha_priv = handle;
uint8_t len = 0;
uint8_t i;
uint32_t *result = (uint32_t *)&sha_reg->SHA_H0L;
/* according to different mode to obtain the hash result */
if (sha_priv->mode == SHA_MODE_1 || sha_priv->mode == SHA_MODE_224 || sha_priv->mode == SHA_MODE_256) {
if (sha_priv->mode == SHA_MODE_1) {
len = 5;
} else if (sha_priv->mode == SHA_MODE_224) {
len = 7;
} else if (sha_priv->mode == SHA_MODE_256) {
len = 8;
}
for (i = 0; i < len; i++) {
*(result + i) = data[i];
}
} else {
if (sha_priv->mode == SHA_MODE_384) {
len = 6;
} else if (sha_priv->mode == SHA_MODE_512) {
len = 8;
}
uint32_t *resulth = (uint32_t *)&sha_reg->SHA_H0H;
for (i = 0; i < len; i++) {
*(resulth + i) = data[i << 1];
*(result + i) = data[(i << 1) + 1] ;
}
}
return 0;
}
#endif
static inline void sha_reverse_order(uint8_t *pdata, int32_t length)
{
uint8_t input_data[length];
uint8_t result[length];
uint32_t tmp = 0;
int32_t i = 0;
memcpy((void *)input_data, (void *)pdata, length);
for (i = 0; i < length; i++) {
tmp = i >> 2;
tmp = tmp << 3;
result[i] = input_data[tmp + 3 - i];
}
memcpy((void *)pdata, (void *)result, length);
}
void ck_sha_irqhandler(int32_t idx)
{
sha_int_flag = 0;
sha_clear_interrupt(); //clear sha interrupt
#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD
ck_sha_priv_t *sha_priv = &sha_handle[idx];
#else
ck_sha_priv_t *sha_priv = (ck_sha_priv_t *)g_sha_context[idx];
#endif
if (finish_flag != 0) {
if (sha_priv->cb != NULL) {
sha_priv->cb(SHA_EVENT_COMPLETE); //execute the callback function
}
}
}
/**
\brief get sha handle count.
\return sha handle count
*/
int32_t csi_sha_get_instance_count(void)
{
return target_get_sha_count();
}
/**
\brief Initialize SHA Interface. 1. Initializes the resources needed for the SHA interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_sha_get_instance_count()
\param[in] cb_event Pointer to \ref sha_event_cb_t
\return return sha handle if success
*/
sha_handle_t csi_sha_initialize(sha_handle_t handle, sha_event_cb_t cb_event)
{
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
uint32_t base = 0u;
uint32_t irq;
/* obtain the sha information */
target_get_sha(0, &base, &irq);
ck_sha_priv_t *sha_priv = handle;
memset(sha_priv->state, 0, sizeof(sha_priv->state));
sha_priv->last_left = 0;
sha_priv->total = 0;
g_sha_context[0] = (uint32_t)handle;
#else
if (idx < 0 || idx >= CONFIG_SHA_NUM) {
return NULL;
}
uint32_t base = 0u;
uint32_t irq;
/* obtain the sha information */
int32_t real_idx = target_get_sha(idx, &base, &irq);
if (real_idx != idx) {
return NULL;
}
ck_sha_priv_t *sha_priv = &sha_handle[idx];
#endif
sha_priv->base = base;
sha_priv->irq = irq;
/* initialize the sha context */
sha_priv->cb = cb_event;
sha_priv->status.busy = 0;
#ifndef CONFIG_SHA_BLOCK_MODE
drv_nvic_enable_irq(sha_priv->irq);
#endif
return (sha_handle_t)sha_priv;
}
/**
\brief De-initialize SHA Interface. stops operation and releases the software resources used by the interface
\param[in] handle sha handle to operate.
\return error code
*/
int32_t csi_sha_uninitialize(sha_handle_t handle)
{
SHA_NULL_PARAM_CHK(handle);
ck_sha_priv_t *sha_priv = handle;
sha_priv->cb = NULL;
#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD
#ifndef CONFIG_SHA_BLOCK_MODE
sha_disable_interrupt();
drv_nvic_disable_irq(sha_priv->irq);
#endif
#endif
return 0;
}
/**
\brief Get driver capabilities.
\param[in] handle sha handle to operate.
\return \ref sha_capabilities_t
*/
sha_capabilities_t csi_sha_get_capabilities(sha_handle_t handle)
{
return driver_capabilities;
}
/**
\brief config sha mode.
\param[in] handle sha handle to operate.
\param[in] mode \ref sha_mode_e
\param[in] endian \ref sha_endian_mode_e
\return error code
*/
int32_t csi_sha_config(sha_handle_t handle, sha_mode_e mode, sha_endian_mode_e endian_mode)
{
SHA_NULL_PARAM_CHK(handle);
ck_sha_priv_t *sha_priv = handle;
sha_reg = (ck_sha_reg_t *)(sha_priv->base);
/* config the sha mode */
switch (mode) {
case SHA_MODE_512_256:
case SHA_MODE_512_224:
return ERR_SHA(EDRV_UNSUPPORTED);
case SHA_MODE_1:
case SHA_MODE_224:
case SHA_MODE_256:
case SHA_MODE_384:
case SHA_MODE_512:
sha_priv->mode = mode;
break;
default:
return ERR_SHA(EDRV_PARAMETER);
}
sha_set_mode(mode);
/*config the sha endian mode */
if (endian_mode == SHA_ENDIAN_MODE_LITTLE) {
sha_priv->endian = endian_mode;
sha_select_endian_mode(endian_mode);
} else if (endian_mode == SHA_ENDIAN_MODE_BIG) {
sha_priv->endian = endian_mode;
sha_select_endian_mode(endian_mode);
} else {
return ERR_SHA(EDRV_PARAMETER);
}
#ifndef CONFIG_SHA_BLOCK_MODE
sha_enable_interrupt();
#endif
return 0;
}
/**
\brief start the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\return error code
*/
int32_t csi_sha_starts(sha_handle_t handle, void *context)
{
SHA_NULL_PARAM_CHK(handle);
ck_sha_priv_t *sha_priv = handle;
sha_enable_initial();
sha_priv->status.busy = 1;
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_get_data(handle, (uint32_t *)sha_priv->state);
#endif
return 0;
}
/**
\brief updata the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\param[in] input Pointer to the Source data
\param[in] len the data len
\return error code
*/
#ifndef CONFIG_SHA_SUPPORT_MUL_THREAD
static uint8_t sha_buffer[128];
static uint32_t total[2] = {0x0};
static uint32_t last_left = 0;
#endif
int32_t csi_sha_update(sha_handle_t handle, void *context, const void *input, uint32_t len)
{
SHA_NULL_PARAM_CHK(handle);
SHA_NULL_PARAM_CHK(input);
if (len <= 0) {
return ERR_SHA(EDRV_PARAMETER);
}
g_sha_context[0] = (uint32_t)handle;
ck_sha_priv_t *sha_priv = handle;
sha_reg = (ck_sha_reg_t *)(sha_priv->base);
uint32_t block_size;
if (sha_priv->mode < 4) {
block_size = 64;
} else {
block_size = 128;
}
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
uint8_t *sha_buffer = sha_priv->sha_buffer;
uint32_t last_left = sha_priv->last_left;
sha_set_mode(sha_priv->mode);
uint32_t left = sha_priv->total & (block_size - 1);
uint32_t fill = block_size - left;
uint32_t total_length = sha_priv->total << 3;
sha_priv->total += len;
sha_priv->total &= 0xffffffff;
uint32_t word_left = sha_priv->total & 0x3;
#else
uint32_t left = total[0] & (block_size - 1);
uint32_t fill = block_size - left;
uint32_t total_length = total[0] << 3;
total[0] += len;
total[0] &= 0xffffffff;
uint32_t word_left = total[0] & 0x3;
#endif
uint8_t temp_data[4];
uint32_t j;
if (finish_flag) {
/*calculate the final word*/
for (j = 0; j < 4; j++) {
temp_data[j] = (total_length >> (8 * j)) & 0xff;
}
}
uint8_t *p = (uint8_t *)input;
/* when the text is not aligned by block and len > fill */
if (left && len >= fill) {
if (finish_flag) {
if (sha_priv->endian == SHA_ENDIAN_MODE_BIG) {
memset(&sha_buffer[left], 0x0, len);
sha_buffer[left] = 0x80;
for (j=0; j<4; j++) {
sha_buffer[left + len - 4 + j] = temp_data[3 - j];
}
} else {
memset(&sha_buffer[left + 4 - last_left], 0x0, len - 4 + last_left);
sha_buffer[left - last_left + 3 - last_left] = 0x80;
for (j = 1; j < 4 - last_left; j++) {
sha_buffer[left - last_left + 3 - last_left - j] = 0x00;
}
for (j=0; j<4; j++) {
sha_buffer[left + len - 4 + j] = temp_data[j];
}
}
} else {
if (last_left && sha_priv->endian == SHA_ENDIAN_MODE_LITTLE) {
uint32_t i;
for (i = 0; i < 4 - last_left; i++) {
*(sha_buffer + left + 3 - last_left - i) = *((uint8_t *)p + 3 - last_left - i);
}
fill = fill - 4 + last_left;
p = (p + 4 - last_left);
}
else if (last_left) {
memcpy((void *)(sha_buffer + left + 4 - last_left), p, fill);
} else {
memcpy((void *)(sha_buffer + left), p, fill);
}
p += fill;
}
/* set the input data */
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_set_data(handle, (uint32_t *)sha_priv->state);
#endif
sha_input_data((uint32_t *)sha_buffer, block_size >> 2);
sha_enable_calculate();
#ifdef CONFIG_SHA_BLOCK_MODE
sha_message_done();
#else
while (sha_int_flag);
sha_int_flag = 1;
#endif
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_get_data(handle, (uint32_t *)sha_priv->state);
#endif
len -= fill;
left = 0;
} else {
if (finish_flag) {
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
memset(sha_buffer, 0, sizeof(sha_priv->sha_buffer));
#else
memset(sha_buffer, 0, sizeof(sha_buffer));
#endif
if (sha_priv->endian == SHA_ENDIAN_MODE_BIG) {
sha_buffer[0] = 0x80;
for (j = 0; j < 4; j++) {
sha_buffer[block_size - 4 + j] = temp_data[3 - j];
}
} else {
sha_buffer[3 - last_left] = 0x80;
for (j = 0; j < 4; j++) {
sha_buffer[block_size - 4 + j] = temp_data[j];
}
}
}
}
/* calculate the hash by block */
while (len >= block_size) {
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_set_data(handle, (uint32_t *)sha_priv->state);
#endif
if (finish_flag) {
if (fill == block_size) {
sha_input_data((uint32_t *)sha_buffer, block_size >> 2);
} else {
sha_input_data((uint32_t *)&sha_buffer[block_size], block_size >> 2);
}
}
else {
sha_input_data((uint32_t *)p, block_size >> 2);
p += block_size;
}
sha_enable_calculate();
#ifdef CONFIG_SHA_BLOCK_MODE
sha_message_done();
#else
while (sha_int_flag);
sha_int_flag = 1;
#endif
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_get_data(handle, (uint32_t *)sha_priv->state);
#endif
len -= block_size;
}
/* when the text is not aligned by block and len < fill */
if (len > 0) {
if (sha_priv->endian == SHA_ENDIAN_MODE_BIG || word_left == 0) {
memcpy((void *)(sha_buffer + left), p, len);
} else {
memcpy((void *)(sha_buffer + left), p, len + 4 - word_left);
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_priv->last_left = word_left;
#else
last_left = word_left;
#endif
}
}
sha_priv->status.busy = 0;
return 0;
}
/**
\brief finish the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\param[out] output Pointer to the dest data
\return error code
*/
//static uint32_t total_length;
int32_t csi_sha_finish(sha_handle_t handle, void *context, void *output)
{
SHA_NULL_PARAM_CHK(handle);
SHA_NULL_PARAM_CHK(output);
ck_sha_priv_t *sha_priv = handle;
uint32_t block_size;
uint8_t message_len;
if (sha_priv->mode < 4) {
block_size = 64;
message_len = 8;
} else {
block_size = 128;
message_len = 16;
}
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
uint32_t last = sha_priv->total & (block_size - 1);
uint32_t padn = (last < (block_size - message_len)) ? (block_size - last) : (block_size + block_size - last);
#else
uint32_t last = total[0] & (block_size - 1);
uint32_t padn = (last < (block_size - message_len)) ? (block_size - last) : (block_size + block_size - last);
#endif
finish_flag = 1;
csi_sha_update(handle, NULL, output, padn);
/* get the hash result */
sha_get_data(handle, (uint32_t *)output);
uint8_t *p = output;
/* convert the data endian according the sha mode */
if (sha_priv->mode == SHA_MODE_1) {
sha_reverse_order(p, 20);
} else if (sha_priv->mode == SHA_MODE_224) {
sha_reverse_order(p, 28);
} else if (sha_priv->mode == SHA_MODE_256) {
sha_reverse_order(p, 32);
} else if (sha_priv->mode == SHA_MODE_512) {
sha_reverse_order(p, 64);
} else if (sha_priv->mode == SHA_MODE_384) {
sha_reverse_order(p, 48);
}
#ifdef CONFIG_SHA_SUPPORT_MUL_THREAD
sha_priv->total = 0;
sha_priv->last_left = 0;
#else
total[0] = 0;
last_left = 0;
#endif
finish_flag = 0;
return 0;
}
/**
\brief Get SHA status.
\param[in] handle sha handle to operate.
\return SHA status \ref sha_status_t
*/
sha_status_t csi_sha_get_status(sha_handle_t handle)
{
ck_sha_priv_t *sha_priv = handle;
return sha_priv->status;
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_sha.h
* @brief header file for sha driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CK_SHA_H_
#define _CK_SHA_H_
#include <stdio.h>
#include "drv_sha.h"
#include "soc.h"
#define SHA_INIT_OFFSET 3
#define SHA_INT_ENABLE_OFFSET 4
#define SHA_ENDIAN_OFFSET 5
#define SHA_CAL_OFFSET 6
typedef struct {
__IOM uint32_t SHA_CON; /* Offset: 0x000 (R/W) Control register */
__IOM uint32_t SHA_INTSTATE; /* Offset: 0x004 (R/W) Instatus register */
__IOM uint32_t SHA_H0L; /* Offset: 0x008 (R/W) H0L register */
__IOM uint32_t SHA_H1L; /* Offset: 0x00c (R/W) H1L register */
__IOM uint32_t SHA_H2L; /* Offset: 0x010 (R/W) H2L register */
__IOM uint32_t SHA_H3L; /* Offset: 0x014 (R/W) H3L register */
__IOM uint32_t SHA_H4L; /* Offset: 0x018 (R/W) H4L register */
__IOM uint32_t SHA_H5L; /* Offset: 0x01c (R/W) H5L register */
__IOM uint32_t SHA_H6L; /* Offset: 0x020 (R/W) H6L register */
__IOM uint32_t SHA_H7L; /* Offset: 0x024 (R/W) H7L register */
__IOM uint32_t SHA_H0H; /* Offset: 0x028 (R/W) H0H register */
__IOM uint32_t SHA_H1H; /* Offset: 0x02c (R/W) H1H register */
__IOM uint32_t SHA_H2H; /* Offset: 0x030 (R/W) H2H register */
__IOM uint32_t SHA_H3H; /* Offset: 0x034 (R/W) H3H register */
__IOM uint32_t SHA_H4H; /* Offset: 0x038 (R/W) H4H register */
__IOM uint32_t SHA_H5H; /* Offset: 0x03c (R/W) H5H register */
__IOM uint32_t SHA_H6H; /* Offset: 0x040 (R/W) H6H register */
__IOM uint32_t SHA_H7H; /* Offset: 0x044 (R/W) H7H register */
__IOM uint32_t SHA_DATA1; /* Offset: 0x048 (R/W) DATA1 register */
uint32_t REV[15];
__IOM uint32_t SHA_DATA2; /* Offset: 0x088 (R/W) DATA2 register */
} ck_sha_reg_t;
#endif
typedef enum {
SHA_STATUS_START_END = 0, /* the one time count mode */
SHA_STATUS_START = 1, /* the first time of the cal */
SHA_STATUS_CONTINUE = 2, /* the middle stage of the cal */
SHA_STATUS_END = 3 /* the last time of the cal*/
} enum_sha_status;

View file

@ -0,0 +1,20 @@
choice
prompt "select trng type "
help
select trng type
config TRNG_CK
bool "csky trng"
help
select the ck trng driver
config TRNG_ZX29
bool "zx29 trng"
help
select the zx29 trng driver
config TRNG_XX
bool "example trng"
help
this option for test
endchoice

View file

@ -0,0 +1,233 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_trng.c
* @brief CSI Source File for TRNG Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "drv_trng.h"
#include "ck_trng.h"
#define ERR_TRNG(errno) (CSI_DRV_ERRNO_TRNG_BASE | errno)
#define TRNG_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_TRNG(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
trng_event_cb_t cb;
trng_status_t status;
} ck_trng_priv_t;
extern int32_t target_get_trng_count(void);
extern int32_t target_get_trng(int32_t idx, uint32_t *base);
static ck_trng_priv_t trng_handle[CONFIG_TRNG_NUM];
/* Driver Capabilities */
static const trng_capabilities_t driver_capabilities = {
.lowper_mode = 1 /* low power mode */
};
extern int32_t target_get_trng(int32_t idx, uint32_t *base);
extern int32_t target_get_trng_count(void);
//
// Functions
//
ck_trng_reg_t *trng_reg = NULL;
static int32_t trng_enable(void)
{
trng_reg->TCR |= TRNG_EN;
return 0;
}
static int32_t trng_get_data(void)
{
int data = trng_reg->TDR;
return data;
}
static int32_t trng_data_is_ready(void)
{
int flag = (trng_reg->TCR & TRNG_DATA_READY);
return flag;
}
/**
\brief get trng handle count.
\return trng handle count
*/
int32_t csi_trng_get_instance_count(void)
{
return target_get_trng_count();
}
/**
\brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_trng_get_instance_count()
\param[in] cb_event Pointer to \ref trng_event_cb_t
\return pointer to trng handle
*/
trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_TRNG_NUM) {
return NULL;
}
/* obtain the trng information */
uint32_t base = 0u;
int32_t real_idx = target_get_trng(idx, &base);
if (real_idx != idx) {
return NULL;
}
ck_trng_priv_t *trng_priv = &trng_handle[idx];
trng_priv->base = base;
/* initialize the trng context */
trng_reg = (ck_trng_reg_t *)(trng_priv->base);
trng_priv->cb = cb_event;
trng_priv->status.busy = 0;
trng_priv->status.data_valid = 0;
return (trng_handle_t)trng_priv;
}
/**
\brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface
\param[in] handle trng handle to operate.
\return error code
*/
int32_t csi_trng_uninitialize(trng_handle_t handle)
{
TRNG_NULL_PARAM_CHK(handle);
ck_trng_priv_t *trng_priv = handle;
trng_priv->cb = NULL;
return 0;
}
/**
\brief Get driver capabilities.
\param[in] trng handle to operate.
\return \ref trng_capabilities_t
*/
trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle)
{
return driver_capabilities;
}
/**
\brief Get data from the TRNG.
\param[in] handle trng handle to operate.
\param[out] data Pointer to buffer with data get from TRNG
\param[in] num Number of data items to obtain
\return error code
*/
int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num)
{
TRNG_NULL_PARAM_CHK(handle);
TRNG_NULL_PARAM_CHK(data);
TRNG_NULL_PARAM_CHK(num);
ck_trng_priv_t *trng_priv = handle;
trng_priv->status.busy = 1U;
trng_priv->status.data_valid = 0U;
uint8_t left_len = (uint32_t)data & 0x3;
uint32_t result = 0;
/* if the data addr is not aligned by word */
if (left_len) {
trng_enable();
while (!trng_data_is_ready());
result = trng_get_data();
/* wait the data is ready */
while (trng_data_is_ready());
if (num > (4 - left_len)) {
memcpy(data, &result, 4 - left_len);
} else {
memcpy(data, &result, num);
trng_priv->status.busy = 0U;
trng_priv->status.data_valid = 1U;
if (trng_priv->cb) {
trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
}
return 0;
}
num -= (4 - left_len);
data += (4 - left_len);
}
uint32_t word_len = num >> 2;
left_len = num & 0x3;
/* obtain the data by word */
while (word_len--) {
trng_enable();
while (!trng_data_is_ready());
result = trng_get_data();
while (trng_data_is_ready());
*(uint32_t *)data = result;
data = (void *)((uint32_t)data + 4);
}
/* if the num is not aligned by word */
if (left_len) {
trng_enable();
while (!trng_data_is_ready());
result = trng_get_data();
while (trng_data_is_ready());
memcpy(data, &result, left_len);
}
trng_priv->status.busy = 0U;
trng_priv->status.data_valid = 1U;
if (trng_priv->cb) {
trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
}
return 0;
}
/**
\brief Get TRNG status.
\param[in] handle trng handle to operate.
\return TRNG status \ref trng_status_t
*/
trng_status_t csi_trng_get_status(trng_handle_t handle)
{
ck_trng_priv_t *trng_priv = handle;
return trng_priv->status;
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_trng.h
* @brief header file for trng driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CK_TRNG_H_
#define _CK_TRNG_H_
#include "drv_trng.h"
#include "soc.h"
/*
* define the bits for TCR
*/
#define TRNG_EN (1UL << 1)
#define TRNG_LOWPER_MODE (1UL << 2)
#define TRNG_DATA_READY 1
typedef struct {
__IOM uint32_t TCR; /* Offset: 0x000 (W/R) TRNG control register */
__IM uint32_t TDR; /* Offset: 0x004 (R) TRNG Data register */
} ck_trng_reg_t;
#endif

View file

@ -0,0 +1,241 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file osr_trng.c
* @brief CSI Source File for TRNG Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "drv_trng.h"
#include "osr_trng.h"
#define ERR_TRNG(errno) (CSI_DRV_ERRNO_TRNG_BASE | errno)
#define TRNG_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_TRNG(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
uint32_t irq;
trng_event_cb_t cb;
trng_status_t status;
} osr_trng_priv_t;
extern int32_t target_get_trng(int32_t idx, uint32_t *base, uint32_t *irq);
static osr_trng_priv_t trng_handle[CONFIG_TRNG_NUM];
/* Driver Capabilities */
static const trng_capabilities_t driver_capabilities = {
.lowper_mode = 0 /* low power mode */
};
//
// Functions
//
osr_trng_reg_t *trng_reg = NULL;
static int32_t trng_disable_irq(void)
{
trng_reg->RBG_CR &= ~TRNG_IRQ_BIT;
return 0;
}
static int32_t trng_enable(void)
{
trng_reg->RBG_CR |= TRNG_EN;
return 0;
}
static int32_t trng_get_data(void)
{
int data = trng_reg->RBG_DR;
return data;
}
static int32_t trng_data_is_ready(void)
{
int flag = (trng_reg->RBG_FIFO_SR & TRNG_DATA_READY);
return flag;
}
/**
\brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function
\param[in] idx device id
\param[in] cb_event Pointer to \ref trng_event_cb_t
\return pointer to trng handle
*/
trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_TRNG_NUM) {
return NULL;
}
/* obtain the trng information */
uint32_t base = 0u;
uint32_t irq = 0u;
int32_t real_idx = target_get_trng(idx, &base, &irq);
if (real_idx != idx) {
return NULL;
}
osr_trng_priv_t *trng_priv = &trng_handle[idx];
trng_priv->base = base;
trng_priv->irq = irq;
/* initialize the trng context */
trng_reg = (osr_trng_reg_t *)(trng_priv->base);
trng_priv->cb = cb_event;
trng_priv->status.busy = 0;
trng_priv->status.data_valid = 0;
trng_disable_irq();
return (trng_handle_t)trng_priv;
}
/**
\brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface
\param[in] handle trng handle to operate.
\return error code
*/
int32_t csi_trng_uninitialize(trng_handle_t handle)
{
TRNG_NULL_PARAM_CHK(handle);
osr_trng_priv_t *trng_priv = handle;
trng_priv->cb = NULL;
return 0;
}
/**
\brief Get driver capabilities.
\param[in] idx device id.
\return \ref trng_capabilities_t
*/
//trng_capabilities_t csi_trng_get_capabilities(int32_t idx)
trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle)
{
/*
if (idx < 0 || idx >= CONFIG_TRNG_NUM) {
trng_capabilities_t ret;
memset(&ret, 0, sizeof(trng_capabilities_t));
return ret;
}*/
return driver_capabilities;
}
/**
\brief Get data from the TRNG.
\param[in] handle trng handle to operate.
\param[out] data Pointer to buffer with data get from TRNG
\param[in] num Number of data items to obtain
\return error code
*/
int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num)
{
TRNG_NULL_PARAM_CHK(handle);
TRNG_NULL_PARAM_CHK(data);
TRNG_NULL_PARAM_CHK(num);
osr_trng_priv_t *trng_priv = handle;
trng_priv->status.busy = 1U;
trng_priv->status.data_valid = 0U;
uint8_t left_len = (uint32_t)data & 0x3;
uint32_t result = 0;
trng_enable();
/* if the data addr is not aligned by word */
if (left_len) {
while (!trng_data_is_ready());
result = trng_get_data();
if (num > (4 - left_len)) {
memcpy(data, &result, 4 - left_len);
} else {
memcpy(data, &result, num);
trng_priv->status.busy = 0U;
trng_priv->status.data_valid = 1U;
if (trng_priv->cb) {
//trng_priv->cb(0, TRNG_EVENT_DATA_GENERATE_COMPLETE);
trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
}
return 0;
}
num -= (4 - left_len);
data += (4 - left_len);
}
uint32_t word_len = num >> 2;
left_len = num & 0x3;
/* obtain the data by word */
while (word_len--) {
while (!trng_data_is_ready());
result = trng_get_data();
*(uint32_t *)data = result;
data = (void *)((uint32_t)data + 4);
}
/* if the num is not aligned by word */
if (left_len) {
while (!trng_data_is_ready());
result = trng_get_data();
memcpy(data, &result, left_len);
}
trng_priv->status.busy = 0U;
trng_priv->status.data_valid = 1U;
if (trng_priv->cb) {
//trng_priv->cb(0, TRNG_EVENT_DATA_GENERATE_COMPLETE);
trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
}
return 0;
}
/**
\brief Get TRNG status.
\param[in] handle trng handle to operate.
\return TRNG status \ref trng_status_t
*/
trng_status_t csi_trng_get_status(trng_handle_t handle)
{
if (handle == NULL) {
trng_status_t ret;
memset(&ret, 0, sizeof(trng_status_t));
return ret;
}
osr_trng_priv_t *trng_priv = handle;
return trng_priv->status;
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file osr_trng.h
* @brief header file for trng driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _OSR_TRNG_H_
#define _OSR_TRNG_H_
#include "drv_trng.h"
#include "soc.h"
/*
* define the bits for TCR
*/
#define TRNG_EN (1UL << 0)
#define TRNG_DATA_READY (0xff << 16)
#define TRNG_IRQ_BIT (1UL << 24)
typedef struct {
__IOM uint32_t RBG_CR; /* Offset: 0x000 (W/R) RBG control register */
__IOM uint32_t RBG_RTCR; /* Offset: 0x004 (W/R) RBG mode selection register */
__IOM uint32_t RBG_SR; /* Offset: 0x008 (W/R) RBG status register */
__IM uint32_t RBG_DR; /* Offset: 0x00c ( /R) RBG data register */
uint32_t Reserved[4];
__IOM uint32_t RBG_FIFO_CR; /* Offset: 0x020 (W/R) FIFO control register */
__IM uint32_t RBG_FIFO_SR; /* Offset: 0x024 ( /R) FIFO status register */
} osr_trng_reg_t;
#endif

View file

@ -0,0 +1,25 @@
choice
prompt "select usart type "
help
select usart type
config USART_DW
bool "designware usart"
help
select the dw usart driver
config USART_CK
bool "csky usart"
help
select the ck usart driver
config USART_SILAN
bool "silan usart"
help
select the silan usart driver
config USART_ZX29
bool "zx29 usart"
help
select the zx29 usart driver
endchoice

View file

@ -0,0 +1,710 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_usart.c
* @brief CSI Source File for usart Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdbool.h>
#include "csi_core.h"
#include "drv_usart.h"
#include "ck_usart.h"
#include "soc.h"
#define ERR_USART(errno) (CSI_DRV_ERRNO_USART_BASE | errno)
/*
* setting config may be accessed when the USART is not
* busy(USR[0]=0) and the DLAB bit(LCR[7]) is set.
*/
#define WAIT_USART_IDLE(addr)\
do { \
int32_t timecount = 0; \
while ((addr->USR & USR_UART_BUSY) && (timecount < UART_BUSY_TIMEOUT)) {\
timecount++;\
}\
if (timecount >= UART_BUSY_TIMEOUT) {\
return ERR_USART(EDRV_TIMEOUT);\
} \
} while(0)
#define USART_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_USART(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
uint32_t irq;
usart_event_cb_t cb_event; ///< Event callback
void *cb_arg;
uint32_t rx_total_num;
uint32_t tx_total_num;
uint8_t *rx_buf;
uint8_t *tx_buf;
volatile uint32_t rx_cnt;
volatile uint32_t tx_cnt;
volatile uint32_t tx_busy;
volatile uint32_t rx_busy;
} dw_usart_priv_t;
extern int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq);
static dw_usart_priv_t usart_instance[CONFIG_USART_NUM];
static const usart_capabilities_t usart_capabilities = {
.asynchronous = 1, /* supports USART (Asynchronous) mode */
.synchronous_master = 0, /* supports Synchronous Master mode */
.synchronous_slave = 0, /* supports Synchronous Slave mode */
.single_wire = 0, /* supports USART Single-wire mode */
.event_tx_complete = 1, /* Transmit completed event */
.event_rx_timeout = 0, /* Signal receive character timeout event */
};
/**
\brief set the bautrate of usart.
\param[in] addr usart base to operate.
\param[in] baudrate.
\param[in] apbfreq the frequence of the apb.
\return error code
*/
static int32_t dw_usart_set_baudrate(dw_usart_reg_t *addr, uint32_t baudrate, uint32_t apbfreq)
{
WAIT_USART_IDLE(addr);
/* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/
uint32_t divisor = ((apbfreq * 10) / baudrate) >> 4;
if ((divisor % 10) >= 5) {
divisor = (divisor / 10) + 1;
} else {
divisor = divisor / 10;
}
addr->LCR |= LCR_SET_DLAB;
/* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/
addr->DLL = divisor & 0xff;
addr->DLH = (divisor >> 8) & 0xff;
/*
* The DLAB must be cleared after the baudrate is setted
* to access other registers.
*/
addr->LCR &= (~LCR_SET_DLAB);
return 0;
}
/**
\brief enable or disable parity.
\param[in] addr usart base to operate.
\param[in] parity ODD=8, EVEN=16, or NONE=0.
\return error code
*/
static int32_t dw_usart_set_parity(dw_usart_reg_t *addr, usart_parity_e parity)
{
WAIT_USART_IDLE(addr);
switch (parity) {
case USART_PARITY_NONE:
/*CLear the PEN bit(LCR[3]) to disable parity.*/
addr->LCR &= (~LCR_PARITY_ENABLE);
break;
case USART_PARITY_ODD:
/* Set PEN and clear EPS(LCR[4]) to set the ODD parity. */
addr->LCR |= LCR_PARITY_ENABLE;
addr->LCR &= LCR_PARITY_ODD;
break;
case USART_PARITY_EVEN:
/* Set PEN and EPS(LCR[4]) to set the EVEN parity.*/
addr->LCR |= LCR_PARITY_ENABLE;
addr->LCR |= LCR_PARITY_EVEN;
break;
default:
return ERR_USART(EDRV_USART_PARITY);
}
return 0;
}
/**
\brief set the stop bit.
\param[in] addr usart base to operate.
\param[in] stopbit two possible value: USART_STOP_BITS_1 and USART_STOP_BITS_2.
\return error code
*/
static int32_t dw_usart_set_stopbit(dw_usart_reg_t *addr, usart_stop_bits_e stopbit)
{
WAIT_USART_IDLE(addr);
switch (stopbit) {
case USART_STOP_BITS_1:
/* Clear the STOP bit to set 1 stop bit*/
addr->LCR &= LCR_STOP_BIT1;
break;
case USART_STOP_BITS_2:
/*
* If the STOP bit is set "1",we'd gotten 1.5 stop
* bits when DLS(LCR[1:0]) is zero, else 2 stop bits.
*/
addr->LCR |= LCR_STOP_BIT2;
break;
default:
return ERR_USART(EDRV_USART_STOP_BITS);
}
return 0;
}
/**
\brief the transmit data length,and we have four choices:5, 6, 7, and 8 bits.
\param[in] addr usart base to operate.
\param[in] databits the data length that user decides.
\return error code
*/
static int32_t dw_usart_set_databit(dw_usart_reg_t *addr, usart_data_bits_e databits)
{
WAIT_USART_IDLE(addr);
/* The word size decides by the DLS bits(LCR[1:0]), and the
* corresponding relationship between them is:
* DLS word size
* 00 -- 5 bits
* 01 -- 6 bits
* 10 -- 7 bits
* 11 -- 8 bits
*/
switch (databits) {
case USART_DATA_BITS_5:
addr->LCR &= LCR_WORD_SIZE_5;
break;
case USART_DATA_BITS_6:
addr->LCR &= 0xfd;
addr->LCR |= LCR_WORD_SIZE_6;
break;
case USART_DATA_BITS_7:
addr->LCR &= 0xfe;
addr->LCR |= LCR_WORD_SIZE_7;
break;
case USART_DATA_BITS_8:
addr->LCR |= LCR_WORD_SIZE_8;
break;
default:
return ERR_USART(EDRV_USART_DATA_BITS);
}
return 0;
}
/**
\brief get character in query mode.
\param[in] instance usart instance to operate.
\param[in] the pointer to the recieve charater.
\return error code
*/
int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch)
{
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
while (!(addr->LSR & LSR_DATA_READY));
*ch = addr->RBR;
return 0;
}
/**
\brief transmit character in query mode.
\param[in] instance usart instance to operate.
\param[in] ch the input charater
\return error code
*/
int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch)
{
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
while ((!(addr->LSR & DW_LSR_TRANS_EMPTY)));
addr->THR = ch;
return 0;
}
/**
\brief interrupt service function for transmitter holding register empty.
\param[in] usart_priv usart private to operate.
*/
static void dw_usart_intr_threshold_empty(dw_usart_priv_t *usart_priv)
{
if (usart_priv->tx_total_num == 0) {
return;
}
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
addr->THR = *((uint8_t *)usart_priv->tx_buf);
usart_priv->tx_cnt++;
usart_priv->tx_buf++;
if (usart_priv->tx_cnt >= usart_priv->tx_total_num) {
addr->IER &= (~IER_THRE_INT_ENABLE);
while ((!(addr->LSR & DW_LSR_TEMT)));
usart_priv->tx_cnt = 0;
usart_priv->tx_busy = 0;
usart_priv->tx_buf = NULL;
usart_priv->tx_total_num = 0;
if (usart_priv->cb_event) {
usart_priv->cb_event(USART_EVENT_SEND_COMPLETE, usart_priv->cb_arg);
}
}
}
/**
\brief interrupt service function for receiver data available.
\param[in] usart_priv usart private to operate.
*/
static void dw_usart_intr_recv_data(dw_usart_priv_t *usart_priv)
{
if (usart_priv->cb_event && (usart_priv->rx_total_num == 0)) {
usart_priv->cb_event(USART_EVENT_RECEIVED, usart_priv->cb_arg);
return;
}
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
uint8_t data = addr->RBR;
if ((usart_priv->rx_total_num == 0) || (usart_priv->rx_buf == NULL)) {
return;
}
*((uint8_t *)usart_priv->rx_buf) = data;
usart_priv->rx_cnt++;
usart_priv->rx_buf++;
if (usart_priv->rx_cnt >= usart_priv->rx_total_num) {
usart_priv->rx_cnt = 0;
usart_priv->rx_buf = NULL;
usart_priv->rx_busy = 0;
usart_priv->rx_total_num = 0;
if (usart_priv->cb_event) {
usart_priv->cb_event(USART_EVENT_RECEIVE_COMPLETE, usart_priv->cb_arg);
}
}
}
/**
\brief the interrupt service function.
\param[in] index of usart instance.
*/
void dw_usart_irqhandler(int32_t idx)
{
dw_usart_priv_t *usart_priv = &usart_instance[idx];
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
uint8_t intr_state = addr->IIR & 0xf;
switch (intr_state) {
case DW_IIR_THR_EMPTY: /* interrupt source:transmitter holding register empty */
dw_usart_intr_threshold_empty(usart_priv);
break;
case DW_IIR_RECV_DATA: /* interrupt source:receiver data available or receiver fifo trigger level reached */
dw_usart_intr_recv_data(usart_priv);
break;
default:
break;
}
}
/**
\brief Get driver capabilities.
\param[in] handle usart handle to operate.
\return \ref usart_capabilities_t
*/
usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle)
{
return usart_capabilities;
}
/**
\brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
\param[in] usart pin of tx
\param[in] usart pin of rx
\param[in] cb_event Pointer to \ref usart_event_cb_t
\return return usart handle if success
*/
usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg)
{
uint32_t base = 0u;
uint32_t irq = 0u;
int32_t idx = target_usart_init(tx, rx, &base, &irq);
if (idx < 0 || idx >= CONFIG_USART_NUM) {
return NULL;
}
dw_usart_priv_t *usart_priv = &usart_instance[idx];
usart_priv->base = base;
usart_priv->irq = irq;
usart_priv->cb_event = cb_event;
usart_priv->cb_arg = cb_arg;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
/* enable received data available */
addr->IER = IER_RDA_INT_ENABLE;
drv_nvic_enable_irq(usart_priv->irq);
return usart_priv;
}
/**
\brief De-initialize UART Interface. stops operation and releases the software resources used by the interface
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_uninitialize(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
drv_nvic_disable_irq(usart_priv->irq);
usart_priv->cb_event = NULL;
return 0;
}
/**
\brief config usart mode.
\param[in] handle usart handle to operate.
\param[in] sysclk configured system clock.
\param[in] mode \ref usart_mode_e
\param[in] parity \ref usart_parity_e
\param[in] stopbits \ref usart_stop_bits_e
\param[in] bits \ref usart_data_bits_e
\param[in] baud configured baud
\return error code
*/
int32_t csi_usart_config(usart_handle_t handle,
uint32_t sysclk,
uint32_t baud,
usart_mode_e mode,
usart_parity_e parity,
usart_stop_bits_e stopbits,
usart_data_bits_e bits)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
/* control the data_bit of the usart*/
int32_t ret = dw_usart_set_baudrate(addr, baud, sysclk);
if (ret < 0) {
return ret;
}
/* control the parity of the usart*/
ret = dw_usart_set_parity(addr, parity);
if (ret < 0) {
return ret;
}
/* control the stopbit of the usart*/
ret = dw_usart_set_stopbit(addr, stopbits);
if (ret < 0) {
return ret;
}
ret = dw_usart_set_databit(addr, bits);
if (ret < 0) {
return ret;
}
return 0;
}
/**
\brief config usart default tx value. used in syn mode
\param[in] handle usart handle to operate.
\param[in] value default tx value
\return error code
*/
int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Start sending data to UART transmitter,(received data is ignored).
The function is non-blocking,UART_EVENT_TRANSFER_COMPLETE is signaled when transfer completes.
csi_usart_get_status can indicates if transmission is still in progress or pending
\param[in] handle usart handle to operate.
\param[in] data Pointer to buffer with data to send to UART transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits,
\param[in] num Number of data items to send
\return error code
*/
int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num)
{
USART_NULL_PARAM_CHK(handle);
USART_NULL_PARAM_CHK(data);
if (num == 0) {
return ERR_USART(EDRV_PARAMETER);
}
dw_usart_priv_t *usart_priv = handle;
uint8_t *source = NULL;
source = (uint8_t *)data;
usart_priv->tx_buf = (uint8_t *)data;
usart_priv->tx_total_num = num;
usart_priv->tx_cnt = 0;
usart_priv->tx_busy = 1;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
/* enable the interrupt*/
addr->IER |= IER_THRE_INT_ENABLE;
return 0;
}
/**
\brief Abort Send data to UART transmitter
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_send(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
usart_priv->tx_cnt = usart_priv->tx_total_num;
return 0;
}
/**
\brief Start receiving data from UART receiver.transmits the default value as specified by csi_usart_set_default_tx_value
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from UART receiver
\param[in] num Number of data items to receive
\return error code
*/
int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num)
{
USART_NULL_PARAM_CHK(handle);
USART_NULL_PARAM_CHK(data);
uint8_t *dest = NULL;
dw_usart_priv_t *usart_priv = handle;
dest = (uint8_t *)data;
usart_priv->rx_buf = (uint8_t *)data; // Save receive buffer usart
usart_priv->rx_total_num = num; // Save number of data to be received
usart_priv->rx_cnt = 0;
usart_priv->rx_busy = 1;
return 0;
}
/**
\brief query data from UART receiver FIFO.
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from UART receiver
\param[in] num Number of data items to receive
\return receive fifo data num
*/
int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num)
{
USART_NULL_PARAM_CHK(handle);
USART_NULL_PARAM_CHK(data);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
int32_t recv_num = 0;
while (addr->LSR & 0x1) {
*((uint8_t *)data++) = addr->RBR;
recv_num++;
if (recv_num >= num) {
break;
}
}
return recv_num;
}
/**
\brief Abort Receive data from UART receiver
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_receive(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
usart_priv->rx_cnt = usart_priv->rx_total_num;
return 0;
}
/**
\brief Start sending/receiving data to/from UART transmitter/receiver.
\param[in] handle usart handle to operate.
\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 error code
*/
int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief abort sending/receiving data to/from USART transmitter/receiver.
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_transfer(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Get USART status.
\param[in] handle usart handle to operate.
\return USART status \ref usart_status_t
*/
usart_status_t csi_usart_get_status(usart_handle_t handle)
{
usart_status_t usart_status;
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
uint32_t line_status_reg = addr->LSR;
usart_status.tx_busy = usart_priv->tx_busy;
usart_status.rx_busy = usart_priv->rx_busy;
if (line_status_reg & DW_LSR_BI) {
usart_status.rx_break = 1;
}
if (line_status_reg & DW_LSR_FE) {
usart_status.rx_framing_error = 1;
}
if (line_status_reg & DW_LSR_PE) {
usart_status.rx_parity_error = 1;
}
return usart_status;
}
/**
\brief control the transmit.
\param[in] handle usart handle to operate.
\param[in] 1 - enable the transmitter. 0 - disable the transmitter
\return error code
*/
int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable)
{
USART_NULL_PARAM_CHK(handle);
return 0;
}
/**
\brief control the receive.
\param[in] handle usart handle to operate.
\param[in] 1 - enable the receiver. 0 - disable the receiver
\return error code
*/
int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable)
{
USART_NULL_PARAM_CHK(handle);
return 0;
}
/**
\brief control the break.
\param[in] handle usart handle to operate.
\param[in] 1- Enable continuous Break transmission,0 - disable continuous Break transmission
\return error code
*/
int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief flush receive/send data.
\param[in] handle usart handle to operate.
\param[in] type \ref usart_flush_type_e.
\return error code
*/
int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
if (type == USART_FLUSH_WRITE) {
while ((!(addr->LSR & DW_LSR_TEMT)));
} else if (type == USART_FLUSH_READ) {
while (addr->LSR & 0x1) {
addr->RBR;
}
} else {
return ERR_USART(EDRV_PARAMETER);
}
return 0;
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_usart.h
* @brief header file for usart driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef __CK_USART_H
#define __CK_USART_H
#include <stdio.h>
#include "errno.h"
#include "soc.h"
#define BAUDRATE_DEFAULT 19200
#define UART_BUSY_TIMEOUT 1000000
#define UART_RECEIVE_TIMEOUT 1000
#define UART_TRANSMIT_TIMEOUT 1000
#define UART_MAX_FIFO 0x10
/* UART register bit definitions */
#define USR_UART_BUSY 0x01
#define USR_UART_TFE 0x04
#define USR_UART_RFNE 0x08
#define LSR_DATA_READY 0x01
#define LSR_THR_EMPTY 0x20
#define IER_RDA_INT_ENABLE 0x01
#define IER_THRE_INT_ENABLE 0x02
#define IIR_NO_ISQ_PEND 0x01
#define LCR_SET_DLAB 0x80 /* enable r/w DLR to set the baud rate */
#define LCR_PARITY_ENABLE 0x08 /* parity enabled */
#define LCR_PARITY_EVEN 0x10 /* Even parity enabled */
#define LCR_PARITY_ODD 0xef /* Odd parity enabled */
#define LCR_WORD_SIZE_5 0xfc /* the data length is 5 bits */
#define LCR_WORD_SIZE_6 0x01 /* the data length is 6 bits */
#define LCR_WORD_SIZE_7 0x02 /* the data length is 7 bits */
#define LCR_WORD_SIZE_8 0x03 /* the data length is 8 bits */
#define LCR_STOP_BIT1 0xfb /* 1 stop bit */
#define LCR_STOP_BIT2 0x04 /* 1.5 stop bit */
#define DW_LSR_PFE 0x80
#define DW_LSR_TEMT 0x40
#define DW_LSR_THRE 0x40
#define DW_LSR_BI 0x10
#define DW_LSR_FE 0x08
#define DW_LSR_PE 0x04
#define DW_LSR_OE 0x02
#define DW_LSR_DR 0x01
#define DW_LSR_TRANS_EMPTY 0x20
#define DW_IIR_THR_EMPTY 0x02 /* threshold empty */
#define DW_IIR_RECV_DATA 0x04 /* received data available */
typedef struct {
union {
__IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */
__OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */
__IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */
};
union {
__IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */
__IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */
};
__IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */
__IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */
uint32_t RESERVED0;
__IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */
__IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */
uint32_t RESERVED1[24];
__IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */
} dw_usart_reg_t;
#endif /* __CK_USART_H */

View file

@ -0,0 +1,761 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_usart.c
* @brief CSI Source File for usart Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdbool.h>
#include "csi_core.h"
#include "drv_usart.h"
#include "dw_usart.h"
#include "soc.h"
#define ERR_USART(errno) (CSI_DRV_ERRNO_USART_BASE | errno)
/*
* setting config may be accessed when the USART is not
* busy(USR[0]=0) and the DLAB bit(LCR[7]) is set.
*/
#define WAIT_USART_IDLE(addr)\
do { \
int32_t timecount = 0; \
while ((addr->USR & USR_UART_BUSY) && (timecount < UART_BUSY_TIMEOUT)) {\
timecount++;\
}\
if (timecount >= UART_BUSY_TIMEOUT) {\
return ERR_USART(EDRV_TIMEOUT);\
} \
} while(0)
#define USART_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_USART(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
} dw_usart_priv_t;
extern int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq);
extern int32_t target_usart_flowctrl_init(pin_t tx_flow, pin_t rx_flow, uint32_t flag);
static dw_usart_priv_t usart_instance[CONFIG_USART_NUM];
static const usart_capabilities_t usart_capabilities = {
.asynchronous = 0, /* supports USART (Asynchronous) mode */
.synchronous_master = 0, /* supports Synchronous Master mode */
.synchronous_slave = 0, /* supports Synchronous Slave mode */
.single_wire = 0, /* supports USART Single-wire mode */
.event_tx_complete = 0, /* Transmit completed event */
.event_rx_timeout = 0, /* Signal receive character timeout event */
};
/**
\brief set the baut drate of usart.
\param[in] addr usart base to operate.
\param[in] baudrate baud rate
\param[in] apbfreq the frequency of the apb.
\return error code
*/
int32_t csi_usart_config_baudrate(usart_handle_t handle, uint32_t baudrate, uint32_t apbfreq)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
#ifdef CONFIG_CHIP_HOBBIT1_2
uint8_t data[16];
csi_usart_receive_query(handle, data, 16);
#endif
WAIT_USART_IDLE(addr);
/* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/
uint32_t divisor = ((apbfreq * 10) / baudrate) >> 4;
if ((divisor % 10) >= 5) {
divisor = (divisor / 10) + 1;
} else {
divisor = divisor / 10;
}
addr->LCR |= LCR_SET_DLAB;
/* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/
addr->DLL = divisor & 0xff;
addr->DLH = (divisor >> 8) & 0xff;
/*
* The DLAB must be cleared after the baudrate is setted
* to access other registers.
*/
addr->LCR &= (~LCR_SET_DLAB);
return 0;
}
/**
\brief config usart mode.
\param[in] handle usart handle to operate.
\param[in] mode \ref usart_mode_e
\return error code
*/
int32_t csi_usart_config_mode(usart_handle_t handle, usart_mode_e mode)
{
if (mode == USART_MODE_ASYNCHRONOUS) {
return 0;
}
return ERR_USART(EDRV_USART_MODE);
}
/**
\brief config usart parity.
\param[in] handle usart handle to operate.
\param[in] parity \ref usart_parity_e
\return error code
*/
int32_t csi_usart_config_parity(usart_handle_t handle, usart_parity_e parity)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
WAIT_USART_IDLE(addr);
switch (parity) {
case USART_PARITY_NONE:
/*CLear the PEN bit(LCR[3]) to disable parity.*/
addr->LCR &= (~LCR_PARITY_ENABLE);
break;
case USART_PARITY_ODD:
/* Set PEN and clear EPS(LCR[4]) to set the ODD parity. */
addr->LCR |= LCR_PARITY_ENABLE;
addr->LCR &= LCR_PARITY_ODD;
break;
case USART_PARITY_EVEN:
/* Set PEN and EPS(LCR[4]) to set the EVEN parity.*/
addr->LCR |= LCR_PARITY_ENABLE;
addr->LCR |= LCR_PARITY_EVEN;
break;
default:
return ERR_USART(EDRV_USART_PARITY);
}
return 0;
}
/**
\brief config usart stop bit number.
\param[in] handle usart handle to operate.
\param[in] stopbits \ref usart_stop_bits_e
\return error code
*/
int32_t dw_usart_config_stopbits(usart_handle_t handle, usart_stop_bits_e stopbit)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
WAIT_USART_IDLE(addr);
switch (stopbit) {
case USART_STOP_BITS_1:
/* Clear the STOP bit to set 1 stop bit*/
addr->LCR &= LCR_STOP_BIT1;
break;
case USART_STOP_BITS_2:
/*
* If the STOP bit is set "1",we'd gotten 1.5 stop
* bits when DLS(LCR[1:0]) is zero, else 2 stop bits.
*/
addr->LCR |= LCR_STOP_BIT2;
break;
default:
return ERR_USART(EDRV_USART_STOP_BITS);
}
return 0;
}
/**
\brief config usart data length.
\param[in] handle usart handle to operate.
\param[in] databits \ref usart_data_bits_e
\return error code
*/
int32_t csi_usart_config_databits(usart_handle_t handle, usart_data_bits_e databits)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
#ifdef CONFIG_CHIP_HOBBIT1_2
uint8_t data[16];
csi_usart_receive_query(handle, data, 16);
#endif
WAIT_USART_IDLE(addr);
/* The word size decides by the DLS bits(LCR[1:0]), and the
* corresponding relationship between them is:
* DLS word size
* 00 -- 5 bits
* 01 -- 6 bits
* 10 -- 7 bits
* 11 -- 8 bits
*/
switch (databits) {
case USART_DATA_BITS_5:
addr->LCR &= LCR_WORD_SIZE_5;
break;
case USART_DATA_BITS_6:
addr->LCR &= 0xfd;
addr->LCR |= LCR_WORD_SIZE_6;
break;
case USART_DATA_BITS_7:
addr->LCR &= 0xfe;
addr->LCR |= LCR_WORD_SIZE_7;
break;
case USART_DATA_BITS_8:
addr->LCR |= LCR_WORD_SIZE_8;
break;
default:
return ERR_USART(EDRV_USART_DATA_BITS);
}
return 0;
}
/**
\brief get character in query mode.
\param[in] handle usart handle to operate.
\param[in] the pointer to the received character if return 0.
\return error code
*/
int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch)
{
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
while (!(addr->LSR & LSR_DATA_READY));
*ch = addr->RBR;
return 0;
}
/**
\brief transmit character in query mode.
\param[in] handle usart handle to operate.
\param[in] ch the input character
\return error code
*/
int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch)
{
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
while ((!(addr->LSR & DW_LSR_TRANS_EMPTY)));
addr->THR = ch;
return 0;
}
/**
\brief the interrupt service function.
\param[in] index of usart instance.
*/
void dw_usart_irqhandler(int32_t idx)
{
(void)idx;
}
/**
\brief Get driver capabilities.
\param[in] handle usart handle to operate.
\return \ref usart_capabilities_t
*/
usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle)
{
return usart_capabilities;
}
/**
\brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
\param[in] usart pin of tx
\param[in] usart pin of rx
\param[in] cb_event Pointer to \ref usart_event_cb_t
\return return usart handle if success
*/
usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg)
{
uint32_t base = 0u;
uint32_t irq = 0u;
int32_t idx = target_usart_init(tx, rx, &base, &irq);
if (idx < 0 || idx >= CONFIG_USART_NUM) {
return NULL;
}
dw_usart_priv_t *usart_priv = &usart_instance[idx];
usart_priv->base = base;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
/* FIFO enable */
addr->FCR = DW_FCR_FIFOE | DW_FCR_RT_FIFO_HALF;
return usart_priv;
}
/**
\brief De-initialize UART Interface. stops operation and releases the software resources used by the interface
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_uninitialize(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
return 0;
}
/**
\brief config usart mode.
\param[in] handle usart handle to operate.
\param[in] sysclk configured system clock.
\param[in] baud baud rate
\param[in] mode \ref usart_mode_e
\param[in] parity \ref usart_parity_e
\param[in] stopbits \ref usart_stop_bits_e
\param[in] bits \ref usart_data_bits_e
\return error code
*/
int32_t csi_usart_config(usart_handle_t handle,
uint32_t sysclk,
uint32_t baud,
usart_mode_e mode,
usart_parity_e parity,
usart_stop_bits_e stopbits,
usart_data_bits_e bits)
{
int32_t ret;
/* control the data_bit of the usart*/
ret = csi_usart_config_baudrate(handle, baud, sysclk);
if (ret < 0) {
return ret;
}
/* control mode of the usart*/
ret = csi_usart_config_mode(handle, mode);
if (ret < 0) {
return ret;
}
/* control the parity of the usart*/
ret = csi_usart_config_parity(handle, parity);
if (ret < 0) {
return ret;
}
/* control the stopbit of the usart*/
ret = dw_usart_config_stopbits(handle, stopbits);
if (ret < 0) {
return ret;
}
ret = csi_usart_config_databits(handle, bits);
if (ret < 0) {
return ret;
}
return 0;
}
/**
\brief config usart default tx value. used in syn mode
\param[in] handle usart handle to operate.
\param[in] value default tx value
\return error code
*/
int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Start sending data to UART transmitter,(received data is ignored).
The function is non-blocking,UART_EVENT_TRANSFER_COMPLETE is signaled when transfer completes.
csi_usart_get_status can indicates if transmission is still in progress or pending
\param[in] handle usart handle to operate.
\param[in] data Pointer to buffer with data to send to UART transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits,
\param[in] num Number of data items to send
\return error code
*/
int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num)
{
USART_NULL_PARAM_CHK(handle);
USART_NULL_PARAM_CHK(data);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Abort Send data to UART transmitter
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_send(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Start receiving data from UART receiver.transmits the default value as specified by csi_usart_set_default_tx_value
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from UART receiver
\param[in] num Number of data items to receive
\return error code
*/
int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num)
{
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief query data from UART receiver FIFO.
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from UART receiver
\param[in] num Number of data items to receive
\return receive fifo data num
*/
int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num)
{
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Abort Receive data from UART receiver
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_receive(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Start sending/receiving data to/from UART transmitter/receiver.
\param[in] handle usart handle to operate.
\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 error code
*/
int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief abort sending/receiving data to/from USART transmitter/receiver.
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_transfer(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Get USART status.
\param[in] handle usart handle to operate.
\return USART status \ref usart_status_t
*/
usart_status_t csi_usart_get_status(usart_handle_t handle)
{
usart_status_t status = {0};
return status;
}
/**
\brief control the transmit.
\param[in] handle usart handle to operate.
\param[in] 1 - enable the transmitter. 0 - disable the transmitter
\return error code
*/
int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable)
{
USART_NULL_PARAM_CHK(handle);
return 0;
}
/**
\brief control the receive.
\param[in] handle usart handle to operate.
\param[in] 1 - enable the receiver. 0 - disable the receiver
\return error code
*/
int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable)
{
USART_NULL_PARAM_CHK(handle);
return 0;
}
/**
\brief control the break.
\param[in] handle usart handle to operate.
\param[in] 1- Enable continuous Break transmission,0 - disable continuous Break transmission
\return error code
*/
int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief flush receive/send data.
\param[in] handle usart handle to operate.
\param[in] type \ref usart_flush_type_e.
\return error code
*/
int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
if (type == USART_FLUSH_WRITE) {
addr->FCR |= DW_FCR_XFIFOR;
while (addr->FCR & DW_FCR_XFIFOR);
} else if (type == USART_FLUSH_READ) {
addr->FCR |= DW_FCR_RFIFOR;
while (addr->FCR & DW_FCR_RFIFOR);
} else {
return ERR_USART(EDRV_PARAMETER);
}
return 0;
}
/**
\brief control interrupt on/off.
\param[in] handle usart handle to operate.
\param[in] type \ref usart_intr_type_e.
\param[in] flag 0-OFF, 1-ON.
\return error code
*/
int32_t csi_usart_interrupt_on_off(usart_handle_t handle, usart_intr_type_e type, int flag)
{
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Get usart send data count.
\param[in] handle usart handle to operate.
\return number of data bytes transferred
*/
uint32_t csi_usart_get_tx_count(usart_handle_t handle)
{
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Get usart receive data count.
\param[in] handle usart handle to operate.
\return number of data bytes transferred
*/
uint32_t csi_usart_get_rx_count(usart_handle_t handle)
{
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief control usart power.
\param[in] handle usart handle to operate.
\param[in] state power state.\ref csi_power_stat_e.
\return error code
*/
int32_t csi_usart_power_control(usart_handle_t handle, csi_power_stat_e state)
{
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief config usart flow control type.
\param[in] handle usart handle to operate.
\param[in] flowctrl_type flow control type.\ref usart_flowctrl_type_e.
\param[in] tx_flow The TX flow pin name
\param[in] rx_flow The RX flow pin name
\return error code
*/
int32_t csi_usart_config_flowctrl(usart_handle_t handle,
usart_flowctrl_type_e flowctrl_type,
pin_t tx_flow, pin_t rx_flow)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
int32_t ret;
switch (flowctrl_type) {
case USART_FLOWCTRL_CTS:
return ERR_USART(EDRV_UNSUPPORTED);
case USART_FLOWCTRL_RTS:
return ERR_USART(EDRV_UNSUPPORTED);
case USART_FLOWCTRL_CTS_RTS:
ret = target_usart_flowctrl_init(tx_flow, rx_flow, 1);
if (ret < 0) {
return ERR_USART(EDRV_PARAMETER);
}
WAIT_USART_IDLE(addr);
addr->MCR |= DW_MCR_AFCE | DW_MCR_RTS;
break;
case USART_FLOWCTRL_NONE:
ret = target_usart_flowctrl_init(tx_flow, rx_flow, 0);
if (ret < 0) {
return ERR_USART(EDRV_PARAMETER);
}
WAIT_USART_IDLE(addr);
addr->MCR = 0;
break;
default:
return ERR_USART(EDRV_UNSUPPORTED);
}
return 0;
}
/**
\brief usart modem control.
\param[in] handle usart handle to operate.
\param[in] modem_ctrl modem control action.\ref usart_modem_ctrl_e.
\return error code
*/
int32_t csi_usart_modem_ctrl(usart_handle_t handle, usart_modem_ctrl_e modem_ctrl)
{
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief get usart modem status.
\param[in] handle usart handle to operate.
\param[in] modem_ctrl modem control action.\ref usart_modem_ctrl_e.
\return modem status.\ref usart_modem_stat_t.
*/
usart_modem_stat_t csi_usart_get_modem_stat(usart_handle_t handle)
{
usart_modem_stat_t modem_stat = {0};
return modem_stat;
}
/**
\brief config usart clock Polarity and Phase.
\param[in] handle usart handle to operate.
\param[in] cpol Clock Polarity.\ref usart_cpol_e.
\param[in] cpha Clock Phase.\ref usart_cpha_e.
\return error code
*/
int32_t csi_usart_config_clock(usart_handle_t handle, usart_cpol_e cpol, usart_cpha_e cpha)
{
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief config usart guard time.
\param[in] handle usart handle to operate.
\param[in] num_of_bits guard time in number of bit periods.
\return error code
*/
int32_t csi_usart_config_guard_time(usart_handle_t handle, uint32_t num_of_bits)
{
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief check if usart is readable(data received).
\param[in] handle usart handle to operate.
\return 1 - a character can be read, 0 if nothing to read ,negative for error code
*/
int32_t csi_usart_readable(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
if (addr->LSR & LSR_DATA_READY) {
return 1;
} else {
return 0;
}
}
/**
\brief check if usart is writable(free for data sending).
\param[in] handle usart handle to operate.
\return 1 - a character can be written, 0 - cannot be written ,negative for error code
*/
int32_t csi_usart_writable(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
if (addr->LSR & DW_LSR_TRANS_EMPTY) {
return 1;
} else {
return 0;
}
}

View file

@ -0,0 +1,116 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_usart.h
* @brief header file for usart driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef __DW_USART_H
#define __DW_USART_H
#include <stdio.h>
#include "errno.h"
#include "soc.h"
#define BAUDRATE_DEFAULT 19200
#define UART_BUSY_TIMEOUT 1000000
#define UART_RECEIVE_TIMEOUT 1000
#define UART_TRANSMIT_TIMEOUT 1000
#define UART_MAX_FIFO 0x10
/* UART register bit definitions */
#define USR_UART_BUSY 0x01
#define USR_UART_TFE 0x04
#define USR_UART_RFNE 0x08
#define LSR_DATA_READY 0x01
#define LSR_THR_EMPTY 0x20
#define IER_RDA_INT_ENABLE 0x01
#define IER_THRE_INT_ENABLE 0x02
#define IIR_NO_ISQ_PEND 0x01
#define IIR_RECV_LINE_ENABLE 0x04
#define LCR_SET_DLAB 0x80 /* enable r/w DLR to set the baud rate */
#define LCR_PARITY_ENABLE 0x08 /* parity enabled */
#define LCR_PARITY_EVEN 0x10 /* Even parity enabled */
#define LCR_PARITY_ODD 0xef /* Odd parity enabled */
#define LCR_WORD_SIZE_5 0xfc /* the data length is 5 bits */
#define LCR_WORD_SIZE_6 0x01 /* the data length is 6 bits */
#define LCR_WORD_SIZE_7 0x02 /* the data length is 7 bits */
#define LCR_WORD_SIZE_8 0x03 /* the data length is 8 bits */
#define LCR_STOP_BIT1 0xfb /* 1 stop bit */
#define LCR_STOP_BIT2 0x04 /* 1.5 stop bit */
#define DW_LSR_PFE 0x80
#define DW_LSR_TEMT 0x40
#define DW_LSR_THRE 0x40
#define DW_LSR_BI 0x10
#define DW_LSR_FE 0x08
#define DW_LSR_PE 0x04
#define DW_LSR_OE 0x02
#define DW_LSR_DR 0x01
#define DW_LSR_TRANS_EMPTY 0x20
#define DW_FCR_FIFOE 0x01
#define DW_FCR_RFIFOR 0x02
#define DW_FCR_XFIFOR 0x04
#define DW_FCR_RT_FIFO_SINGLE 0x0 << 6 /* rcvr trigger 1 character in the FIFO */
#define DW_FCR_RT_FIFO_QUARTER 0x1 << 6 /* rcvr trigger FIFO 1/4 full */
#define DW_FCR_RT_FIFO_HALF 0x2 << 6 /* rcvr trigger FIFO 1/2 full */
#define DW_FCR_RT_FIFO_LESSTWO 0x3 << 6 /* rcvr trigger FIFO 2 less than full */
#define DW_FCR_TET_FIFO_EMPTY 0x0 << 4 /* tx empty trigger FIFO empty */
#define DW_FCR_TET_FIFO_TWO 0x1 << 4 /* tx empty trigger 2 characters in the FIFO */
#define DW_FCR_TET_FIFO_QUARTER 0x2 << 4 /* tx empty trigger FIFO 1/4 full */
#define DW_FCR_TET_FIFO_HALF 0x3 << 4 /* tx empty trigger FIFO 1/2 full*/
#define DW_IIR_THR_EMPTY 0x02 /* threshold empty */
#define DW_IIR_RECV_DATA 0x04 /* received data available */
#define DW_IIR_RECV_LINE 0x06 /* receiver line status */
#define DW_IIR_CHAR_TIMEOUT 0x0c /* character timeout */
#define DW_MCR_AFCE 0x20 /* Auto Flow Control Enable */
#define DW_MCR_RTS 0x02
typedef struct {
union {
__IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */
__OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */
__IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */
};
union {
__IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */
__IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */
};
union {
__IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */
__OM uint32_t FCR; /* Offset: 0x008 ( /W) FIFO control register */
};
__IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */
__IOM uint32_t MCR; /* Offset: 0x010 (R/W) Modem control register */
__IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */
__IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */
uint32_t RESERVED1[21];
__IOM uint32_t FAR; /* Offset: 0x070 (R/W) FIFO accesss register */
__IM uint32_t TFR; /* Offset: 0x074 (R/ ) transmit FIFO read */
__OM uint32_t RFW; /* Offset: 0x078 ( /W) receive FIFO write */
__IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */
__IM uint32_t TFL; /* Offset: 0x080 (R/ ) transmit FIFO level */
__IM uint32_t RFL; /* Offset: 0x084 (R/ ) receive FIFO level */
} dw_usart_reg_t;
#endif /* __DW_USART_H */

View file

@ -0,0 +1,11 @@
choice
prompt "select wdt type "
help
select wdt type
config WDT_DW
bool "designware wdt"
help
select the dw wdt driver
endchoice

View file

@ -0,0 +1,259 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_wdt.c
* @brief CSI Source File for WDT Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdio.h>
#include "drv_wdt.h"
#include "dw_wdt.h"
#include "soc.h"
#include "csi_core.h"
#define ERR_WDT(errno) (CSI_DRV_ERRNO_WDT_BASE | errno)
static uint32_t timeout_ms[16] = {4, 7, 13, 26, 52, 105, 210, 419, 839, 1678, 3355, 6711,
13422, 26844, 53687, 107374
};
#define WDT_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_WDT(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
uint32_t irq;
wdt_event_cb_t cb_event;
} dw_wdt_priv_t;
extern int32_t target_get_wdt_count(void);
extern int32_t target_get_wdt(int32_t idx, uint32_t *base, uint32_t *irq);
static dw_wdt_priv_t wdt_instance[CONFIG_WDT_NUM];
/* Driver Capabilities */
static const wdt_capabilities_t wdt_capabilities = {
.interrupt = 1, ///< supports interrupt
};
static inline void dw_wdt_enable(dw_wdt_reg_t *addr)
{
uint32_t value = addr->WDT_CR;
value |= 1 << 0;
addr->WDT_CR = value;
}
static inline void dw_wdt_disable(dw_wdt_reg_t *addr)
{
uint32_t value = addr->WDT_CR;
value &= ~(1 << 0);
addr->WDT_CR = value;
}
void dw_wdt_irqhandler(int32_t idx)
{
dw_wdt_priv_t *wdt_priv = &wdt_instance[idx];
dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
addr->WDT_EOI;
if (wdt_priv->cb_event) {
wdt_priv->cb_event(WDT_EVENT_TIMEOUT);
}
}
/**
\brief get wdt instance count.
\return wdt instance count
*/
int32_t csi_wdt_get_instance_count(void)
{
return target_get_wdt_count();
}
/**
\brief Initialize WDT Interface. 1. Initializes the resources needed for the WDT interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_wdt_get_instance_count()
\param[in] cb_event Pointer to \ref wdt_event_cb_t
\return pointer to wdt instance
*/
wdt_handle_t csi_wdt_initialize(int32_t idx, wdt_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_WDT_NUM) {
return NULL;
}
uint32_t base = 0u;
uint32_t irq = 0u;
int32_t real_idx = target_get_wdt(idx, &base, &irq);
if (real_idx != idx) {
return NULL;
}
dw_wdt_priv_t *wdt_priv = &wdt_instance[idx];
wdt_priv->base = base;
wdt_priv->irq = irq;
wdt_priv->cb_event = cb_event;
drv_nvic_enable_irq(wdt_priv->irq);
return (wdt_handle_t)wdt_priv;
}
/**
\brief De-initialize WDT Interface. stops operation and releases the software resources used by the interface
\param[in] instance wdt instance to operate.
\return \ref execution_status
*/
int32_t csi_wdt_uninitialize(wdt_handle_t handle)
{
WDT_NULL_PARAM_CHK(handle);
dw_wdt_priv_t *wdt_priv = handle;
wdt_priv->cb_event = NULL;
drv_nvic_disable_irq(wdt_priv->irq);
return 0;
}
/**
\brief Get driver capabilities.
\param[in] wdt instance to operate.
\return \ref wdt_capabilities_t
*/
wdt_capabilities_t csi_wdt_get_capabilities(wdt_handle_t handle)
{
return wdt_capabilities;
}
/**
\brief Set the WDT value. value = (2^t*0xffff * 10^6 /freq)/10^3(t: 0 ~ 15).
\param[in] handle wdt handle to operate.
\param[in] value the timeout value(ms) \ref:timeout_ms[]
\return \ref execution_status
*/
int32_t csi_wdt_set_timeout(wdt_handle_t handle, uint32_t value)
{
WDT_NULL_PARAM_CHK(handle);
uint32_t i = 0u;
for (i = 0; i <= 15 ; i++) {
if (timeout_ms[i] == value) {
break;
}
if (i == 15) {
return ERR_WDT(EDRV_PARAMETER);
}
}
dw_wdt_priv_t *wdt_priv = handle;
dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
uint32_t config = addr->WDT_CR;
uint32_t en_stat = 0; /*origin wdt enable status*/
if ((config & 0x1) != 0) {
en_stat = 1;
}
config = 0;
addr->WDT_CR = config;
/*before configuration, must disable wdt first*/
dw_wdt_disable(addr);
i += i << 4;
addr->WDT_TORR = i;
if (en_stat == 1) {
dw_wdt_enable(addr);
csi_wdt_restart(handle);
}
return 0;
}
/**
\brief Start the WDT.
\param[in] handle wdt handle to operate.
\return \ref execution_status
*/
int32_t csi_wdt_start(wdt_handle_t handle)
{
WDT_NULL_PARAM_CHK(handle);
dw_wdt_priv_t *wdt_priv = handle;
dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
dw_wdt_enable(addr);
csi_wdt_restart(handle);
return 0;
}
/**
\brief Stop the WDT.
\param[in] handle wdt handle to operate.
\return \ref execution_status
*/
int32_t csi_wdt_stop(wdt_handle_t handle)
{
WDT_NULL_PARAM_CHK(handle);
return ERR_WDT(EDRV_UNSUPPORTED);
}
/**
\brief Restart the WDT.
\param[in] handle wdt handle to operate.
\return \ref execution_status
*/
int32_t csi_wdt_restart(wdt_handle_t handle)
{
WDT_NULL_PARAM_CHK(handle);
dw_wdt_priv_t *wdt_priv = handle;
dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
addr->WDT_CRR = DW_WDT_CRR_RESET;
return 0;
}
/**
\brief Read the WDT Current value.
\param[in] handle wdt handle to operate.
\param[in] value Pointer to the Value.
\return \ref execution_status
*/
int32_t csi_wdt_read_current_value(wdt_handle_t handle, uint32_t *value)
{
WDT_NULL_PARAM_CHK(handle);
dw_wdt_priv_t *wdt_priv = handle;
dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
*value = addr->WDT_CCVR;
return 0;
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_wdt.h
* @brief header file for wdt driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef __DW_WDT_H
#define __DW_WDT_H
#include <stdio.h>
#include "soc.h"
#define DW_WDT_CRR_RESET 0x76
typedef struct {
__IOM uint8_t WDT_CR:5; /* Offset: 0x000 (R/W) WDT control register */
uint8_t RESERVED0[3];
__IOM uint8_t WDT_TORR; /* Offset: 0x004 (R/W) WDT timeout range register */
uint8_t RESERVED1[3];
__IM uint32_t WDT_CCVR; /* Offset: 0x008 (R/ ) WDT current counter value register */
__OM uint8_t WDT_CRR:8; /* Offset: 0x00C ( /W) WDT count restart register */
uint8_t RESERVED2[3];
__IM uint8_t WDT_STAT:1; /* Offset: 0x010 (R/ ) WDT interrupt status register */
uint8_t RESERVED3[3];
__IM uint8_t WDT_EOI:1; /* Offset: 0x014 (R/ ) WDT interrupt clear register */
uint8_t RESERVED4[3];
} dw_wdt_reg_t;
#endif /* __DW_WDT_H */

View file

@ -0,0 +1,14 @@
ifeq ($(CONFIG_PLATFORM_PHOBOS), y)
include $(CSI_DIR)/csi_driver/csky/phobos/csi.mk
endif
ifeq ($(CONFIG_PLATFORM_HOBBIT1_2), y)
include $(CSI_DIR)/csi_driver/csky/hobbit1_2/csi.mk
endif
ifeq ($(CONFIG_PLATFORM_HOBBIT3), y)
include $(CSI_DIR)/csi_driver/csky/hobbit3/csi.mk
endif
include $(CSI_DIR)/csi_driver/csky/common/csi.mk

View file

@ -0,0 +1,5 @@
TEE_INC += -I$(CSI_DIR)/csi_driver/csky/hobbit1_2/include
TEE_SRC += \
$(CSI_DIR)/csi_driver/csky/hobbit1_2/devices.c \
$(CSI_DIR)/csi_driver/csky/hobbit1_2/isr.c \
$(CSI_DIR)/csi_driver/csky/hobbit1_2/pinmux.c

View file

@ -0,0 +1,829 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file devices.c
* @brief source file for the devices
* @version V1.0
* @date 24. August 2017
******************************************************************************/
#include "soc.h"
#include "config.h"
#include <drv_usart.h>
#include <drv_timer.h>
#include <drv_rtc.h>
#include <drv_trng.h>
#include <drv_crc.h>
#include <drv_aes.h>
#include <drv_rsa.h>
#include <drv_eflash.h>
#include <drv_spi.h>
#include <drv_gpio.h>
#include <stdio.h>
#include "pin_name.h"
#include "pinmux.h"
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
#if CONFIG_GPIO
struct {
uint32_t base;
uint32_t irq;
uint32_t pin_num;
port_name_t port;
}
const sg_gpio_config[CONFIG_GPIO_NUM] = {
{CSKY_GPIO0_BASE, GPIOA_IRQn, 28, PORTA},
{CSKY_GPIO1_BASE, GPIOB_IRQn, 4, PORTB},
};
typedef struct {
pin_t gpio_pin;
uint32_t cfg_idx; //idx of sg_gpio_config[]
} gpio_pin_map_t;
const static gpio_pin_map_t s_gpio_pin_map[] = {
{PA0_TRIG0_ACMP1P_TCK, 0},
{PA1_TRIG1_ACMP1N_TMS, 0},
{PA2_TXD0_SPI0MISO, 0},
{PA3_RXD0_SPI0MOSI, 0},
{PA4_CTS0_PWM0_SPI0SCK_TRIG0, 0},
{PA5_RTS0_PWM1_SPI0SSN_TRIG1, 0},
{PB0_SCL0_PWM2_I2SMCLK, 1},
{PB1_SDA0_PWM3_I2SSCK, 1},
{PB2_SPI0SCK_PWM4_I2SWS, 1},
{PB3_SPI0MISO_PWM5_I2SSD, 1},
{PA6_SPI0MOSI_PWM6_SCL0, 0},
{PA7_SPI0SSN_PWM7_SDA0, 0},
{PA8_WKUP_ADC0_ACMP0P, 0},
{PA9_BOOT_ADC1_PWMFAULT, 0},
{PA10_ADC2_TXD0, 0},
{PA11_ACMP0N_ADC3_RXD0, 0},
{PA12_PWM8_TCK_ADC4, 0},
{PA13_PWM9_TMS_ADC5, 0},
{PA14_PWM10_ADC6, 0},
{PA15_PWM11_ADC7, 0},
{PA16_RXD1_ADC8, 0},
{PA17_TXD1_ADC9, 0},
{PA18_SPI1SSN0_ACMP0O, 0},
{PA19_SPI1SSN1_ACMP1O, 0},
{PA20_SPI1SSN2_TRIG0_RXD1, 0},
{PA21_SPI1SCK_TRIG1_TXD1, 0},
{PA22_SPI1MISO_PWM0_ADC10, 0},
{PA23_SPI1MOSI_PWM1_ADC11, 0},
{PA24_TXD2_I2SMCLK_SPI1SSN0, 0},
{PA25_RXD2_I2SSCK_SPI1SSN1, 0},
{PA26_CTS2_I2SWS_ADC12, 0},
{PA27_RTS2_I2SSD_ADC13, 0}
};
int32_t target_gpio_port_init(port_name_t port, uint32_t *base, uint32_t *irq, uint32_t *pin_num)
{
int i;
for (i = 0; i < CONFIG_GPIO_NUM; i++) {
if (sg_gpio_config[i].port == port) {
*base = sg_gpio_config[i].base;
*irq = sg_gpio_config[i].irq;
*pin_num = sg_gpio_config[i].pin_num;
return i;
}
}
return -1;
}
/**
\param[in] instance idx, must not exceed return value of target_get_gpio_count()
\brief get gpio instance.
\return pointer to gpio instance
*/
int32_t target_gpio_pin_init(pin_t gpio_pin, uint32_t *port_idx)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_gpio_pin_map) / sizeof(gpio_pin_map_t); idx++) {
if (s_gpio_pin_map[idx].gpio_pin == gpio_pin) {
*port_idx = s_gpio_pin_map[idx].cfg_idx;
/*pinmux*/
pin_mux(s_gpio_pin_map[idx].gpio_pin, 0xff);
if (idx >= 10) {
return idx - 4;
} else if (idx >= 6) {
return idx - 6;
} else {
return idx;
}
}
}
return -1;
}
#endif
#if CONFIG_TIMER
struct {
uint32_t base;
uint32_t irq;
}
const sg_timer_config[CONFIG_TIMER_NUM] = {
{CSKY_TIM0_BASE, TIMA0_IRQn},
{CSKY_TIM0_BASE + 0x14, TIMA1_IRQn},
{CSKY_TIM1_BASE, TIMB0_IRQn},
{CSKY_TIM1_BASE + 0x14, TIMB1_IRQn}
};
int32_t target_get_timer_count(void)
{
return CONFIG_TIMER_NUM;
}
int32_t target_get_timer(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_timer_count()) {
return NULL;
}
*base = sg_timer_config[idx].base;
*irq = sg_timer_config[idx].irq;
return idx;
}
#endif
#if CONFIG_PMU
struct {
uint32_t base;
uint32_t irq;
}
const sg_pmu_config[CONFIG_PMU_NUM] = {
{CSKY_CLKGEN_BASE, POWM_IRQn}
};
int32_t target_get_pmu(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx > CONFIG_PMU_NUM) {
return -1;
}
*base = sg_pmu_config[idx].base;
*irq = sg_pmu_config[idx].irq;
return idx;
}
#endif
#if CONFIG_RTC
#undef CSKY_PMU_BASE
#define CSKY_PMU_BASE 0x40002000
#define BIT1 (0x1)
struct {
uint32_t base;
uint32_t irq;
}
const sg_rtc_config[CONFIG_RTC_NUM] = {
{CSKY_RTC0_BASE, RTC_IRQn},
{CSKY_RTC1_BASE, RTC1_IRQn}
};
int32_t target_get_rtc_count(void)
{
return CONFIG_RTC_NUM;
}
int32_t target_get_rtc(int32_t idx, uint32_t *base, uint32_t *irq)
{
unsigned int value;
if (idx >= target_get_rtc_count()) {
return NULL;
}
value = readl(CSKY_PMU_BASE);
value &= ~BIT1;
writel(value, CSKY_PMU_BASE);
*base = sg_rtc_config[idx].base;
*irq = sg_rtc_config[idx].irq;
return idx;
}
#endif
#if CONFIG_TRNG
struct {
uint32_t base;
}
const sg_trng_config[CONFIG_TRNG_NUM] = {
{CSKY_TRNG_BASE}
};
/**
\brief get trng instance count.
\return trng instance count
*/
int32_t target_get_trng_count(void)
{
return CONFIG_TRNG_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_trng_count()
\brief get trng instance.
\return pointer to trng instance
*/
int32_t target_get_trng(int32_t idx, uint32_t *base)
{
if (idx >= target_get_trng_count()) {
return NULL;
}
*base = sg_trng_config[idx].base;
return idx;
}
#endif
#if CONFIG_CRC
struct {
uint32_t base;
}
const sg_crc_config[CONFIG_CRC_NUM] = {
{CSKY_CRC_BASE}
};
/**
\brief get crc instance count.
\return crc instance count
*/
int32_t target_get_crc_count(void)
{
return CONFIG_CRC_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_crc_count()
\brief get crc instance.
\return pointer to crc instance
*/
int32_t target_get_crc(int32_t idx, uint32_t *base)
{
if (idx >= target_get_crc_count()) {
return NULL;
}
*base = sg_crc_config[idx].base;
return idx;
}
#endif
#if CONFIG_USART
struct {
uint32_t base;
uint32_t irq;
}
const sg_usart_config[CONFIG_USART_NUM] = {
{CSKY_UART0_BASE, UART0_IRQn},
{CSKY_UART1_BASE, UART1_IRQn},
{CSKY_UART2_BASE, UART2_IRQn},
};
typedef struct {
pin_t tx;
pin_t rx;
pin_t cts;
pin_t rts;
uint16_t cfg_idx; //idx of sg_usart_config[]
uint16_t function;
} usart_pin_map_t;
const static usart_pin_map_t s_usart_pin_map[] = {
{
PA2_TXD0_SPI0MISO,
PA3_RXD0_SPI0MOSI,
-1,
-1,
0,
0
},
{
PA10_ADC2_TXD0,
PA11_ACMP0N_ADC3_RXD0,
-1,
-1,
0,
2
},
{
PA17_TXD1_ADC9,
PA16_RXD1_ADC8,
-1,
-1,
1,
0
},
{
PA21_SPI1SCK_TRIG1_TXD1,
PA20_SPI1SSN2_TRIG0_RXD1,
-1,
-1,
1,
2,
},
{
PA24_TXD2_I2SMCLK_SPI1SSN0,
PA25_RXD2_I2SSCK_SPI1SSN1,
PA26_CTS2_I2SWS_ADC12,
PA27_RTS2_I2SSD_ADC13,
2,
0
},
};
/**
\param[in] instance idx, must not exceed return value of target_get_usart_count()
\brief get usart instance.
\return pointer to usart instance
*/
int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) {
if (s_usart_pin_map[idx].tx == tx && s_usart_pin_map[idx].rx == rx) {
*base = sg_usart_config[s_usart_pin_map[idx].cfg_idx].base;
*irq = sg_usart_config[s_usart_pin_map[idx].cfg_idx].irq;
/*pinmux*/
pin_mux(s_usart_pin_map[idx].tx, s_usart_pin_map[idx].function);
pin_mux(s_usart_pin_map[idx].rx, s_usart_pin_map[idx].function);
return s_usart_pin_map[idx].cfg_idx;
}
}
return -1;
}
/**
\brief control usart flow.
\param[in] tx_flow The TX flow pin name
\param[in] rx_flow The RX flow pin name
\param[in] flag 0-disable, 1-enable.
\return 0 if setting ready ,negative for error code
*/
int32_t target_usart_flowctrl_init(pin_t tx_flow, pin_t rx_flow, uint32_t flag)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) {
if ((s_usart_pin_map[idx].cts == tx_flow) &&(s_usart_pin_map[idx].rts == rx_flow))
break;
}
if (idx >= sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t)) {
return -1;
}
if ((s_usart_pin_map[idx].cts == tx_flow) && flag) {
pin_mux(s_usart_pin_map[idx].cts, s_usart_pin_map[idx].function);
} else if ((s_usart_pin_map[idx].cts == tx_flow) && (flag == 0)) {
pin_mux(s_usart_pin_map[idx].cts, 0xff);
} else {
return -1;
}
if ((s_usart_pin_map[idx].rts == rx_flow) && flag) {
pin_mux(s_usart_pin_map[idx].rts, s_usart_pin_map[idx].function);
} else if ((s_usart_pin_map[idx].rts == rx_flow) && (flag == 0)) {
pin_mux(s_usart_pin_map[idx].rts, 0xff);
} else {
return -1;
}
return 0;
}
#endif
#if CONFIG_SPI
struct {
uint32_t base;
uint32_t irq;
}
const sg_spi_config[CONFIG_SPI_NUM] = {
{CSKY_SPI0_BASE, SPI0_IRQn},
{CSKY_SPI1_BASE, SPI1_IRQn}
};
typedef struct {
pin_t mosi;
pin_t miso;
pin_t sclk;
pin_t ssel;
uint32_t cfg_idx; //idx of sg_iic_config[]
uint16_t function;
} spi_pin_map_t;
const static spi_pin_map_t s_spi_pin_map[] = {
{
PA2_TXD0_SPI0MISO,
PA3_RXD0_SPI0MOSI,
PA4_CTS0_PWM0_SPI0SCK_TRIG0,
PA5_RTS0_PWM1_SPI0SSN_TRIG1,
0,
2
},
{
PB3_SPI0MISO_PWM5_I2SSD,
PA6_SPI0MOSI_PWM6_SCL0,
PB2_SPI0SCK_PWM4_I2SWS,
PA7_SPI0SSN_PWM7_SDA0,
0,
0
},
{
PA22_SPI1MISO_PWM0_ADC10,
PA23_SPI1MOSI_PWM1_ADC11,
PA21_SPI1SCK_TRIG1_TXD1,
PA18_SPI1SSN0_ACMP0O,
1,
0
}
};
/**
\param[in] instance idx, must not exceed return value of target_get_spi_count()
\brief get spi instance.
\return pointer to spi instance
*/
int32_t target_spi_init(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_spi_pin_map) / sizeof(spi_pin_map_t); idx++) {
if (s_spi_pin_map[idx].mosi == mosi && s_spi_pin_map[idx].miso == miso
&& s_spi_pin_map[idx].sclk == sclk && s_spi_pin_map[idx].ssel == ssel) {
*base = sg_spi_config[s_spi_pin_map[idx].cfg_idx].base;
*irq = sg_spi_config[s_spi_pin_map[idx].cfg_idx].irq;
/*pinmux*/
pin_mux(s_spi_pin_map[idx].mosi, s_spi_pin_map[idx].function);
pin_mux(s_spi_pin_map[idx].miso, s_spi_pin_map[idx].function);
pin_mux(s_spi_pin_map[idx].sclk, s_spi_pin_map[idx].function);
pin_mux(s_spi_pin_map[idx].ssel, s_spi_pin_map[idx].function);
return s_spi_pin_map[idx].cfg_idx;
}
}
return -1;
}
#endif
#if CONFIG_AES
struct {
uint32_t base;
uint32_t irq;
}
const sg_aes_config[CONFIG_AES_NUM] = {
{CSKY_AES_BASE, AES_IRQn}
};
/**
\brief get aes instance count.
\return aes instance count
*/
int32_t target_get_aes_count(void)
{
return CONFIG_AES_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_aes_count()
\brief get aes instance.
\return pointer to aes instance
*/
int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_aes_count()) {
return NULL;
}
*base = sg_aes_config[idx].base;
*irq = sg_aes_config[idx].irq;
return idx;
}
#endif
#if CONFIG_RSA
struct {
uint32_t base;
uint32_t irq;
}
const sg_rsa_config[CONFIG_RSA_NUM] = {
{CSKY_RSA_BASE, RSA_IRQn}
};
/**
\brief get rsa instance count.
\return rsa instance count
*/
int32_t target_get_rsa_count(void)
{
return CONFIG_RSA_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_rsa_count()
\brief get rsa instance.
\return pointer to rsa instance
*/
int32_t target_get_rsa(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_rsa_count()) {
return NULL;
}
*base = sg_rsa_config[idx].base;
*irq = sg_rsa_config[idx].irq;
return idx;
}
#endif
#if CONFIG_EFLASH
struct {
uint32_t base;
eflash_info_t info;
}
const sg_eflash_config[CONFIG_EFLASH_NUM] = {
{CSKY_EFLASH_CONTROL_BASE, {0x10000000, 0x1003f800, 0x1fc}}
};
/**
\brief get eflash instance count.
\return eflash instance count
*/
int32_t target_get_eflash_count(void)
{
return CONFIG_EFLASH_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_eflash_count()
\brief get eflash instance.
\return pointer to eflash instance
*/
int32_t target_get_eflash(int32_t idx, uint32_t *base, eflash_info_t *info)
{
if (idx >= target_get_eflash_count()) {
return NULL;
}
*base = sg_eflash_config[idx].base;
info->start = sg_eflash_config[idx].info.start;
info->end = sg_eflash_config[idx].info.end;
info->sector_count = sg_eflash_config[idx].info.sector_count;
return idx;
}
#endif
#if CONFIG_WDT
struct {
uint32_t base;
uint32_t irq;
}
const sg_wdt_config[CONFIG_WDT_NUM] = {
{CSKY_WDT_BASE, WDT_IRQn}
};
int32_t target_get_wdt_count(void)
{
return CONFIG_WDT_NUM;
}
int32_t target_get_wdt(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_wdt_count()) {
return NULL;
}
*base = sg_wdt_config[idx].base;
*irq = sg_wdt_config[idx].irq;
return idx;
}
#endif
#if CONFIG_DMAC
struct {
uint32_t base;
uint32_t irq;
}
const sg_dmac_config[CONFIG_DMAC_NUM] = {
{CSKY_DMAC0_BASE, SEU_DMAC_IRQn},
{CSKY_DMAC1_BASE, NONSEU_DMAC_IRQn}
};
int32_t target_get_dmac_count(void)
{
return CONFIG_DMAC_NUM;
}
int32_t target_get_dmac(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_dmac_count()) {
return NULL;
}
*base = sg_dmac_config[idx].base;
*irq = sg_dmac_config[idx].irq;
return idx;
}
#endif
#if CONFIG_IIC
struct {
uint32_t base;
uint32_t irq;
}
const sg_iic_config[CONFIG_IIC_NUM] = {
{CSKY_I2C0_BASE, I2C0_IRQn},
{CSKY_I2C1_BASE, I2C1_IRQn}
};
typedef struct {
pin_t scl;
pin_t sda;
uint16_t cfg_idx; //idx of sg_iic_config[]
uint16_t function;
} iic_pin_map_t;
const static iic_pin_map_t s_iic_pin_map[] = {
{
PB0_SCL0_PWM2_I2SMCLK,
PB1_SDA0_PWM3_I2SSCK,
0,
0
},
{
PA6_SPI0MOSI_PWM6_SCL0,
PA7_SPI0SSN_PWM7_SDA0,
0,
2
},
{
PC0_SCL1_CTS1_PWM10_ADC14,
PC1_SDA1_RTS1_PWM11_ADC15,
1,
0
}
};
/**
\param[in] instance idx, must not exceed return value of target_get_iic_count()
\brief get iic instance.
\return pointer to iic instance
*/
int32_t target_iic_init(pin_t scl, pin_t sda, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_iic_pin_map) / sizeof(iic_pin_map_t); idx++) {
if (s_iic_pin_map[idx].scl == scl && s_iic_pin_map[idx].sda == sda) {
*base = sg_iic_config[s_iic_pin_map[idx].cfg_idx].base;
*irq = sg_iic_config[s_iic_pin_map[idx].cfg_idx].irq;
/*pinmux*/
if (s_iic_pin_map[idx].cfg_idx == 0) {
pin_mux(s_iic_pin_map[idx].scl, s_iic_pin_map[idx].function);
pin_mux(s_iic_pin_map[idx].sda, s_iic_pin_map[idx].function);
}
return s_iic_pin_map[idx].cfg_idx;
}
}
return -1;
}
#endif
#if CONFIG_PWM
struct {
uint32_t base;
uint32_t irq;
}
const sg_pwm_config[CONFIG_PWM_NUM] = {
{CSKY_PWM_BASE, PWM_IRQn},
};
typedef struct {
pin_t pwm_pin;
uint32_t cfg_idx; //idx of sg_pwm_config[]
uint32_t ch_num;
uint16_t function;
} pwm_pin_map_t;
const static pwm_pin_map_t s_pwm_pin_map[] = {
{PA4_CTS0_PWM0_SPI0SCK_TRIG0, 0, 0, 1},
{PA5_RTS0_PWM1_SPI0SSN_TRIG1, 0, 0, 1},
{PB0_SCL0_PWM2_I2SMCLK, 0, 1, 1},
{PB1_SDA0_PWM3_I2SSCK, 0, 1, 1},
{PB2_SPI0SCK_PWM4_I2SWS, 0, 2, 1},
{PB3_SPI0MISO_PWM5_I2SSD, 0, 2, 1},
{PA6_SPI0MOSI_PWM6_SCL0, 0, 3, 1},
{PA7_SPI0SSN_PWM7_SDA0, 0, 3, 1},
{PA12_PWM8_TCK_ADC4, 0, 4, 0},
{PA13_PWM9_TMS_ADC5, 0, 4, 0},
{PA14_PWM10_ADC6, 0, 5, 0},
{PA15_PWM11_ADC7, 0, 5, 0},
{PA22_SPI1MISO_PWM0_ADC10, 0, 0, 1},
{PA23_SPI1MOSI_PWM1_ADC11, 0, 0, 1},
{PC0_SCL1_CTS1_PWM10_ADC14, 0, 5, 2},
{PC1_SDA1_RTS1_PWM11_ADC15, 0, 5, 2}
};
/**
\param[in] instance idx, must not exceed return value of target_get_pwm_count()
\brief get pwm instance.
\return pointer to pwm instance
*/
int32_t target_pwm_init(pin_t pwm_pin, uint32_t *ch_num, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_pwm_pin_map) / sizeof(pwm_pin_map_t); idx++) {
if (s_pwm_pin_map[idx].pwm_pin == pwm_pin) {
*base = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].base;
*irq = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].irq;
*ch_num = s_pwm_pin_map[idx].ch_num;
/*pinmux*/
pin_mux(s_pwm_pin_map[idx].pwm_pin, s_pwm_pin_map[idx].function);
return s_pwm_pin_map[idx].cfg_idx;
}
}
return -1;
}
#endif
#if CONFIG_SHA
struct {
uint32_t base;
uint32_t irq;
}
const sg_sha_config[CONFIG_SHA_NUM] = {
{CSKY_SHA_BASE, SHA_IRQn}
};
/**
\brief get sha instance count.
\return sha instance count
*/
int32_t target_get_sha_count(void)
{
return CONFIG_SHA_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_sha_count()
\brief get sha instance.
\return pointer to sha instance
*/
int32_t target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_sha_count()) {
return NULL;
}
*base = sg_sha_config[idx].base;
*irq = sg_sha_config[idx].irq;
return idx;
}
#endif

View file

@ -0,0 +1,68 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_sys_freq.h
* @brief header file for setting system frequency.
* @version V1.0
* @date 18. July 2017
******************************************************************************/
#ifndef _CK_SYS_FREQ_H_
#define _CK_SYS_FREQ_H_
#include <stdint.h>
#include "soc.h"
#define PMU_MCLK_SEL (CSKY_CLKGEN_BASE + 0x4)
#define MCLK_REG_VAL 0x8UL
#define PMU_CLK_STABLE (CSKY_CLKGEN_BASE + 0x18)
#define PMU_PLL_CTRL (CSKY_CLKGEN_BASE + 0x2c)
#define TRC_ADDR (CSKY_OTP_BASE + 0x20)
#define TRC_REG_VAL 0x1UL
#define EXTERNAL_CLK_SOURCE 0x8UL
#define EXTERNAL_CLK_16M (EXTERNAL_CLK_SOURCE * 2)
#define EXTERNAL_CLK_24M (EXTERNAL_CLK_SOURCE * 3)
#define EXTERNAL_CLK_32M (EXTERNAL_CLK_SOURCE * 4)
#define EXTERNAL_CLK_40M (EXTERNAL_CLK_SOURCE * 5)
#define EXTERNAL_CLK_48M (EXTERNAL_CLK_SOURCE * 6)
#define CLK_8M_REG_VAL 0xc0202UL
#define CLK_16M_REG_VAL 0xc0204UL
#define CLK_24M_REG_VAL 0xc0206UL
#define CLK_32M_REG_VAL 0xc0208UL
#define CLK_40M_REG_VAL 0xc020aUL
#define CLK_48M_REG_VAL 0xc020cUL
typedef enum {
IHS_CLK = 0, //internal high speed clock
EHS_CLK = 1 //external high speed clock
} clk_gen_t;
typedef enum {
CLK_8M = 0,
CLK_16M = 1,
CLK_24M = 2,
CLK_32M = 3,
CLK_40M = 4,
CLK_48M = 5
} clk_val_t;
void ck_set_sys_freq (clk_gen_t source, clk_val_t val);
#endif /* _CK_SYS_FREQ_H_ */

View file

@ -0,0 +1,83 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file pin_name.h
* @brief header file for the pin_name
* @version V1.0
* @date 23. August 2017
******************************************************************************/
#ifndef _PINNAMES_H
#define _PINNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PA0_TRIG0_ACMP1P_TCK = 0,
PA1_TRIG1_ACMP1N_TMS,
PA2_TXD0_SPI0MISO,
PA3_RXD0_SPI0MOSI,
PA4_CTS0_PWM0_SPI0SCK_TRIG0,
PA5_RTS0_PWM1_SPI0SSN_TRIG1,
PB0_SCL0_PWM2_I2SMCLK,
PB1_SDA0_PWM3_I2SSCK,
PB2_SPI0SCK_PWM4_I2SWS,
PB3_SPI0MISO_PWM5_I2SSD,
PA6_SPI0MOSI_PWM6_SCL0,
PA7_SPI0SSN_PWM7_SDA0,
PA8_WKUP_ADC0_ACMP0P,
PA9_BOOT_ADC1_PWMFAULT,
PA10_ADC2_TXD0,
PA11_ACMP0N_ADC3_RXD0,
PA12_PWM8_TCK_ADC4,
PA13_PWM9_TMS_ADC5,
PA14_PWM10_ADC6,
PA15_PWM11_ADC7,
PA16_RXD1_ADC8,
PA17_TXD1_ADC9,
PA18_SPI1SSN0_ACMP0O,
PA19_SPI1SSN1_ACMP1O,
PA20_SPI1SSN2_TRIG0_RXD1,
PA21_SPI1SCK_TRIG1_TXD1,
PA22_SPI1MISO_PWM0_ADC10,
PA23_SPI1MOSI_PWM1_ADC11,
PA24_TXD2_I2SMCLK_SPI1SSN0,
PA25_RXD2_I2SSCK_SPI1SSN1,
PA26_CTS2_I2SWS_ADC12,
PA27_RTS2_I2SSD_ADC13,
PC0_SCL1_CTS1_PWM10_ADC14,
PC1_SDA1_RTS1_PWM11_ADC15,
}
pin_name_t;
typedef enum {
PORTA = 0,
PORTB = 1,
} port_name_t;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,122 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file pinmux.h
* @brief Header file for the pinmux
* @version V1.0
* @date 23. August 2017
******************************************************************************/
#ifndef HOBBIT1_2_PINMUX_H
#define HOBBIT1_2_PINMUX_H
#include <stdint.h>
#include "pin_name.h"
void hobbit_ioreuse_initial(void);
int32_t pin_mux(pin_name_t pin, uint16_t function);
/*IOMUX0L function definition */
/* IOMUX0H function definition */
#define PA16_UART1_RX 0x00010000
#define PA17_UART1_TX 0x00020000
#define PA20_UART1_RX 0x00020000
#define PA21_UART1_TX 0x00080000
//use for spi eth
#define PA3_SPI0MOSI 0x00000080
#define PA2_SPI0MISO 0x00000020
#define PA4_SPI0SCK 0x00000200
#define PA5_SPI0SSN 0x00000800
#define PA23_SPI1MOSI 0x00800000
#define PA22_SPI1MISO 0x00400000
#define PA21_SPI1SCK 0x00200000
#define PA18_SPI1SSN0 0x00040000
/* IOMUX1L function definition */
/* flag as identification */
#define GPIO_SET_BIT0 0x00000001
#define GPIO_SET_BIT1 0x00000002
#define GPIO_SET_BIT2 0x00000004
#define GPIO_SET_BIT3 0x00000008
#define GPIO_SET_BIT4 0x00000010
#define GPIO_SET_BIT5 0x00000020
#define GPIO_SET_BIT6 0x00000040
#define GPIO_SET_BIT7 0x00000080
#define GPIO_SET_BIT8 0x00000100
#define GPIO_SET_BIT9 0x00000200
#define GPIO_SET_BIT10 0x00000400
#define GPIO_SET_BIT11 0x00000800
#define GPIO_SET_BIT12 0x00001000
#define GPIO_SET_BIT13 0x00002000
#define GPIO_SET_BIT14 0x00004000
#define GPIO_SET_BIT15 0x00008000
#define GPIO_SET_BIT16 0x00010000
#define GPIO_SET_BIT17 0x00020000
#define GPIO_SET_BIT18 0x00040000
#define GPIO_SET_BIT19 0x00080000
#define GPIO_SET_BIT20 0x00100000
#define GPIO_SET_BIT21 0x00200000
#define GPIO_SET_BIT22 0x00400000
#define GPIO_SET_BIT23 0x00800000
#define GPIO_SET_BIT24 0x01000000
#define GPIO_SET_BIT25 0x02000000
#define GPIO_SET_BIT26 0x04000000
#define GPIO_SET_BIT27 0x08000000
#define GPIO_SET_BIT28 0x10000000
#define GPIO_SET_BIT29 0x20000000
#define GPIO_SET_BIT30 0x40000000
#define GPIO_SET_BIT31 0x80000000
/******************************************************************************
* hobbit1_2 gpio control and gpio reuse function
* selecting regester adddress
******************************************************************************/
#define HOBBIT1_2_GIPO0_PORTCTL_REG 0x50006008
#define HOBBIT1_2_GIPO1_PORTCTL_REG 0x50009008
#define HOBBIT1_2_IOMUX0L_REG 0x50006100
#define HOBBIT1_2_IOMUX0H_REG 0x50006104
#define HOBBIT1_2_IOMUX1L_REG 0x50006108
/*************basic gpio reuse v1.0********************************************
* UART1(PA16,PA17) for bootrom
* UART1(PA20,PA21) for console
******************************************************************************/
#define GPIO0_REUSE_EN (0x00000000)
#define GPIO0_REUSE_DIS (GPIO_SET_BIT16 | GPIO_SET_BIT17)
#define GPIO1_REUSE_EN (0x00000000)
#define IOMUX0L_FUNCTION_SEL (0x00000000)
#define IOMUX0H_FUNCTION_SEL (0x00000000)
#define IOMUX1L_FUNCTION_SEL (0x00000000)
#endif /* HOBBIT_PINMUX_H */

View file

@ -0,0 +1,333 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**************************************************************************//**
* @file soc.h
* @brief CSI Core Peripheral Access Layer Header File for
* CSKYSOC Device Series
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef SOC_H
#define SOC_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SYSTEM_CLOCK
#define SYSTEM_CLOCK (24000000)
#endif
#ifndef IHS_VALUE
#define IHS_VALUE (8000000)
#endif
#ifndef EHS_VALUE
#define EHS_VALUE (8000000)
#endif
/* ------------------------- Interrupt Number Definition ------------------------ */
typedef enum IRQn
{
/* ---------------------- CSKYCK801 Specific Interrupt Numbers --------------------- */
GPIOA_IRQn = 0, /* gpio Interrupt */
CORET_IRQn = 1, /* core Timer Interrupt */
TIMA0_IRQn = 2, /* timerA0 Interrupt */
TIMA1_IRQn = 3, /* timerA1 Interrupt */
I2S_IRQn = 4, /* i2s Interrupt */
WDT_IRQn = 5, /* wdt Interrupt */
UART0_IRQn = 6, /* uart0 Interrupt */
UART1_IRQn = 7, /* uart1 Interrupt */
UART2_IRQn = 8, /* uart2 Interrupt */
I2C0_IRQn = 9, /* i2c0 Interrupt */
I2C1_IRQn = 10, /* i2c1 Interrupt */
SPI1_IRQn = 11, /* spi0 Interrupt */
SPI0_IRQn = 12, /* spi1 Interrupt */
RTC_IRQn = 13, /* rtc Interrupt */
EXTWAK_IRQn = 14, /* extwakeup Interrupt */
ADC_IRQn = 15, /* adc interrupt */
CMP_IRQn = 16, /* cmp interrupt */
SEU_DMAC_IRQn = 17, /* seu dmac Interrupt */
POWM_IRQn = 18, /* powm Interrupt */
PWM_IRQn = 19, /* pwm Interrupt */
SYS_RESET_IRQn = 20, /* system reset Interrupt */
REV_IRQn = 21, /* rev Interrupt */
NONSEU_DMAC_IRQn = 22, /* nonuseu dmac Interrupt */
TIMB0_IRQn = 23, /* timerB0 Interrupt */
TIMB1_IRQn = 24, /* timerB1 Interrupt */
RTC1_IRQn = 25, /* rtc1 Interrupt */
AES_IRQn = 26, /* aes Interrupt */
GPIOB_IRQn = 27, /* trng Interrupt */
RSA_IRQn = 28, /* rsa Interrupt */
SHA_IRQn = 29, /* sha Interrupt */
}
IRQn_Type;
/* ================================================================================ */
/* ================ Processor and Core Peripheral Section ================ */
/* ================================================================================ */
/* -------- Configuration of the CK801 Processor and Core Peripherals ------- */
#define __CK802_REV 0x0000U /* Core revision r0p0 */
#define __MGU_PRESENT 0 /* MGU present or not */
#define __NVIC_PRIO_BITS 2 /* Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */
#include "core_ck802.h" /* Processor and core peripherals */
#include "stdint.h"
typedef enum {
CKENUM_DMA_UART0_RX,
CKENUM_DMA_UART0_TX,
CKENUM_DMA_UART1_RX,
CKENUM_DMA_UART1_TX,
CKENUM_DMA_ADC_RX,
CKENUM_DMA_ADC_TX,
CKENUM_DMA_SPI1_RX,
CKENUM_DMA_SPI1_TX,
CKENUM_DMA_SPI0_RX,
CKENUM_DMA_SPI0_TX,
CKENUM_DMA_IIC_RX,
CKENUM_DMA_IIC_TX,
CKENUM_DMA_IIC1_RX,
CKENUM_DMA_IIC1_TX,
CKENUM_DMA_IIS_RX,
CKENUM_DMA_IIS_TX,
CKENUM_DMA_MEMORY
} ckenum_dma_device_e;
/* ================================================================================ */
/* ================ Device Specific Peripheral Section ================ */
/* ================================================================================ */
#if 0
/* ================================================================================ */
/* ============== Universal Asyncronous Receiver / Transmitter (UART) ============= */
/* ================================================================================ */
typedef struct {
union {
__IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */
__OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */
__IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */
};
union {
__IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */
__IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */
};
__IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */
__IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */
__IOM uint32_t MCR; /* Offset: 0x010 (R/W) Modem control register */
__IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */
__IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */
uint32_t RESERVED1[24];
__IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */
} CSKY_UART_TypeDef;
/* ================================================================================ */
/* ============== Inter-Integrated Circuit (IIC) ============= */
/* ================================================================================ */
typedef struct {
__IOM uint32_t IC_CON; /* Offset: 0x000 (R/W) Receive buffer register */
__IOM uint32_t IC_TAR; /* Offset: 0x004 (R/W) Transmission hold register */
__IOM uint32_t IC_SAR; /* Offset: 0x008 (R/W) Clock frequency division low section register */
__IOM uint32_t IC_HS_MADDR; /* Offset: 0x00c (R/W) Clock frequency division high section register */
__IOM uint32_t IC_DATA_CMD; /* Offset: 0x010 (R/W) Interrupt enable register */
__IOM uint32_t IC_SS_SCL_HCNT; /* Offset: 0x014 (R/W) Interrupt indicia register */
__IOM uint32_t IC_SS_SCL_LCNT; /* Offset: 0x018 (R/W) Transmission control register */
__IOM uint32_t IC_FS_SCL_HCNT; /* Offset: 0x01c (R/W) Modem control register */
__IOM uint32_t IC_FS_SCL_LCNT; /* Offset: 0x020 (R/W) Transmission state register */
__IOM uint32_t IC_HS_SCL_HCNT; /* Offset: 0x024 (R/W) Transmission state register */
__IOM uint32_t IC_HS_SCL_LCNT; /* Offset: 0x028 (R/W) Transmission state register */
__IOM uint32_t IC_INTR_STAT; /* Offset: 0x02c (R) Transmission state register */
__IOM uint32_t IC_INTR_MASK; /* Offset: 0x030 (R/W) Transmission state register */
__IOM uint32_t IC_RAW_INTR_STAT; /* Offset: 0x034 (R) Transmission state register */
__IOM uint32_t IC_RX_TL; /* Offset: 0x038 (R/W) Transmission state register */
__IOM uint32_t IC_TX_TL; /* Offset: 0x03c (R/W) Transmission state register */
__IOM uint32_t IC_CLR_INTR; /* Offset: 0x040 (R) Transmission state register */
__IOM uint32_t IC_CLR_RX_UNDER; /* Offset: 0x044 (R) Transmission state register */
__IOM uint32_t IC_CLR_RX_OVER; /* Offset: 0x048 (R) Transmission state register */
__IOM uint32_t IC_CLR_TX_OVER; /* Offset: 0x04c (R) Transmission state register */
__IOM uint32_t IC_CLR_RD_REQ; /* Offset: 0x050 (R) Transmission state register */
__IOM uint32_t IC_CLR_TX_ABRT; /* Offset: 0x054 (R) Transmission state register */
__IOM uint32_t IC_CLR_RX_DONE; /* Offset: 0x058 (R) Transmission state register */
__IOM uint32_t IC_CLR_ACTIVITY; /* Offset: 0x05c (R) Transmission state register */
__IOM uint32_t IC_CLR_STOP_DET; /* Offset: 0x060 (R) Transmission state register */
__IOM uint32_t IC_CLR_START_DET; /* Offset: 0x064 (R) Transmission state register */
__IOM uint32_t IC_CLR_GEN_CALL; /* Offset: 0x068 (R) Transmission state register */
__IOM uint32_t IC_ENABLE; /* Offset: 0x06c (R/W) Transmission state register */
__IOM uint32_t IC_STATUS; /* Offset: 0x070 (R) Transmission state register */
__IOM uint32_t IC_TXFLR; /* Offset: 0x074 (R) Transmission state register */
__IOM uint32_t IC_RXFLR; /* Offset: 0x078 (R) Transmission state register */
uint32_t RESERVED; /* Offset: 0x014 (R/ ) Transmission state register */
__IOM uint32_t IC_TX_ABRT_SOURCE; /* Offset: 0x080 (R/W) Transmission state register */
__IOM uint32_t IC_SAR1; /* Offset: 0x084 (R/W) Transmission state register */
__IOM uint32_t IC_DMA_CR; /* Offset: 0x088 (R/W) Transmission state register */
__IOM uint32_t IC_DMA_TDLR; /* Offset: 0x08c (R/W) Transmission state register */
__IOM uint32_t IC_DMA_RDLR; /* Offset: 0x090 (R/W) Transmission state register */
__IOM uint32_t IC_SAR2; /* Offset: 0x094 (R/W) Transmission state register */
__IOM uint32_t IC_SAR3; /* Offset: 0x098 (R/W) Transmission state register */
__IOM uint32_t IC_MULTI_SLAVE; /* Offset: 0x09c (R/W) Transmission state register */
__IOM uint32_t IC_GEN_CALL_EN; /* Offset: 0x0a0 (R/W) Transmission state register */
} CSKY_IIC_TypeDef;
/* ================================================================================ */
/* ============== TIMER ============= */
/* ================================================================================ */
typedef struct {
__IOM uint32_t TxLoadCount; /* Offset: 0x000 (R/W) Receive buffer register */
__IOM uint32_t TxCurrentValue; /* Offset: 0x004 (R) Transmission hold register */
__IOM uint32_t TxControl; /* Offset: 0x008 (R/W) Clock frequency division low section register */
__IOM uint32_t TxEOI; /* Offset: 0x00c (R) Clock frequency division high section register */
__IOM uint32_t TxIntStatus; /* Offset: 0x010 (R) Interrupt enable register */
} CSKY_TIMER_TypeDef;
/* ================================================================================ */
/* ============== TIMER Control ============= */
/* ================================================================================ */
typedef struct {
__IOM uint32_t TimersIntStatus; /* Offset: 0x000 (R) Interrupt indicia register */
__IOM uint32_t TimerEOI; /* Offset: 0x004 (R) Transmission control register */
__IOM uint32_t TimerRawIntStatus; /* Offset: 0x008 (R) Modem control register */
} CSKY_TIMER_Control_TypeDef;
/* ================================================================================ */
/* ============== GPIO ============= */
/* ================================================================================ */
typedef struct {
__IOM uint32_t SWPORT_DR; /* Offset: 0x000 (R/W) Interrupt indicia register */
__IOM uint32_t SWPORT_DDR; /* Offset: 0x004 (R/W) Interrupt indicia register */
__IOM uint32_t PORT_CTL; /* Offset: 0x008 (R/W) Interrupt indicia register */
} CKStruct_GPIO, *PCKStruct_GPIO;
typedef struct {
__IOM uint32_t SHA_CON; /* Offset: 0x000 (R/W) Control register */
__IOM uint32_t SHA_INTSTATE; /* Offset: 0x004 (R/W) Instatus register */
__IOM uint32_t SHA_H0L; /* Offset: 0x008 (R/W) H0L register */
__IOM uint32_t SHA_H1L; /* Offset: 0x00c (R/W) H1L register */
__IOM uint32_t SHA_H2L; /* Offset: 0x010 (R/W) H2L register */
__IOM uint32_t SHA_H3L; /* Offset: 0x014 (R/W) H3L register */
__IOM uint32_t SHA_H4L; /* Offset: 0x018 (R/W) H4L register */
__IOM uint32_t SHA_H5L; /* Offset: 0x01c (R/W) H5L register */
__IOM uint32_t SHA_H6L; /* Offset: 0x020 (R/W) H6L register */
__IOM uint32_t SHA_H7L; /* Offset: 0x024 (R/W) H7L register */
__IOM uint32_t SHA_H0H; /* Offset: 0x028 (R/W) H0H register */
__IOM uint32_t SHA_H1H; /* Offset: 0x02c (R/W) H1H register */
__IOM uint32_t SHA_H2H; /* Offset: 0x030 (R/W) H2H register */
__IOM uint32_t SHA_H3H; /* Offset: 0x034 (R/W) H3H register */
__IOM uint32_t SHA_H4H; /* Offset: 0x038 (R/W) H4H register */
__IOM uint32_t SHA_H5H; /* Offset: 0x03c (R/W) H5H register */
__IOM uint32_t SHA_H6H; /* Offset: 0x040 (R/W) H6H register */
__IOM uint32_t SHA_H7H; /* Offset: 0x044 (R/W) H7H register */
__IOM uint32_t SHA_DATA1; /* Offset: 0x048 (R/W) DATA1 register */
uint32_t REV[15];
__IOM uint32_t SHA_DATA2; /* Offset: 0x088 (R/W) DATA2 register */
} CSKY_SHA_TypeDef;
#endif
#define CONFIG_PMU_NUM 1
#define CONFIG_CRC_NUM 1
#define CONFIG_EFLASH_NUM 1
#define CONFIG_IIC_NUM 2
#define CONFIG_TRNG_NUM 1
#define CONFIG_AES_NUM 1
#define CONFIG_RSA_NUM 1
#define CONFIG_SHA_NUM 1
#define CONFIG_SPI_NUM 2
#define CONFIG_PWM_NUM 6
#define CONFIG_TIMER_NUM 4
#define CONFIG_RTC_NUM 2
#define CONFIG_WDT_NUM 1
#define CONFIG_DMAC_NUM 2
#define CONFIG_GPIO_NUM 2
#define CONFIG_GPIO_PIN_NUM 32
#define CONFIG_USART_NUM 3
#define CONFIG_ETH_NUM 2
/* ================================================================================ */
/* ================ Peripheral memory map ================ */
/* ================================================================================ */
/* -------------------------- CHIP memory map ------------------------------- */
#define CSKY_EFLASH_BASE (0x10000000UL)
#define CSKY_SRAM_BASE (0x60000000UL)
/* AHB */
#define CSKY_AHB_ARB_BASE (0x40000000UL)
#define CSKY_DMAC0_BASE (0x40001000UL)
#define CSKY_CLKGEN_BASE (0x40002000UL)
#define CSKY_CRC_BASE (0x40003000UL)
#define CSKY_DMAC1_BASE (0x40004000UL)
#define CSKY_OTP_BASE (0x4003F000UL)
#define CSKY_AES_BASE (0x40006000UL)
#define CSKY_SRAM_SASC_BASE (0x40007000UL)
#define CSKY_SHA_BASE (0x40008000UL)
#define CSKY_TRNG_BASE (0x40009000UL)
#define CSKY_RSA_BASE (0x4000a000UL)
#define CSKY_EFLASH_CONTROL_BASE (0x4003f000UL)
#define CSKY_APB0_BRIDGE_BASE (0x50000000UL)
#define CSKY_APB1_BRIDGE_BASE (0x50010000UL)
/* APB0 */
#define CSKY_WDT_BASE (0x50001000UL)
#define CSKY_SPI0_BASE (0x50002000UL)
#define CSKY_RTC0_BASE (0x50003000UL)
#define CSKY_UART0_BASE (0x50004000UL)
#define CSKY_UART1_BASE (0x50005000UL)
#define CSKY_GPIO0_BASE (0x50006000UL)
#define CSKY_I2C0_BASE (0x50007000UL)
#define CSKY_I2S_BASE (0x50008000UL)
#define CSKY_GPIO1_BASE (0x50009000UL)
#define CSKY_SIPC_BASE (0x5000a000UL)
/* APB1 */
#define CSKY_TIM0_BASE (0x50011000UL)
#define CSKY_SPI1_BASE (0x50012000UL)
#define CSKY_I2C1_BASE (0x50013000UL)
#define CSKY_PWM_BASE (0x50014000UL)
#define CSKY_UART2_BASE (0x50015000UL)
#define CSKY_ADC_CTL_BASE (0x50016000UL)
#define CSKY_CMP_CTL_BASE (0x50017000UL)
#define CSKY_ETB_BASE (0x50018000UL)
#define CSKY_TIM1_BASE (0x50019000UL)
#define CSKY_RTC1_BASE (0x5001a000UL)
#define SHA_CONTEXT_SIZE 224
/* ================================================================================ */
/* ================ Peripheral declaration ================ */
/* ================================================================================ */
#define CSKY_UART1 (( CSKY_UART_TypeDef *) CSKY_UART1_BASE)
#define CSKY_SHA (( CSKY_SHA_TypeDef *) CSKY_SHA_BASE)
#include <config.h>
#ifdef __cplusplus
}
#endif
#endif /* SOC_H */

View file

@ -0,0 +1,229 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file isr.c
* @brief source file for the interrupt server route
* @version V1.0
* @date 25. August 2017
******************************************************************************/
#include <drv_common.h>
#include "config.h"
#include "soc.h"
#ifndef CONFIG_KERNEL_NONE
#include <csi_kernel.h>
#endif
extern void dw_usart_irqhandler(int32_t idx);
extern void dw_timer_irqhandler(int32_t idx);
extern void dw_gpio_irqhandler(int32_t idx);
extern void dw_iic_irqhandler(int32_t idx);
extern void ck_rtc_irqhandler(int32_t idx);
extern void dw_spi_irqhandler(int32_t idx);
extern void dw_wdt_irqhandler(int32_t idx);
extern void ck_dma_irqhandler(int32_t idx);
extern void ck_aes_irqhandler(int32_t idx);
extern void ck_sha_irqhandler(int32_t idx);
extern void xPortSysTickHandler( void );
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
#define ATTRIBUTE_ISR
#ifndef CONFIG_KERNEL_NONE
#define CSI_INTRPT_ENTER() csi_kernel_intrpt_enter()
#define CSI_INTRPT_EXIT() csi_kernel_intrpt_exit()
#else
#define CSI_INTRPT_ENTER()
#define CSI_INTRPT_EXIT()
#endif
ATTRIBUTE_ISR void CORET_IRQHandler(void)
{
readl(0xE000E010);
xPortSysTickHandler();
}
#if defined(CONFIG_USART)
ATTRIBUTE_ISR void USART0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void USART1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(1);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void USART2_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(2);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void USART3_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(3);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_TIMER)
ATTRIBUTE_ISR void TIMA0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIMA1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(1);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIMB0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(2);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIMB1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(3);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_GPIO)
ATTRIBUTE_ISR void GPIO0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIO1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(1);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_IIC)
ATTRIBUTE_ISR void I2C0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_iic_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void I2C1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_iic_irqhandler(1);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_RTC)
ATTRIBUTE_ISR void RTC_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_rtc_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void RTC1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_rtc_irqhandler(1);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_AES)
ATTRIBUTE_ISR void AES_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_aes_irqhandler(0);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_TRNG)
ATTRIBUTE_ISR void TRNG_IRQHandler(void)
{
CSI_INTRPT_ENTER();
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_RSA)
ATTRIBUTE_ISR void RSA_IRQHandler(void)
{
CSI_INTRPT_ENTER();
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_SPI) && defined(CONFIG_GPIO)
ATTRIBUTE_ISR void SPI0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_spi_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void SPI1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_spi_irqhandler(1);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_WDT)
ATTRIBUTE_ISR void WDT_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_wdt_irqhandler(0);
CSI_INTRPT_EXIT();
}
#endif

View file

@ -0,0 +1,157 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file pinmux.c
* @brief source file for the pinmux
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdint.h>
#include "pinmux.h"
#include "pin_name.h"
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
/*******************************************************************************
* function: hobbit_ioreuse_inital
*
* description:
* initial hobbit_pinmux
*******************************************************************************/
void hobbit_ioreuse_initial(void)
{
unsigned int value;
value = readl(HOBBIT1_2_GIPO0_PORTCTL_REG);
value &= ~(GPIO0_REUSE_DIS);
writel(value, HOBBIT1_2_GIPO0_PORTCTL_REG);
}
int32_t pin_mux(pin_name_t pin, uint16_t function)
{
unsigned int val = 0;
unsigned int reg_val = 0;
uint8_t offset;
if (function > 3) {
if (pin <= PB3_SPI0MISO_PWM5_I2SSD) {
if (pin <= PA5_RTS0_PWM1_SPI0SSN_TRIG1) {
offset = pin;
/* gpio data source select */
val = readl(HOBBIT1_2_GIPO0_PORTCTL_REG);
val &= ~(1 << offset);
writel(val, HOBBIT1_2_GIPO0_PORTCTL_REG);
return 0;
} else if (pin >= PB0_SCL0_PWM2_I2SMCLK) {
offset = pin - 6;
/* gpio data source select */
val = readl(HOBBIT1_2_GIPO1_PORTCTL_REG);
val &= ~(1 << offset);
writel(val, HOBBIT1_2_GIPO1_PORTCTL_REG);
return 0;
}
}
if ((pin >= PA6_SPI0MOSI_PWM6_SCL0) && (pin <= PA27_RTS2_I2SSD_ADC13)) {
offset = pin - 4;
/* gpio data source select */
val = readl(HOBBIT1_2_GIPO0_PORTCTL_REG);
val &= ~(1 << offset);
writel(val, HOBBIT1_2_GIPO0_PORTCTL_REG);
return 0;
}
return -1;
}
if ((pin >= PA6_SPI0MOSI_PWM6_SCL0) && (pin <= PA27_RTS2_I2SSD_ADC13)) {
offset = pin - 4;
/* gpio data source select */
val = readl(HOBBIT1_2_GIPO0_PORTCTL_REG);
val |= (1 << offset);
writel(val, HOBBIT1_2_GIPO0_PORTCTL_REG);
if (pin <= PA11_ACMP0N_ADC3_RXD0) {
offset = pin;
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(HOBBIT1_2_IOMUX0L_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, HOBBIT1_2_IOMUX0L_REG);
return 0;
} else {
offset = pin - 16;
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(HOBBIT1_2_IOMUX0H_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, HOBBIT1_2_IOMUX0H_REG);
return 0;
}
}
if ((pin >= PA0_TRIG0_ACMP1P_TCK) && (pin <= PB3_SPI0MISO_PWM5_I2SSD)) {
if (pin >= PB0_SCL0_PWM2_I2SMCLK) {
offset = pin - 6;
val = readl(HOBBIT1_2_GIPO1_PORTCTL_REG);
val |= (1 << offset);
writel(val, HOBBIT1_2_GIPO1_PORTCTL_REG);
offset = pin;
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(HOBBIT1_2_IOMUX0L_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, HOBBIT1_2_IOMUX0L_REG);
return 0;
}
if (pin <= PA5_RTS0_PWM1_SPI0SSN_TRIG1) {
offset = pin;
/* gpio data source select */
val = readl(HOBBIT1_2_GIPO0_PORTCTL_REG);
val |= (1 << offset);
writel(val, HOBBIT1_2_GIPO0_PORTCTL_REG);
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(HOBBIT1_2_IOMUX0L_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, HOBBIT1_2_IOMUX0L_REG);
return 0;
}
}
if (pin > PA27_RTS2_I2SSD_ADC13) {
offset = pin - PC0_SCL1_CTS1_PWM10_ADC14;
reg_val = (0x3 << (offset *2));
val = readl(HOBBIT1_2_IOMUX1L_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, HOBBIT1_2_IOMUX1L_REG);
}
return -1;
}

View file

@ -0,0 +1,5 @@
TEE_INC += -I$(CSI_DIR)/csi_driver/csky/hobbit3/include
TEE_SRC += \
$(CSI_DIR)/csi_driver/csky/hobbit3/devices.c \
$(CSI_DIR)/csi_driver/csky/hobbit3/isr.c \
$(CSI_DIR)/csi_driver/csky/hobbit3/pinmux.c

View file

@ -0,0 +1,804 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file devices.c
* @brief source file for the devices
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <soc.h>
#include <config.h>
#include <drv_usart.h>
#include <stdio.h>
#include <drv_timer.h>
#include <drv_rtc.h>
#include <drv_trng.h>
#include <drv_crc.h>
#include <drv_aes.h>
#include <drv_rsa.h>
#include <drv_eflash.h>
#include <drv_spi.h>
#include <drv_gpio.h>
#include "pin_name.h"
#include "pinmux.h"
//typedef int32_t int32_t;
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
#if 0
struct {
uint32_t base;
uint32_t irq;
}
const sg_usi_config[CONFIG_USI_NUM] = {
{CSKY_USI0_BASE, USI0_IRQn},
{CSKY_USI1_BASE, USI1_IRQn},
};
typedef struct {
int32_t sclk;
int32_t sd0;
int32_t sd1;
int32_t nss;
uint16_t cfg_idx; //idx of sg_usi_config[]
uint16_t function;
} usi_pin_map_t;
const static usi_pin_map_t s_usi_pin_map[] = {
{
PA10_UART0CTS_USI0SCLK_SPU4_I2C0SCL,
PA11_UART0RTS_USI0SD0_SPU5_I2C0SDA,
PA12_XX_USI0SD1_XX_UART2RX,
PA13_XX_USI0NSS_XX_UART2TX,
0,
1
},
{
PA16_SPI0CS0_PWMTRIG0_XX_USI1SCLK,
PA17_SPI0MOSI_PWMTRIG1_XX_USI1SD0,
PA18_SPI0MISO_XX_SPU6_USI1SD1,
PA19_SPI0SCK_FAULT_SPU7_USI1NSS,
1,
3
},
};
#endif
struct {
uint32_t base;
uint32_t irq;
}
const static sg_usart_config[CONFIG_USART_NUM] = {
{CSKY_UART0_BASE, UART0_IRQn},
{CSKY_UART1_BASE, UART1_IRQn},
{CSKY_UART2_BASE, UART2_IRQn},
{CSKY_UART3_BASE, UART3_IRQn}
};
typedef struct {
int32_t tx;
int32_t rx;
#if 0
int32_t cts;
int32_t rts;
#endif
uint16_t cfg_idx; //idx of sg_usart_config[]
uint16_t function;
} usart_pin_map_t;
const static usart_pin_map_t s_usart_pin_map[] = {
{
PA8_UART0TX_XX_SPU2_SIROUT0,
PA9_UART0RX_XX_SPU3_SIRIN0,
0,
0
},
{
PA21_UART1TX_PWM1_SPU9_SIROUT1,
PA20_UART1RX_PWM0_SPU8_SIRIN1,
1,
0
},
{
PA0_I2C0SCL_SPI1CS1_SPU0_UART1TX,
PA1_I2C0SDA_SPI1CS2_SPU1_UART1RX,
1,
4,
},
{
PB0_UART2TX_XX_XX_SIROUT2,
PB1_UART2RX_XX_XX_SIRIN2,
2,
0
},
{
PB13_UART3TX_SPI1MISO_SPU29_SIROUT3,
PB12_UART3RX_SPI1CS0_SPU28_SIRIN3,
3,
0
}
};
/**
\param[in] instance idx, must not exceed return value of target_get_usart_count()
\brief get usart instance.
\return pointer to usart instance
*/
int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) {
if (s_usart_pin_map[idx].tx == tx && s_usart_pin_map[idx].rx == rx) {
*base = sg_usart_config[s_usart_pin_map[idx].cfg_idx].base;
*irq = sg_usart_config[s_usart_pin_map[idx].cfg_idx].irq;
/*pinmux*/
pin_mux(s_usart_pin_map[idx].tx, s_usart_pin_map[idx].function);
pin_mux(s_usart_pin_map[idx].rx, s_usart_pin_map[idx].function);
return s_usart_pin_map[idx].cfg_idx;
}
}
return -1;
}
/**
\brief control usart flow.
\param[in] tx_flow The TX flow pin name
\param[in] rx_flow The RX flow pin name
\param[in] flag 0-disable, 1-enable.
\return 0 if setting ready ,negative for error code
*/
int32_t target_usart_flowctrl_init(int32_t tx_flow, int32_t rx_flow, uint32_t flag)
{
#if 0
uint32_t idx;
for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) {
if ((s_usart_pin_map[idx].cts == tx_flow) &&(s_usart_pin_map[idx].rts == rx_flow))
break;
}
if (idx >= sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t)) {
return -1;
}
if ((s_usart_pin_map[idx].cts == tx_flow) && flag) {
pin_mux(s_usart_pin_map[idx].cts, s_usart_pin_map[idx].function);
} else if ((s_usart_pin_map[idx].cts == tx_flow) && (flag == 0)) {
pin_mux(s_usart_pin_map[idx].cts, 0xff);
} else {
return -1;
}
if ((s_usart_pin_map[idx].rts == rx_flow) && flag) {
pin_mux(s_usart_pin_map[idx].rts, s_usart_pin_map[idx].function);
} else if ((s_usart_pin_map[idx].rts == rx_flow) && (flag == 0)) {
pin_mux(s_usart_pin_map[idx].rts, 0xff);
} else {
return -1;
}
return 0;
#endif
return 0;
}
struct {
uint32_t base;
uint32_t irq;
uint32_t pin_num;
port_name_t port;
}
const sg_gpio_config[CONFIG_GPIO_NUM] = {
{CSKY_GPIO0_BASE, GPIOA_IRQn, 32, PORTA},
{CSKY_GPIO1_BASE, GPIOB_IRQn, 16, PORTB}
};
typedef struct {
int32_t gpio_pin;
uint32_t cfg_idx; //idx of sg_gpio_config[]
} gpio_pin_map_t;
const static gpio_pin_map_t s_gpio_pin_map[] = {
{PA0_I2C0SCL_SPI1CS1_SPU0_UART1TX ,0},
{PA1_I2C0SDA_SPI1CS2_SPU1_UART1RX,0},
{PA2_QSPI0CLK_XX_XX_XX,0},
{PA3_QSPI0MISO_XX_XX_XX,0},
{PA4_QSPI0MOSI_XX_XX_XX,0},
{PA5_QSPI0HOLD_XX_XX_XX,0},
{PA6_QSPI0WP_XX_XX_XX,0},
{PA7_QSPI0CS0_XX_XX_XX,0},
{PA8_UART0TX_XX_SPU2_SIROUT0,0},
{PA9_UART0RX_XX_SPU3_SIRIN0,0},
{PA10_UART0CTS_USI0SCLK_SPU4_I2C0SCL,0},
{PA11_UART0RTS_USI0SD0_SPU5_I2C0SDA,0},
{PA12_XX_USI0SD1_XX_UART2RX,0},
{PA13_XX_USI0NSS_XX_UART2TX,0},
{PA14_SPI0CS2_FAULT_I2C1SDA_XX,0},
{PA15_SPI0CS1_XX_I2C1SCL_XX,0},
{PA16_SPI0CS0_PWMTRIG0_XX_USI1SCLK,0},
{PA17_SPI0MOSI_PWMTRIG1_XX_USI1SD0,0},
{PA18_SPI0MISO_XX_SPU6_USI1SD1,0},
{PA19_SPI0SCK_FAULT_SPU7_USI1NSS,0},
{PA20_UART1RX_PWM0_SPU8_SIRIN1,0},
{PA21_UART1TX_PWM1_SPU9_SIROUT1,0},
{PA22_UART1CTS_PWM2_SPU10_XX,0},
{PA23_UART1RTS_PWM3_SPU11_XX,0},
{PA24_USI1NSS_PWM4_SPU12_XX,0},
{PA25_USI1SD1_PWM5_SPU13_XX,0},
{PA26_USI1SD0_PWM6_SPU14_XX,0},
{PA27_USI1SCLK_PWM7_SPU15_XX,0},
{PA28_I2C1SCL_PWM8_SPU16_XX,0},
{PA29_I2C1SDA_PWM9_SPU17_XX,0},
{PA30_I2C0SDA_PWM10_SPU18_XX,0},
{PA31_I2C0SCL_PWM11_SPU19_XX,0},
{PB0_UART2TX_XX_XX_SIROUT2,1},
{PB1_UART2RX_XX_XX_SIRIN2,1},
{PB2_UART2RTS_XX_XX_XX,1},
{PB3_UART2CTS_XX_XX_XX,1},
{PB4_XX_XX_SPU20_UART3TX,1},
{PB5_QSPI1CS1_XX_SPU21_UART3RX,1},
{PB6_QSPI1WP_XX_SPU22_XX,1},
{PB7_QSPI1HOLD_XX_SPU23_XX,1},
{PB8_QSPI1CS0_PWMTRIG0_SPU24_XX,1},
{PB9_QSPI1MOSI_PWMTRIG1_SPU25_XX,1},
{PB10_QSPI1MISO_XX_SPU26_I2C1SDA,1},
{PB11_QSPI1CLK_XX_SPU27_I2C1SCL,1},
{PB12_UART3RX_SPI1CS0_SPU28_SIRIN3,1},
{PB13_UART3TX_SPI1MISO_SPU29_SIROUT3,1},
{PB14_UART3RTS_SPI1MOSI_SPU30_XX,1},
{PB15_UART3CTS_SPI1SCK_SPU31_XX,1}
};
int32_t target_gpio_port_init(port_name_t port, uint32_t *base, uint32_t *irq, uint32_t *pin_num)
{
int i;
for (i = 0; i < CONFIG_GPIO_NUM; i++) {
if (sg_gpio_config[i].port == port) {
*base = sg_gpio_config[i].base;
*irq = sg_gpio_config[i].irq;
*pin_num = sg_gpio_config[i].pin_num;
return i;
}
}
return -1;
}
/**
\param[in] instance idx, must not exceed return value of target_get_gpio_count()
\brief get gpio instance.
\return pointer to gpio instance
*/
int32_t target_gpio_pin_init(int32_t gpio_pin, uint32_t *port_idx)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_gpio_pin_map) / sizeof(gpio_pin_map_t); idx++) {
if (s_gpio_pin_map[idx].gpio_pin == gpio_pin) {
*port_idx = s_gpio_pin_map[idx].cfg_idx;
/*pinmux*/
pin_mux(s_gpio_pin_map[idx].gpio_pin, 0xff);
return idx;
}
}
return -1;
}
struct {
uint32_t base;
uint32_t irq;
}
const sg_timer_config[CONFIG_TIMER_NUM] = {
{CSKY_TIM0_BASE, TIMA0_IRQn},
{CSKY_TIM0_BASE + 0x14, TIMA1_IRQn},
{CSKY_TIM1_BASE, TIMB0_IRQn},
{CSKY_TIM1_BASE + 0x14, TIMB1_IRQn},
{CSKY_TIM2_BASE, TIM34567_IRQn},
{CSKY_TIM2_BASE + 0x14, TIM34567_IRQn},
{CSKY_TIM3_BASE, TIM34567_IRQn},
{CSKY_TIM3_BASE + 0x14, TIM34567_IRQn},
{CSKY_TIM4_BASE, TIM34567_IRQn},
{CSKY_TIM4_BASE + 0x14, TIM34567_IRQn},
{CSKY_TIM5_BASE, TIM34567_IRQn},
{CSKY_TIM5_BASE + 0x14, TIM34567_IRQn},
{CSKY_TIM6_BASE, TIM34567_IRQn},
{CSKY_TIM6_BASE + 0x14, TIM34567_IRQn},
};
int32_t target_get_timer_count(void)
{
return CONFIG_TIMER_NUM;
}
int32_t target_get_timer(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_timer_count()) {
return NULL;
}
*base = sg_timer_config[idx].base;
*irq = sg_timer_config[idx].irq;
return idx;
}
struct {
uint32_t base;
uint32_t irq;
}
const sg_sha_config[CONFIG_SHA_NUM] = {
{CSKY_SHA_BASE, SHA_IRQn}
};
/**
\brief get sha instance count.
\return sha instance count
*/
int32_t target_get_sha_count(void)
{
return CONFIG_SHA_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_sha_count()
\brief get sha instance.
\return pointer to sha instance
*/
int32_t target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_sha_count()) {
return NULL;
}
*base = sg_sha_config[idx].base;
*irq = sg_sha_config[idx].irq;
return idx;
}
struct {
uint32_t base;
uint32_t irq;
}
const sg_rsa_config[CONFIG_RSA_NUM] = {
{CSKY_RSA_BASE, RSA_IRQn}
};
/**
\brief get rsa instance count.
\return rsa instance count
*/
int32_t target_get_rsa_count(void)
{
return CONFIG_RSA_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_rsa_count()
\brief get rsa instance.
\return pointer to rsa instance
*/
int32_t target_get_rsa(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_rsa_count()) {
return NULL;
}
*base = sg_rsa_config[idx].base;
*irq = sg_rsa_config[idx].irq;
return idx;
}
struct {
uint32_t base;
uint32_t irq;
}
const sg_aes_config[CONFIG_AES_NUM] = {
{CSKY_AES_BASE, AES_IRQn}
};
/**
\brief get aes instance count.
\return aes instance count
*/
int32_t target_get_aes_count(void)
{
return CONFIG_AES_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_aes_count()
\brief get aes instance.
\return pointer to aes instance
*/
int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_aes_count()) {
return NULL;
}
*base = sg_aes_config[idx].base;
*irq = sg_aes_config[idx].irq;
return idx;
}
struct {
uint32_t base;
uint32_t irq;
}
const sg_trng_config[CONFIG_TRNG_NUM] = {
{CSKY_TRNG_BASE, TRNG_IRQn}
};
/**
\param[in] instance idx
\brief get trng instance.
\return pointer to trng instance
*/
int32_t target_get_trng(int32_t idx, uint32_t *base)
{
*base = sg_trng_config[idx].base;
return idx;
}
struct {
uint32_t base;
}
const sg_crc_config[CONFIG_CRC_NUM] = {
{CSKY_CRC_BASE}
};
/**
\param[in] instance idx
\brief get crc instance.
\return pointer to crc instance
*/
int32_t target_get_crc(int32_t idx, uint32_t *base)
{
*base = sg_crc_config[idx].base;
return idx;
}
struct {
uint32_t base;
uint32_t irq;
}
const sg_iic_config[CONFIG_IIC_NUM] = {
{CSKY_I2C0_BASE, I2C0_IRQn},
{CSKY_I2C1_BASE, I2C1_IRQn}
};
typedef struct {
int32_t scl;
int32_t sda;
uint16_t cfg_idx; //idx of sg_iic_config[]
uint16_t function;
} iic_pin_map_t;
const static iic_pin_map_t s_iic_pin_map[] = {
{
PA31_I2C0SCL_PWM11_SPU19_XX,
PA30_I2C0SDA_PWM10_SPU18_XX,
0,
0
},
{
PA28_I2C1SCL_PWM8_SPU16_XX,
PA29_I2C1SDA_PWM9_SPU17_XX,
1,
0
}
};
/**
\param[in] instance idx, must not exceed return value of target_get_iic_count()
\brief get iic instance.
\return pointer to iic instance
*/
int32_t target_iic_init(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= sizeof(s_iic_pin_map) / sizeof(iic_pin_map_t)) {
return -1;
}
*base = sg_iic_config[s_iic_pin_map[idx].cfg_idx].base;
*irq = sg_iic_config[s_iic_pin_map[idx].cfg_idx].irq;
/*pinmux*/
pin_mux(s_iic_pin_map[idx].scl, s_iic_pin_map[idx].function);
pin_mux(s_iic_pin_map[idx].sda, s_iic_pin_map[idx].function);
return s_iic_pin_map[idx].cfg_idx;
}
#define BIT1 (0x1)
struct {
uint32_t base;
uint32_t irq;
}
const sg_rtc_config[CONFIG_RTC_NUM] = {
{CSKY_RTC0_BASE, RTC_IRQn},
};
int32_t target_get_rtc_count(void)
{
return CONFIG_RTC_NUM;
}
int32_t target_get_rtc(int32_t idx, uint32_t *base, uint32_t *irq)
{
unsigned int value;
if (idx >= target_get_rtc_count()) {
return NULL;
}
value = readl(CSKY_PMU_BASE);
value &= ~BIT1;
writel(value, CSKY_PMU_BASE);
*base = sg_rtc_config[idx].base;
*irq = sg_rtc_config[idx].irq;
return idx;
}
struct {
uint32_t base;
uint32_t irq;
}
const sg_spi_config[CONFIG_SPI_NUM] = {
{CSKY_SPI0_BASE, SPI0_IRQn},
{CSKY_SPI1_BASE, SPI1_IRQn}
};
typedef struct {
int32_t mosi;
int32_t miso;
int32_t sclk;
int32_t ssel;
uint32_t cfg_idx; //idx of sg_iic_config[]
uint16_t function;
} spi_pin_map_t;
const static spi_pin_map_t s_spi_pin_map[] = {
{
PA18_SPI0MISO_XX_SPU6_USI1SD1,
PA17_SPI0MOSI_PWMTRIG1_XX_USI1SD0,
PA19_SPI0SCK_FAULT_SPU7_USI1NSS,
PA16_SPI0CS0_PWMTRIG0_XX_USI1SCLK,
0,
0
},
{
PB13_UART3TX_SPI1MISO_SPU29_SIROUT3,
PB14_UART3RTS_SPI1MOSI_SPU30_XX,
PB15_UART3CTS_SPI1SCK_SPU31_XX,
PB12_UART3RX_SPI1CS0_SPU28_SIRIN3,
1,
1
}
};
/**
\param[in] instance idx, must not exceed return value of target_get_spi_count()
\brief get spi instance.
\return pointer to spi instance
*/
int32_t target_spi_init(int32_t idx, uint32_t *base, uint32_t *irq, uint32_t *ssel)
{
if (idx >= sizeof(s_spi_pin_map) / sizeof(spi_pin_map_t)) {
return -1;
}
*base = sg_spi_config[s_spi_pin_map[idx].cfg_idx].base;
*irq = sg_spi_config[s_spi_pin_map[idx].cfg_idx].irq;
*ssel = s_spi_pin_map[idx].ssel;
/*pinmux*/
pin_mux(s_spi_pin_map[idx].mosi, s_spi_pin_map[idx].function);
pin_mux(s_spi_pin_map[idx].miso, s_spi_pin_map[idx].function);
pin_mux(s_spi_pin_map[idx].sclk, s_spi_pin_map[idx].function);
pin_mux(s_spi_pin_map[idx].ssel, s_spi_pin_map[idx].function);
return s_spi_pin_map[idx].cfg_idx;
}
struct {
uint32_t base;
uint32_t irq;
}
const sg_dmac_config[CONFIG_DMAC_NUM] = {
{CSKY_DMAC0_BASE, DMAC_IRQn},
};
int32_t target_get_dmac_count(void)
{
return CONFIG_DMAC_NUM;
}
int32_t target_get_dmac(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_dmac_count()) {
return NULL;
}
*base = sg_dmac_config[idx].base;
*irq = sg_dmac_config[idx].irq;
return idx;
}
struct {
uint32_t base;
uint32_t irq;
}
const sg_pwm_config[CONFIG_PWM_NUM] = {
{CSKY_PWM_BASE, PWM_IRQn},
};
typedef struct {
int32_t pwm_pin;
uint32_t cfg_idx; //idx of sg_pwm_config[]
uint32_t ch_num;
uint16_t function;
} pwm_pin_map_t;
const static pwm_pin_map_t s_pwm_pin_map[] = {
{PA20_UART1RX_PWM0_SPU8_SIRIN1, 0, 0, 1},
{PA21_UART1TX_PWM1_SPU9_SIROUT1, 0, 1, 1},
{PA22_UART1CTS_PWM2_SPU10_XX, 0, 2, 1},
{PA23_UART1RTS_PWM3_SPU11_XX, 0, 3, 1},
{PA24_USI1NSS_PWM4_SPU12_XX, 0, 4, 1},
{PA25_USI1SD1_PWM5_SPU13_XX, 0, 5, 1},
{PA26_USI1SD0_PWM6_SPU14_XX, 0, 6, 1},
{PA27_USI1SCLK_PWM7_SPU15_XX, 0, 7, 1},
{PA28_I2C1SCL_PWM8_SPU16_XX, 0, 8, 1},
{PA29_I2C1SDA_PWM9_SPU17_XX, 0, 9, 1},
{PA30_I2C0SDA_PWM10_SPU18_XX, 0, 10, 1},
{PA31_I2C0SCL_PWM11_SPU19_XX, 0, 11, 1}
};
/**
\param[in] instance idx, must not exceed return value of target_get_pwm_count()
\brief get pwm instance.
\return pointer to pwm instance
*/
int32_t target_pwm_init(int32_t pwm_pin, uint32_t *ch_num, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_pwm_pin_map) / sizeof(pwm_pin_map_t); idx++) {
if (s_pwm_pin_map[idx].pwm_pin == pwm_pin) {
*base = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].base;
*irq = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].irq;
*ch_num = s_pwm_pin_map[idx].ch_num;
/*pinmux*/
pin_mux(s_pwm_pin_map[idx].pwm_pin, s_pwm_pin_map[idx].function);
return s_pwm_pin_map[idx].cfg_idx;
}
}
return -1;
}
struct {
uint32_t base;
uint32_t irq;
}
const sg_wdt_config[CONFIG_WDT_NUM] = {
{CSKY_WDT_BASE, WDT_IRQn}
};
int32_t target_get_wdt_count(void)
{
return CONFIG_WDT_NUM;
}
int32_t target_get_wdt(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_wdt_count()) {
return NULL;
}
*base = sg_wdt_config[idx].base;
*irq = sg_wdt_config[idx].irq;
return idx;
}
int32_t target_get_etb_count(void)
{
return CONFIG_ETB_NUM;
}
int32_t target_get_etb(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_etb_count()) {
return NULL;
}
// *base = sg_etb_config[idx].base;
// *irq = sg_etb_config[idx].irq;
return 0;
}
struct {
uint32_t base;
uint32_t irq;
}
const sg_qspi_config[CONFIG_QSPI_NUM] = {
{CSKY_QSPIC0_BASE, QSPIC1_IRQn},
{CSKY_QSPIC1_BASE, QSPIC1_IRQn}
};
typedef struct {
pin_name_t sclk;
pin_name_t miso;
pin_name_t mosi;
pin_name_t hold;
pin_name_t wp;
pin_name_t ssel;
uint32_t cfg_idx;
uint16_t function;
} qspi_pin_map_t;
const static qspi_pin_map_t s_qspi_pin_map[] = {
{
PA2_QSPI0CLK_XX_XX_XX,
PA3_QSPI0MISO_XX_XX_XX,
PA4_QSPI0MOSI_XX_XX_XX,
PA5_QSPI0HOLD_XX_XX_XX,
PA6_QSPI0WP_XX_XX_XX,
PA7_QSPI0CS0_XX_XX_XX,
0,
0
},
{
PB11_QSPI1CLK_XX_SPU27_I2C1SCL,
PB10_QSPI1MISO_XX_SPU26_I2C1SDA,
PB9_QSPI1MOSI_PWMTRIG1_SPU25_XX,
PB7_QSPI1HOLD_XX_SPU23_XX,
PB6_QSPI1WP_XX_SPU22_XX,
PB8_QSPI1CS0_PWMTRIG0_SPU24_XX,
1,
0
}
};
/**
\param[in] instance idx, must not exceed return value of target_get_qspi_count()
\brief get qspi instance.
\return pointer to qspi instance
*/
int32_t target_qspi_init(pin_name_t mosi, pin_name_t miso, pin_name_t sclk, pin_name_t ssel, pin_name_t wp, pin_name_t hold, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_qspi_pin_map) / sizeof(qspi_pin_map_t); idx++) {
if (s_qspi_pin_map[idx].mosi == mosi && s_qspi_pin_map[idx].miso == miso
&& s_qspi_pin_map[idx].sclk == sclk && s_qspi_pin_map[idx].ssel == ssel
&& s_qspi_pin_map[idx].hold == hold && s_qspi_pin_map[idx].wp == wp) {
pin_mux(s_qspi_pin_map[idx].mosi, s_qspi_pin_map[idx].function);
pin_mux(s_qspi_pin_map[idx].miso, s_qspi_pin_map[idx].function);
pin_mux(s_qspi_pin_map[idx].sclk, s_qspi_pin_map[idx].function);
pin_mux(s_qspi_pin_map[idx].hold, s_qspi_pin_map[idx].function);
pin_mux(s_qspi_pin_map[idx].wp, s_qspi_pin_map[idx].function);
pin_mux(s_qspi_pin_map[idx].ssel, s_qspi_pin_map[idx].function);
return s_qspi_pin_map[idx].cfg_idx;
}
}
return -1;
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file pin_name.h
* @brief header file for the pin_name
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _PINNAMES_H
#define _PINNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PA0_I2C0SCL_SPI1CS1_SPU0_UART1TX = 0,
PA1_I2C0SDA_SPI1CS2_SPU1_UART1RX,
PA2_QSPI0CLK_XX_XX_XX,
PA3_QSPI0MISO_XX_XX_XX,
PA4_QSPI0MOSI_XX_XX_XX,
PA5_QSPI0HOLD_XX_XX_XX,
PA6_QSPI0WP_XX_XX_XX,
PA7_QSPI0CS0_XX_XX_XX,
PA8_UART0TX_XX_SPU2_SIROUT0,
PA9_UART0RX_XX_SPU3_SIRIN0,
PA10_UART0CTS_USI0SCLK_SPU4_I2C0SCL,
PA11_UART0RTS_USI0SD0_SPU5_I2C0SDA,
PA12_XX_USI0SD1_XX_UART2RX,
PA13_XX_USI0NSS_XX_UART2TX,
PA14_SPI0CS2_FAULT_I2C1SDA_XX,
PA15_SPI0CS1_XX_I2C1SCL_XX,
PA16_SPI0CS0_PWMTRIG0_XX_USI1SCLK,
PA17_SPI0MOSI_PWMTRIG1_XX_USI1SD0,
PA18_SPI0MISO_XX_SPU6_USI1SD1,
PA19_SPI0SCK_FAULT_SPU7_USI1NSS,
PA20_UART1RX_PWM0_SPU8_SIRIN1,
PA21_UART1TX_PWM1_SPU9_SIROUT1,
PA22_UART1CTS_PWM2_SPU10_XX,
PA23_UART1RTS_PWM3_SPU11_XX,
PA24_USI1NSS_PWM4_SPU12_XX,
PA25_USI1SD1_PWM5_SPU13_XX,
PA26_USI1SD0_PWM6_SPU14_XX,
PA27_USI1SCLK_PWM7_SPU15_XX,
PA28_I2C1SCL_PWM8_SPU16_XX,
PA29_I2C1SDA_PWM9_SPU17_XX,
PA30_I2C0SDA_PWM10_SPU18_XX,
PA31_I2C0SCL_PWM11_SPU19_XX,
PB0_UART2TX_XX_XX_SIROUT2,
PB1_UART2RX_XX_XX_SIRIN2,
PB2_UART2RTS_XX_XX_XX,
PB3_UART2CTS_XX_XX_XX,
PB4_XX_XX_SPU20_UART3TX,
PB5_QSPI1CS1_XX_SPU21_UART3RX,
PB6_QSPI1WP_XX_SPU22_XX,
PB7_QSPI1HOLD_XX_SPU23_XX,
PB8_QSPI1CS0_PWMTRIG0_SPU24_XX,
PB9_QSPI1MOSI_PWMTRIG1_SPU25_XX,
PB10_QSPI1MISO_XX_SPU26_I2C1SDA,
PB11_QSPI1CLK_XX_SPU27_I2C1SCL,
PB12_UART3RX_SPI1CS0_SPU28_SIRIN3,
PB13_UART3TX_SPI1MISO_SPU29_SIROUT3,
PB14_UART3RTS_SPI1MOSI_SPU30_XX,
PB15_UART3CTS_SPI1SCK_SPU31_XX,
}
pin_name_t;
typedef enum {
PORTA = 0,
PORTB = 1
} port_name_t;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,99 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file pinmux.h
* @brief Header file for the pinmux
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef HOBBIT_PINMUX_H
#define HOBBIT_PINMUX_H
#include <stdint.h>
#include "pin_name.h"
void hobbit_ioreuse_initial(void);
int32_t pin_mux(pin_name_t pin, uint16_t function);
/*IOMUX0L function definition */
/* IOMUX0H function definition */
#define PA20_UART1_RX 0x00000000
#define PA21_UART1_TX 0x00000000
/* IOMUX1L function definition */
/* flag as identification */
#define GPIO_SET_BIT0 0x00000001
#define GPIO_SET_BIT1 0x00000002
#define GPIO_SET_BIT2 0x00000004
#define GPIO_SET_BIT3 0x00000008
#define GPIO_SET_BIT4 0x00000010
#define GPIO_SET_BIT5 0x00000020
#define GPIO_SET_BIT6 0x00000040
#define GPIO_SET_BIT7 0x00000080
#define GPIO_SET_BIT8 0x00000100
#define GPIO_SET_BIT9 0x00000200
#define GPIO_SET_BIT10 0x00000400
#define GPIO_SET_BIT11 0x00000800
#define GPIO_SET_BIT12 0x00001000
#define GPIO_SET_BIT13 0x00002000
#define GPIO_SET_BIT14 0x00004000
#define GPIO_SET_BIT15 0x00008000
#define GPIO_SET_BIT16 0x00010000
#define GPIO_SET_BIT17 0x00020000
#define GPIO_SET_BIT18 0x00040000
#define GPIO_SET_BIT19 0x00080000
#define GPIO_SET_BIT20 0x00100000
#define GPIO_SET_BIT21 0x00200000
#define GPIO_SET_BIT22 0x00400000
#define GPIO_SET_BIT23 0x00800000
#define GPIO_SET_BIT24 0x01000000
#define GPIO_SET_BIT25 0x02000000
#define GPIO_SET_BIT26 0x04000000
#define GPIO_SET_BIT27 0x08000000
#define GPIO_SET_BIT28 0x10000000
#define GPIO_SET_BIT29 0x20000000
#define GPIO_SET_BIT30 0x40000000
#define GPIO_SET_BIT31 0x80000000
/******************************************************************************
* hobbit gpio control and gpio reuse function
* selecting regester adddress
******************************************************************************/
#define HOBBIT_GIPO0_PORTCTL_REG 0x60030000
#define HOBBIT_GIPO1_PORTCTL_REG 0x60030004
#define HOBBIT_IOMUX0L_REG 0x60030008
#define HOBBIT_IOMUX0H_REG 0x6003000C
#define HOBBIT_IOMUX1L_REG 0x60030010
/*************basic gpio reuse v1.0********************************************
* UART1(PA20,PA21)
******************************************************************************/
#define GPIO0_REUSE_EN (GPIO_SET_BIT20|GPIO_SET_BIT21)
#define GPIO1_REUSE_EN (0x00000000)
#define IOMUX0L_FUNCTION_SEL (0x00000000)
#define IOMUX0H_FUNCTION_SEL (PA20_UART1_RX|PA21_UART1_TX)
#define IOMUX1L_FUNCTION_SEL (0x00000000)
#endif /* HOBBIT_PINMUX_H */

View file

@ -0,0 +1,206 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**************************************************************************//**
* @file soc.h
* @brief CSI Core Peripheral Access Layer Header File for
* CSKYSOC Device Series
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef SOC_H
#define SOC_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SYSTEM_CLOCK
#define SYSTEM_CLOCK (20000000)
#endif
#ifndef LSP_DEFAULT_FREQ
#define LSP_DEFAULT_FREQ (20000000)
#endif
/* ------------------------- Interrupt Number Definition ------------------------ */
typedef enum IRQn
{
/* ---------------------- CSKYCK801 Specific Interrupt Numbers --------------------- */
GPIOA_IRQn = 0,
CORET_IRQn = 1, /* core Timer Interrupt */
TIMA0_IRQn = 2, /* timerA0 Interrupt */
TIMA1_IRQn = 3, /* timerA1 Interrupt */
TIM34567_IRQn = 4, /* timerC ~ timerH Interrupt */
WDT_IRQn = 5, /* wdt Interrupt */
UART0_IRQn = 6, /* uart0 Interrupt */
UART1_IRQn = 7, /* uart1 Interrupt */
UART2_IRQn = 8, /* uart2 Interrupt */
I2C0_IRQn = 9, /* i2c0 Interrupt */
I2C1_IRQn = 10, /* i2c1 Interrupt */
SPI1_IRQn = 11, /* spi1 Interrupt */
SPI0_IRQn = 12, /* spi0 Interrupt */
RTC_IRQn = 13, /* rtc Interrupt */
UART3_IRQn = 14, /* uart3 Interrupt */
ADC_IRQn = 15, /* adc Interrupt */
QSPIC1_IRQn = 16, /* qspic1 interrupt */
DMAC_IRQn = 17, /* dmac Interrupt */
PMU_IRQn = 18, /* pmu Interrupt */
PWM_IRQn = 19, /* pwm Interrupt */
USI0_IRQn = 20, /* usi0 Interrupt */
USI1_IRQn = 21, /* usi1 Interrupt */
SPU_IRQn = 22, /* spu Interrupt */
TIMB0_IRQn = 23, /* timerB0 Interrupt */
TIMB1_IRQn = 24, /* timerB1 Interrupt */
GPIOB_IRQn = 27, /* GPIOB Interrupt */
AES_IRQn = 26, /* aes Interrupt */
RSA_IRQn = 28, /* rsa Interrupt */
SHA_IRQn = 29, /* sha Interrupt */
TRNG_IRQn = 30, /* trng Interrupt */
} IRQn_Type;
/* ================================================================================ */
/* ================ Processor and Core Peripheral Section ================ */
/* ================================================================================ */
/* -------- Configuration of the CK801 Processor and Core Peripherals ------- */
#define __CK803_REV 0x0000U /* Core revision r0p0 */
#define __MPU_PRESENT 0 /* MGU present or not */
#define __VIC_PRIO_BITS 2 /* Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */
#include "core_ck802.h" /* Processor and core peripherals */
#include "stdint.h"
typedef enum {
CKENUM_DMA_UART0_RX,
CKENUM_DMA_UART0_TX,
CKENUM_DMA_UART1_RX,
CKENUM_DMA_UART1_TX,
CKENUM_DMA_ADC_RX,
CKENUM_DMA_ADC_TX,
CKENUM_DMA_SPI1_RX,
CKENUM_DMA_SPI1_TX,
CKENUM_DMA_SPI0_RX,
CKENUM_DMA_SPI0_TX,
CKENUM_DMA_IIC_RX,
CKENUM_DMA_IIC_TX,
CKENUM_DMA_IIC1_RX,
CKENUM_DMA_IIC1_TX,
CKENUM_DMA_IIS_RX,
CKENUM_DMA_IIS_TX,
CKENUM_DMA_MEMORY
} ckenum_dma_device_e;
#define CONFIG_CRC_NUM 1
#define CONFIG_IIC_NUM 2
#define CONFIG_TRNG_NUM 1
#define CONFIG_AES_NUM 1
#define CONFIG_RSA_NUM 1
#define CONFIG_SHA_NUM 1
#define CONFIG_SPI_NUM 2
#define CONFIG_QSPI_NUM 2
#define CONFIG_PWM_NUM 1
#define CONFIG_TIMER_NUM 14
#define CONFIG_RTC_NUM 1
#define CONFIG_WDT_NUM 1
#define CONFIG_DMAC_NUM 1
#define CONFIG_GPIO_NUM 2
#define CONFIG_GPIO_PIN_NUM 43
#define CONFIG_USART_NUM 4
#define CONFIG_SPU_NUM 1
#define CONFIG_EFLASH_NUM 1
#define CONFIG_ETB_NUM 1
#define CONFIG_USI_NUM 2
/* ================================================================================ */
/* ================ Peripheral memory map ================ */
/* ================================================================================ */
/* -------------------------- CPU FPGA memory map ------------------------------- */
#define CSKY_EFLASH_BASE (0x10000000UL)
#define CSKY_QSPIMEM_BASE (0x18000000UL)
#define CSKY_SRAM_BASE (0x20000000UL)
#define CSKY_PMU_BASE (0x40000000UL)
#define CSKY_DMAC0_BASE (0x40001000UL)
#define CSKY_OTP_BASE (0x40006000UL)
#define CSKY_SASC_BASE (0x40009000UL)
#define CSKY_SPU_BASE (0x40020000UL)
#define CSKY_QSPIC1_BASE (0x40030000UL)
#define CSKY_EFLASH_CONTROL_BASE (0x40005000UL)
#define CSKY_SASC_BASE (0x40009000UL)
/* SUB0*/
#define CSKY_AES_BASE (0x4000D000UL)
#define CSKY_SHA_BASE (0x4000E000UL)
#define CSKY_RSA_BASE (0x4000F000UL)
#define CSKY_CRC_BASE (0x40010000UL)
#define CSKY_TRNG_BASE (0x40011000UL)
/* APB0 */
#define CSKY_TIM0_BASE (0x50000000UL)
#define CSKY_TIM1_BASE (0x50000400UL)
#define CSKY_TIM2_BASE (0x50000800UL)
#define CSKY_TIM3_BASE (0x50000C00UL)
#define CSKY_RTC0_BASE (0x50004000UL)
#define CSKY_WDT_BASE (0x50008000UL)
#define CSKY_SPI0_BASE (0x5000C000UL)
#define CSKY_UART0_BASE (0x50010000UL)
#define CSKY_UART1_BASE (0x50010400UL)
#define CSKY_I2C0_BASE (0x50014000UL)
#define CSKY_GPIO0_BASE (0x50018000UL)
#define CSKY_PWM_BASE (0x5001C000UL)
#define CSKY_ADC_BASE (0x50020000UL)
#define CSKY_USI0_BASE (0x50028000UL)
#define CSKY_QSPIC0_BASE (0x5002C000UL)
/* APB1*/
#define CSKY_TIM4_BASE (0x60000000UL)
#define CSKY_TIM5_BASE (0x60000400UL)
#define CSKY_TIM6_BASE (0x60000800UL)
#define CSKY_TIM7_BASE (0x60000C00UL)
#define CSKY_LPWDT_BASE (0x60008000UL)
#define CSKY_SPI1_BASE (0x6000C000UL)
#define CSKY_UART2_BASE (0x60010000UL)
#define CSKY_UART3_BASE (0x60010400UL)
#define CSKY_I2C1_BASE (0x60014000UL)
#define CSKY_GPIO1_BASE (0x60018000UL)
#define CSKY_TIPC_BASE (0x6001c000UL)
#define CSKY_ETB_BASE (0x60024000UL)
#define CSKY_USI1_BASE (0x60028000UL)
#define CSKY_DAC_BASE (0x6002C000UL)
#define CSKY_IOC_BASE (0x60030000UL)
#define SHA_CONTEXT_SIZE 224
/* ================================================================================ */
/* ================ Peripheral declaration ================ */
/* ================================================================================ */
#define CSKY_UART1 (( CSKY_UART_TypeDef *) CSKY_UART1_BASE)
#define CSKY_SHA (( CSKY_SHA_TypeDef *) CSKY_SHA_BASE)
#ifdef CONFIG_HAVE_VIC
#define ATTRIBUTE_ISR __attribute__((isr))
#else
#define ATTRIBUTE_ISR
#endif
#ifdef __cplusplus
}
#endif
#endif /* SOC_H */

View file

@ -0,0 +1,244 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file isr.c
* @brief source file for the interrupt server route
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <drv_common.h>
#include <config.h>
#include "soc.h"
#ifndef CONFIG_KERNEL_NONE
#include <csi_kernel.h>
#endif
#ifndef CONFIG_USI
extern void dw_spi_irqhandler(int32_t idx);
extern void dw_usart_irqhandler(int32_t idx);
extern void dw_iic_irqhandler(int32_t idx);
#else
extern void ck_usi_irqhandler(int idx);
#endif
extern void ck_spu_irqhandler(int32_t idx);
extern void dw_timer_irqhandler(int32_t idx);
extern void dw_gpio_irqhandler(int32_t idx);
extern void ck_rtc_irqhandler(int32_t idx);
extern void dw_wdt_irqhandler(int32_t idx);
extern void ck_dma_irqhandler(int32_t idx);
extern void ck_aes_irqhandler(int32_t idx);
extern void ck_sha_irqhandler(int32_t idx);
#ifdef CONFIG_KERNEL_FREERTOS
extern void CoretimeIsr(void);
extern void CKPendSVIsr(void);
#endif
extern void systick_handler(void);
extern void xPortSysTickHandler(void);
extern void OSTimeTick(void);
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
#ifndef CONFIG_KERNEL_NONE
#define CSI_INTRPT_ENTER() csi_kernel_intrpt_enter()
#define CSI_INTRPT_EXIT() csi_kernel_intrpt_exit()
#else
#define CSI_INTRPT_ENTER()
#define CSI_INTRPT_EXIT()
#endif
ATTRIBUTE_ISR void CORET_IRQHandler(void)
{
#ifndef CONFIG_KERNEL_FREERTOS
CSI_INTRPT_ENTER();
#endif
readl(0xE000E010);
#if defined(CONFIG_KERNEL_RHINO)
systick_handler();
#elif defined(CONFIG_KERNEL_FREERTOS)
xPortSysTickHandler();
#elif defined(CONFIG_KERNEL_UCOS)
OSTimeTick();
#endif
#ifndef CONFIG_KERNEL_FREERTOS
CSI_INTRPT_EXIT();
#endif
}
#ifdef CONFIG_SPU
ATTRIBUTE_ISR void SPU_IRQHandler(void)
{
ck_spu_irqhandler(0);
}
#endif
#ifndef CONFIG_USI
ATTRIBUTE_ISR void SPI0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_spi_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void SPI1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_spi_irqhandler(1);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void I2C0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_iic_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void I2C1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_iic_irqhandler(1);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void USART0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void USART1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(1);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void USART2_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(2);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void USART3_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(3);
CSI_INTRPT_EXIT();
}
#else
ATTRIBUTE_ISR void USI0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_usi_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void USI1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_usi_irqhandler(1);
CSI_INTRPT_EXIT();
}
#endif
ATTRIBUTE_ISR void TIMA0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIMA1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(1);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIMB0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(2);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIMB1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(3);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIM34567_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(4);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIOA_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIOB_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(1);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void RTC_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_rtc_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void AES_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_aes_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void SHA_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_sha_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void WDT_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_wdt_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void DMAC_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_dma_irqhandler(0);
CSI_INTRPT_EXIT();
}

View file

@ -0,0 +1,138 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file pinmux.c
* @brief source file for the pinmux
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdint.h>
#include "pinmux.h"
#include "pin_name.h"
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
/*******************************************************************************
* function: hobbit_ioreuse_inital
*
* description:
* initial hobbit_pinmux
*******************************************************************************/
extern int32_t target_qspi_init(pin_name_t mosi, pin_name_t miso, pin_name_t sclk, pin_name_t ssel, pin_name_t wp, pin_name_t hold, uint32_t *base, uint32_t *irq);
void hobbit_ioreuse_initial(void)
{
unsigned int value;
/* gpio data source select */
value = readl(HOBBIT_GIPO0_PORTCTL_REG);
value |= GPIO0_REUSE_EN;
writel(value, HOBBIT_GIPO0_PORTCTL_REG);
value = readl(HOBBIT_GIPO1_PORTCTL_REG);
value |= GPIO1_REUSE_EN;
writel(value, HOBBIT_GIPO1_PORTCTL_REG);
/* reuse function select */
value = readl(HOBBIT_IOMUX0L_REG);
value |= IOMUX0L_FUNCTION_SEL;
writel(value, HOBBIT_IOMUX0H_REG);
value = readl(HOBBIT_IOMUX0H_REG);
value |= IOMUX1L_FUNCTION_SEL;
writel(value, HOBBIT_IOMUX0H_REG);
value = readl(HOBBIT_IOMUX1L_REG);
value |= IOMUX1L_FUNCTION_SEL;
writel(value, HOBBIT_IOMUX1L_REG);
target_qspi_init(PA4_QSPI0MOSI_XX_XX_XX, PA3_QSPI0MISO_XX_XX_XX, PA2_QSPI0CLK_XX_XX_XX, PA7_QSPI0CS0_XX_XX_XX, PA6_QSPI0WP_XX_XX_XX, PA5_QSPI0HOLD_XX_XX_XX, 0, 0);
}
int32_t pin_mux(pin_name_t pin, uint16_t function)
{
unsigned int val = 0;
unsigned int reg_val = 0;
uint8_t offset;
if (function > 3) {
if (pin < PB0_UART2TX_XX_XX_SIROUT2) {
offset = pin;
/* gpio data source select */
val = readl(HOBBIT_GIPO0_PORTCTL_REG);
val &= ~(1 << offset);
writel(val, HOBBIT_GIPO0_PORTCTL_REG);
return 0;
} else if (pin >= PB0_UART2TX_XX_XX_SIROUT2) {
offset = pin - 32;
/* gpio data source select */
val = readl(HOBBIT_GIPO1_PORTCTL_REG);
val &= ~(1 << offset);
writel(val, HOBBIT_GIPO1_PORTCTL_REG);
return 0;
} else {
return -1;
}
}
if (pin >= PB0_UART2TX_XX_XX_SIROUT2) {
offset = pin - 32;
/* gpio data source select */
val = readl(HOBBIT_GIPO1_PORTCTL_REG);
val |= (1 << offset);
writel(val, HOBBIT_GIPO1_PORTCTL_REG);
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(HOBBIT_IOMUX1L_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, HOBBIT_IOMUX1L_REG);
return 0;
}
offset = pin;
/* gpio data source select */
val = readl(HOBBIT_GIPO0_PORTCTL_REG);
val |= (1 << offset);
writel(val, HOBBIT_GIPO0_PORTCTL_REG);
if (pin >= PA16_SPI0CS0_PWMTRIG0_XX_USI1SCLK) {
offset = pin - 16;
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(HOBBIT_IOMUX0H_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, HOBBIT_IOMUX0H_REG);
return 0;
}
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(HOBBIT_IOMUX0L_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, HOBBIT_IOMUX0L_REG);
return 0;
}

View file

@ -0,0 +1,5 @@
TEE_INC += -I$(CSI_DIR)/csi_driver/csky/phobos/include
TEE_SRC += \
$(CSI_DIR)/csi_driver/csky/phobos/devices.c \
$(CSI_DIR)/csi_driver/csky/phobos/isr.c \
$(CSI_DIR)/csi_driver/csky/phobos/pinmux.c

View file

@ -0,0 +1,843 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file devices.c
* @brief source file for the devices
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include "soc.h"
#include "config.h"
#include <drv_usart.h>
#include <drv_trng.h>
#include <drv_crc.h>
#include <drv_aes.h>
#include <drv_rsa.h>
#include <drv_eflash.h>
#include <drv_timer.h>
#include <drv_gpio.h>
#include <drv_iic.h>
#include <drv_rtc.h>
#include <drv_spi.h>
#include <drv_wdt.h>
#include <drv_sha.h>
#include <drv_pwm.h>
#include <drv_dmac.h>
#include <stdio.h>
#include "pin_name.h"
#include "pinmux.h"
//typedef int32_t pin_t;
#if CONFIG_IIC
struct {
uint32_t base;
uint32_t irq;
}
const sg_iic_config[CONFIG_IIC_NUM] = {
{CSKY_I2C0_BASE, I2C0_IRQn},
{CSKY_I2C1_BASE, I2C1_IRQn}
};
typedef struct {
pin_t scl;
pin_t sda;
uint16_t cfg_idx; //idx of sg_iic_config[]
uint16_t function;
//uint32_t scl_reg;
//uint32_t scl_cfg;
//uint32_t sda_reg;
//uint32_t sda_cfg;
} iic_pin_map_t;
const static iic_pin_map_t s_iic_pin_map[] = {
{
PA4_SCL0_PWM4_SPI0RX_XX,
PA5_SDA0_PWM5_SPI0CS_XX,
0,
0
},
{
PA6_SPI0CLK_PWMTRIG0_SCL0_XX,
PA7_SPI0TX_PWMTRIG1_SDA0_XX,
0,
2
},
{
PA31_I2SSDA__SCL0_PWM4_XX,
PB0_ADC0_SDA0_PWM5_XX,
0,
1
},
{
PA8_SPI0RX_TRIGFAULT_SCL1_XX,
PA9_SPI0CS_PWM0_SDA1_XX,
1,
2
},
{
PA14_SCL1_PWM5_SPI1RX_XX,
PA15_SDA1_PWMTRIG0_SPI1CS0_XX,
1,
0
},
{
PB1_ADC1_SCL1_USISCLK_XX,
PB2_ADC2_SDA1_USISD0_XX,
1,
1
}
};
/**
\param[in] instance idx, must not exceed return value of target_get_iic_count()
\brief get iic instance.
\return pointer to iic instance
*/
int32_t target_iic_init(pin_t scl, pin_t sda, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_iic_pin_map) / sizeof(iic_pin_map_t); idx++) {
if (s_iic_pin_map[idx].scl == scl && s_iic_pin_map[idx].sda == sda) {
*base = sg_iic_config[s_iic_pin_map[idx].cfg_idx].base;
*irq = sg_iic_config[s_iic_pin_map[idx].cfg_idx].irq;
/*pinmux*/
pin_mux(s_iic_pin_map[idx].scl, s_iic_pin_map[idx].function);
pin_mux(s_iic_pin_map[idx].sda, s_iic_pin_map[idx].function);
return s_iic_pin_map[idx].cfg_idx;
}
}
return -1;
}
#endif
#if CONFIG_USART
struct {
uint32_t base;
uint32_t irq;
}
const sg_usart_config[CONFIG_USART_NUM] = {
{CSKY_UART0_BASE, UART0_IRQn},
{CSKY_UART1_BASE, UART1_IRQn},
{CSKY_UART2_BASE, UART2_IRQn},
{CSKY_UART3_BASE, UART3_IRQn}
};
typedef struct {
pin_t tx;
pin_t rx;
pin_t cts;
pin_t rts;
uint16_t cfg_idx; //idx of sg_usart_config[]
uint16_t function;
} usart_pin_map_t;
const static usart_pin_map_t s_usart_pin_map[] = {
{
PA0_TXD0_PWM0_XX_SIROUT0,
PA1_RXD0_PWM1_XX_SIRIN0,
-1,
-1,
0,
0
},
{
PA10_TXD1_PWM1_XX_SIROUT1,
PA11_RXD1_PWM2_XX_SIRIN1,
-1,
-1,
1,
0
},
{
PA23_TXD2_PWM5_XX_SIROUT2,
PA22_RXD2_PWM4_XX_SIRIN2,
PA24_CTS2_PWMTRIG0_SPI1CS1_XX,
PA25_XX_PWMTRIG1_SPI1CS2_XX,
2,
0
},
{
PA26_TXD3_PWMFAULT_XX_SIROUT3,
PA27_RXD3_PWM0_XX_SIRIN3,
-1,
-1,
3,
0
}
};
/**
\param[in] instance idx, must not exceed return value of target_get_usart_count()
\brief get usart instance.
\return pointer to usart instance
*/
int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) {
if (s_usart_pin_map[idx].tx == tx && s_usart_pin_map[idx].rx == rx) {
*base = sg_usart_config[s_usart_pin_map[idx].cfg_idx].base;
*irq = sg_usart_config[s_usart_pin_map[idx].cfg_idx].irq;
/*pinmux*/
pin_mux(s_usart_pin_map[idx].tx, s_usart_pin_map[idx].function);
pin_mux(s_usart_pin_map[idx].rx, s_usart_pin_map[idx].function);
return s_usart_pin_map[idx].cfg_idx;
}
}
return -1;
}
/**
\brief control usart flow.
\param[in] tx_flow The TX flow pin name
\param[in] rx_flow The RX flow pin name
\param[in] flag 0-disable, 1-enable.
\return 0 if setting ready ,negative for error code
*/
int32_t target_usart_flowctrl_init(pin_t tx_flow, pin_t rx_flow, uint32_t flag)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++) {
if ((s_usart_pin_map[idx].cts == tx_flow) &&(s_usart_pin_map[idx].rts == rx_flow))
break;
}
if (idx >= sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t)) {
return -1;
}
if ((s_usart_pin_map[idx].cts == tx_flow) && flag) {
pin_mux(s_usart_pin_map[idx].cts, s_usart_pin_map[idx].function);
} else if ((s_usart_pin_map[idx].cts == tx_flow) && (flag == 0)) {
pin_mux(s_usart_pin_map[idx].cts, 0xff);
} else {
return -1;
}
if ((s_usart_pin_map[idx].rts == rx_flow) && flag) {
pin_mux(s_usart_pin_map[idx].rts, s_usart_pin_map[idx].function);
} else if ((s_usart_pin_map[idx].rts == rx_flow) && (flag == 0)) {
pin_mux(s_usart_pin_map[idx].rts, 0xff);
} else {
return -1;
}
return 0;
}
#endif
#if CONFIG_TRNG
struct {
uint32_t base;
}
const sg_trng_config[CONFIG_TRNG_NUM] = {
{CSKY_TRNG_BASE}
};
/**
\brief get trng instance count.
\return trng instance count
*/
int32_t target_get_trng_count(void)
{
return CONFIG_TRNG_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_trng_count()
\brief get trng instance.
\return pointer to trng instance
*/
int32_t target_get_trng(int32_t idx, uint32_t *base)
{
if (idx >= target_get_trng_count()) {
return NULL;
}
*base = sg_trng_config[idx].base;
return idx;
}
#endif
#if CONFIG_CRC
struct {
uint32_t base;
}
const sg_crc_config[CONFIG_CRC_NUM] = {
{CSKY_CRC_BASE}
};
/**
\brief get crc instance count.
\return crc instance count
*/
int32_t target_get_crc_count(void)
{
return CONFIG_CRC_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_crc_count()
\brief get crc instance.
\return pointer to crc instance
*/
int32_t target_get_crc(int32_t idx, uint32_t *base)
{
if (idx >= target_get_crc_count()) {
return NULL;
}
*base = sg_crc_config[idx].base;
return idx;
}
#endif
#if CONFIG_EFLASH
struct {
uint32_t base;
eflash_info info;
}
const sg_eflash_config[CONFIG_EFLASH_NUM] = {
{CSKY_EFLASH_CONTROL_BASE, {0x10000000, 0x1003f800, 0x1fc}}
};
/**
\brief get eflash instance count.
\return eflash instance count
*/
int32_t target_get_eflash_count(void)
{
return CONFIG_EFLASH_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_eflash_count()
\brief get eflash instance.
\return pointer to eflash instance
*/
int32_t target_get_eflash(int32_t idx, uint32_t *base, eflash_info *info)
{
if (idx >= target_get_eflash_count()) {
return NULL;
}
*base = sg_eflash_config[idx].base;
info->start = sg_eflash_config[idx].info.start;
info->end = sg_eflash_config[idx].info.end;
info->sector_count = sg_eflash_config[idx].info.sector_count;
return idx;
}
#endif
#if CONFIG_TIMER
struct {
uint32_t base;
uint32_t irq;
}
const sg_timer_config[CONFIG_TIMER_NUM] = {
{CSKY_TIMERA0_BASE, TIMA0_IRQn},
{CSKY_TIMERA1_BASE, TIMA1_IRQn},
{CSKY_TIMERB0_BASE, TIMB0_IRQn},
{CSKY_TIMERB1_BASE, TIMB1_IRQn}
};
int32_t target_get_timer_count(void)
{
return CONFIG_TIMER_NUM;
}
int32_t target_get_timer(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_timer_count()) {
return NULL;
}
*base = sg_timer_config[idx].base;
*irq = sg_timer_config[idx].irq;
return idx;
}
#endif
#if CONFIG_GPIO
struct {
uint32_t base;
uint32_t irq;
uint32_t pin_num;
port_name_t port;
}
const sg_gpio_config[CONFIG_GPIO_NUM] = {
{CSKY_GPIOA_BASE, GPIOA_IRQn, 32, PORTA},
{CSKY_GPIOB_BASE, GPIOB_IRQn, 11, PORTB}
};
typedef struct {
pin_t gpio_pin;
uint32_t cfg_idx; //idx of sg_gpio_config[]
} gpio_pin_map_t;
const static gpio_pin_map_t s_gpio_pin_map[] = {
{PA0_TXD0_PWM0_XX_SIROUT0, 0},
{PA1_RXD0_PWM1_XX_SIRIN0, 0},
{PA2_CTS0_PWM2_SPI0CLK_XX, 0},
{PA3_RTS0_PWM3_SPI0TX_XX, 0},
{PA4_SCL0_PWM4_SPI0RX_XX, 0},
{PA5_SDA0_PWM5_SPI0CS_XX, 0},
{PA6_SPI0CLK_PWMTRIG0_SCL0_XX, 0},
{PA7_SPI0TX_PWMTRIG1_SDA0_XX, 0},
{PA8_SPI0RX_TRIGFAULT_SCL1_XX, 0},
{PA9_SPI0CS_PWM0_SDA1_XX, 0},
{PA10_TXD1_PWM1_XX_SIROUT1, 0},
{PA11_RXD1_PWM2_XX_SIRIN1, 0},
{PA12_CTS1_PWM3_SPI1CLK_XX, 0},
{PA13_RTS1_PWM4_SPI1TX_XX, 0},
{PA14_SCL1_PWM5_SPI1RX_XX, 0},
{PA15_SDA1_PWMTRIG0_SPI1CS0_XX, 0},
{PA16_SPI1CLK_PWMTRIG1_XX_XX, 0},
{PA17_SPI1TX_PWMFAULT_XX_XX, 0},
{PA18_SPI1RX_PWM0_XX_XX, 0},
{PA19_SPI1CS0_PWM1_XX_XX, 0},
{PA20_SPI1CS1_PWM2_XX_XX, 0},
{PA21_SPI1CS2_PWM3_XX_XX, 0},
{PA22_RXD2_PWM4_XX_SIRIN2, 0},
{PA23_TXD2_PWM5_XX_SIROUT2, 0},
{PA24_CTS2_PWMTRIG0_SPI1CS1_XX, 0},
{PA25_XX_PWMTRIG1_SPI1CS2_XX, 0},
{PA26_TXD3_PWMFAULT_XX_SIROUT3, 0},
{PA27_RXD3_PWM0_XX_SIRIN3, 0},
{PA28_I2SMCLK_PWM1_XX_XX, 0},
{PA29_I2SSCLK_PWM2_XX_XX, 0},
{PA30_I2SWSCLK_PWM3_XX_XX, 0},
{PA31_I2SSDA__SCL0_PWM4_XX, 0},
{PB0_ADC0_SDA0_PWM5_XX, 1},
{PB1_ADC1_SCL1_USISCLK_XX, 1},
{PB2_ADC2_SDA1_USISD0_XX, 1},
{PB3_ADC3_SPI1CLK_USISD1_XX, 1},
{PB4_ADC4_SPI1TX_USINSS_XX, 1},
{PB5_ADC5_SPI1RX_USISCLK_XX, 1},
{PB6_ADC6_SPI1CS0_USISD0_XX, 1},
{PB7_ADC7_SPI1CS1_USISD1_XX, 1},
{PB8_PWMTRIG0_SPI1CS2_USINSS_XX, 1},
{PB9_PWMTRIG1_CTS3_XX_XX, 1},
{PB10_PWMFAULT_RTS3_XX_XX, 1}
};
int32_t target_gpio_port_init(port_name_t port, uint32_t *base, uint32_t *irq, uint32_t *pin_num)
{
int i;
for (i = 0; i < CONFIG_GPIO_NUM; i++) {
if (sg_gpio_config[i].port == port) {
*base = sg_gpio_config[i].base;
*irq = sg_gpio_config[i].irq;
*pin_num = sg_gpio_config[i].pin_num;
return i;
}
}
return -1;
}
/**
\param[in] instance idx, must not exceed return value of target_get_gpio_count()
\brief get gpio instance.
\return pointer to gpio instance
*/
int32_t target_gpio_pin_init(pin_t gpio_pin, uint32_t *port_idx)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_gpio_pin_map) / sizeof(gpio_pin_map_t); idx++) {
if (s_gpio_pin_map[idx].gpio_pin == gpio_pin) {
*port_idx = s_gpio_pin_map[idx].cfg_idx;
/*pinmux*/
pin_mux(s_gpio_pin_map[idx].gpio_pin, 0xff);
if (idx >= 32) {
return idx-32;
}
return idx;
}
}
return -1;
}
#endif
#if CONFIG_AES
struct {
uint32_t base;
uint32_t irq;
}
const sg_aes_config[CONFIG_AES_NUM] = {
{CSKY_AES_BASE, AES_IRQn}
};
/**
\brief get aes instance count.
\return aes instance count
*/
int32_t target_get_aes_count(void)
{
return CONFIG_AES_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_aes_count()
\brief get aes instance.
\return pointer to aes instance
*/
int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_aes_count()) {
return NULL;
}
*base = sg_aes_config[idx].base;
*irq = sg_aes_config[idx].irq;
return idx;
}
#endif
#if CONFIG_RSA
struct {
uint32_t base;
uint32_t irq;
}
const sg_rsa_config[CONFIG_RSA_NUM] = {
{CSKY_RSA_BASE, RSA_IRQn}
};
/**
\brief get rsa instance count.
\return rsa instance count
*/
int32_t target_get_rsa_count(void)
{
return CONFIG_RSA_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_rsa_count()
\brief get rsa instance.
\return pointer to rsa instance
*/
int32_t target_get_rsa(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_rsa_count()) {
return NULL;
}
*base = sg_rsa_config[idx].base;
*irq = sg_rsa_config[idx].irq;
return idx;
}
#endif
#if CONFIG_RTC
struct {
uint32_t base;
uint32_t irq;
}
const sg_rtc_config[CONFIG_RTC_NUM] = {
{CSKY_RTC_BASE, RTC_IRQn}
};
int32_t target_get_rtc_count(void)
{
return CONFIG_RTC_NUM;
}
int32_t target_get_rtc(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_rtc_count()) {
return NULL;
}
*base = sg_rtc_config[idx].base;
*irq = sg_rtc_config[idx].irq;
return idx;
}
#endif
#if CONFIG_SPI
struct {
uint32_t base;
uint32_t irq;
}
const sg_spi_config[CONFIG_SPI_NUM] = {
{CSKY_SPI0_BASE, SPI0_IRQn},
{CSKY_SPI1_BASE, SPI1_IRQn}
};
typedef struct {
pin_t mosi;
pin_t miso;
pin_t sclk;
pin_t ssel;
uint32_t cfg_idx; //idx of sg_iic_config[]
uint16_t function;
} spi_pin_map_t;
const static spi_pin_map_t s_spi_pin_map[] = {
{
PA7_SPI0TX_PWMTRIG1_SDA0_XX,
PA8_SPI0RX_TRIGFAULT_SCL1_XX,
PA6_SPI0CLK_PWMTRIG0_SCL0_XX,
PA9_SPI0CS_PWM0_SDA1_XX,
0,
0
},
{
PA17_SPI1TX_PWMFAULT_XX_XX,
PA18_SPI1RX_PWM0_XX_XX,
PA16_SPI1CLK_PWMTRIG1_XX_XX,
PA19_SPI1CS0_PWM1_XX_XX,
1,
0
},
{
PA13_RTS1_PWM4_SPI1TX_XX,
PA14_SCL1_PWM5_SPI1RX_XX,
PA12_CTS1_PWM3_SPI1CLK_XX,
PA15_SDA1_PWMTRIG0_SPI1CS0_XX,
1,
2
},
{
PB4_ADC4_SPI1TX_USINSS_XX,
PB5_ADC5_SPI1RX_USISCLK_XX,
PB3_ADC3_SPI1CLK_USISD1_XX,
PB6_ADC6_SPI1CS0_USISD0_XX,
1,
1
}
};
/**
\param[in] instance idx, must not exceed return value of target_get_spi_count()
\brief get spi instance.
\return pointer to spi instance
*/
int32_t target_spi_init(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_spi_pin_map) / sizeof(spi_pin_map_t); idx++) {
if (s_spi_pin_map[idx].mosi == mosi && s_spi_pin_map[idx].miso == miso
&& s_spi_pin_map[idx].sclk == sclk && s_spi_pin_map[idx].ssel == ssel) {
*base = sg_spi_config[s_spi_pin_map[idx].cfg_idx].base;
*irq = sg_spi_config[s_spi_pin_map[idx].cfg_idx].irq;
/*pinmux*/
pin_mux(s_spi_pin_map[idx].mosi, s_spi_pin_map[idx].function);
pin_mux(s_spi_pin_map[idx].miso, s_spi_pin_map[idx].function);
pin_mux(s_spi_pin_map[idx].sclk, s_spi_pin_map[idx].function);
pin_mux(s_spi_pin_map[idx].ssel, s_spi_pin_map[idx].function);
return s_spi_pin_map[idx].cfg_idx;
}
}
return -1;
}
#endif
#if CONFIG_WDT
struct {
uint32_t base;
uint32_t irq;
}
const sg_wdt_config[CONFIG_WDT_NUM] = {
{CSKY_WDT_BASE, WDT_IRQn}
};
int32_t target_get_wdt_count(void)
{
return CONFIG_WDT_NUM;
}
int32_t target_get_wdt(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_wdt_count()) {
return NULL;
}
*base = sg_wdt_config[idx].base;
*irq = sg_wdt_config[idx].irq;
return idx;
}
#endif
#if CONFIG_SHA
struct {
uint32_t base;
uint32_t irq;
}
const sg_sha_config[CONFIG_SHA_NUM] = {
{CSKY_SHA_BASE, SHA_IRQn}
};
/**
\brief get sha instance count.
\return sha instance count
*/
int32_t target_get_sha_count(void)
{
return CONFIG_SHA_NUM;
}
/**
\param[in] instance idx, must not exceed return value of target_get_sha_count()
\brief get sha instance.
\return pointer to sha instance
*/
int32_t target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_sha_count()) {
return NULL;
}
*base = sg_sha_config[idx].base;
*irq = sg_sha_config[idx].irq;
return idx;
}
#endif
#if CONFIG_PWM
struct {
uint32_t base;
uint32_t irq;
}
const sg_pwm_config[CONFIG_PWM_NUM] = {
{CSKY_PWM_BASE, PWM_IRQn},
};
typedef struct {
pin_t pwm_pin;
uint32_t cfg_idx; //idx of sg_pwm_config[]
uint32_t ch_num;
uint16_t function;
} pwm_pin_map_t;
const static pwm_pin_map_t s_pwm_pin_map[] = {
{PA0_TXD0_PWM0_XX_SIROUT0, 0, 0, 1},
{PA9_SPI0CS_PWM0_SDA1_XX, 0, 0, 1},
{PA18_SPI1RX_PWM0_XX_XX, 0, 0, 1},
{PA27_RXD3_PWM0_XX_SIRIN3, 0, 0, 1},
{PA1_RXD0_PWM1_XX_SIRIN0, 0, 1, 1},
{PA10_TXD1_PWM1_XX_SIROUT1, 0, 1, 1},
{PA19_SPI1CS0_PWM1_XX_XX, 0, 1, 1},
{PA28_I2SMCLK_PWM1_XX_XX, 0, 1, 1},
{PA2_CTS0_PWM2_SPI0CLK_XX, 0, 2, 1},
{PA11_RXD1_PWM2_XX_SIRIN1, 0, 2, 1},
{PA20_SPI1CS1_PWM2_XX_XX, 0, 2, 1},
{PA29_I2SSCLK_PWM2_XX_XX, 0, 2, 1},
{PA3_RTS0_PWM3_SPI0TX_XX, 0, 3, 1},
{PA12_CTS1_PWM3_SPI1CLK_XX, 0, 3, 1},
{PA21_SPI1CS2_PWM3_XX_XX, 0, 3, 1},
{PA30_I2SWSCLK_PWM3_XX_XX, 0, 3, 1},
{PA4_SCL0_PWM4_SPI0RX_XX, 0, 4, 1},
{PA13_RTS1_PWM4_SPI1TX_XX, 0, 4, 1},
{PA22_RXD2_PWM4_XX_SIRIN2, 0, 4, 1},
{PA31_I2SSDA__SCL0_PWM4_XX, 0, 4, 1},
{PA5_SDA0_PWM5_SPI0CS_XX, 0, 5, 1},
{PA14_SCL1_PWM5_SPI1RX_XX, 0, 5, 1},
{PA23_TXD2_PWM5_XX_SIROUT2, 0, 5, 1},
{PB0_ADC0_SDA0_PWM5_XX, 0, 5, 1},
};
/**
\param[in] instance idx, must not exceed return value of target_get_pwm_count()
\brief get pwm instance.
\return pointer to pwm instance
*/
int32_t target_pwm_init(pin_t pwm_pin, uint32_t *ch_num, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_pwm_pin_map) / sizeof(pwm_pin_map_t); idx++) {
if (s_pwm_pin_map[idx].pwm_pin == pwm_pin) {
*base = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].base;
*irq = sg_pwm_config[s_pwm_pin_map[idx].cfg_idx].irq;
*ch_num = s_pwm_pin_map[idx].ch_num;
/*pinmux*/
pin_mux(s_pwm_pin_map[idx].pwm_pin, s_pwm_pin_map[idx].function);
return s_pwm_pin_map[idx].cfg_idx;
}
}
return -1;
}
#endif
#if CONFIG_DMAC
struct {
uint32_t base;
uint32_t irq;
}
const sg_dmac_config[CONFIG_DMAC_NUM] = {
{CSKY_DMA_BASE, DMAC_IRQn},
};
int32_t target_get_dmac_count(void)
{
return CONFIG_DMAC_NUM;
}
int32_t target_get_dmac(int32_t idx, uint32_t *base, uint32_t *irq)
{
if (idx >= target_get_dmac_count()) {
return NULL;
}
*base = sg_dmac_config[idx].base;
*irq = sg_dmac_config[idx].irq;
return idx;
}
#endif

View file

@ -0,0 +1,88 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file pn_name.h
* @brief header file for the pin_name
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _PINNAMES_H
#define _PINNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PA0_TXD0_PWM0_XX_SIROUT0 = 0,
PA1_RXD0_PWM1_XX_SIRIN0,
PA2_CTS0_PWM2_SPI0CLK_XX,
PA3_RTS0_PWM3_SPI0TX_XX,
PA4_SCL0_PWM4_SPI0RX_XX,
PA5_SDA0_PWM5_SPI0CS_XX,
PA6_SPI0CLK_PWMTRIG0_SCL0_XX,
PA7_SPI0TX_PWMTRIG1_SDA0_XX,
PA8_SPI0RX_TRIGFAULT_SCL1_XX,
PA9_SPI0CS_PWM0_SDA1_XX,
PA10_TXD1_PWM1_XX_SIROUT1,
PA11_RXD1_PWM2_XX_SIRIN1,
PA12_CTS1_PWM3_SPI1CLK_XX,
PA13_RTS1_PWM4_SPI1TX_XX,
PA14_SCL1_PWM5_SPI1RX_XX,
PA15_SDA1_PWMTRIG0_SPI1CS0_XX,
PA16_SPI1CLK_PWMTRIG1_XX_XX,
PA17_SPI1TX_PWMFAULT_XX_XX,
PA18_SPI1RX_PWM0_XX_XX,
PA19_SPI1CS0_PWM1_XX_XX,
PA20_SPI1CS1_PWM2_XX_XX,
PA21_SPI1CS2_PWM3_XX_XX,
PA22_RXD2_PWM4_XX_SIRIN2,
PA23_TXD2_PWM5_XX_SIROUT2,
PA24_CTS2_PWMTRIG0_SPI1CS1_XX,
PA25_XX_PWMTRIG1_SPI1CS2_XX,
PA26_TXD3_PWMFAULT_XX_SIROUT3,
PA27_RXD3_PWM0_XX_SIRIN3,
PA28_I2SMCLK_PWM1_XX_XX,
PA29_I2SSCLK_PWM2_XX_XX,
PA30_I2SWSCLK_PWM3_XX_XX,
PA31_I2SSDA__SCL0_PWM4_XX,
PB0_ADC0_SDA0_PWM5_XX,
PB1_ADC1_SCL1_USISCLK_XX,
PB2_ADC2_SDA1_USISD0_XX,
PB3_ADC3_SPI1CLK_USISD1_XX,
PB4_ADC4_SPI1TX_USINSS_XX,
PB5_ADC5_SPI1RX_USISCLK_XX,
PB6_ADC6_SPI1CS0_USISD0_XX,
PB7_ADC7_SPI1CS1_USISD1_XX,
PB8_PWMTRIG0_SPI1CS2_USINSS_XX,
PB9_PWMTRIG1_CTS3_XX_XX,
PB10_PWMFAULT_RTS3_XX_XX
}
pin_name_t;
typedef enum {
PORTA = 0,
PORTB = 1
} port_name_t;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,221 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file pinmux.h
* @brief Header file for the pinmux
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef PHOBOS_PINMUX_H
#define PHOBOS_PINMUX_H
#include <stdint.h>
#include "pin_name.h"
void phobos_ioreuse_initial(void);
int32_t pin_mux(pin_name_t pin, uint16_t function);
/* IOMUX0L function definition */
#define PA0_UART0_TX 0x00000000
#define PA0_PWM_CH0 0x00000001
#define PA0_UART0_SIROUT 0x00000003
#define PA1_UART0_RX 0x00000000
#define PA1_PWM_CH1 0x00000004
#define PA1_UART0_SIRIN 0x0000000C
#define PA2_UART0_CTS 0x00000000
#define PA2_PWM_CH2 0x00000010
#define PA2_SPI0_CLK 0x00000020
#define PA3_UART0_TRS 0x00000000
#define PA3_PWM_CH3 0x00000040
#define PA3_SPI0_TX 0x00000080
#define PA4_I2C0_SCL 0x00000000
#define PA4_PWM_CH4 0x00000100
#define PA4_SPI0_RX 0x00000200
#define PA5_I2C0_SDA 0x00000000
#define PA5_PWM_CH5 0x00000400
#define PA5_SPI0_CS 0x00000800
#define PA6_SPI0_CLK 0x00000000
#define PA6_ETB_TRIG0 0x00001000
#define PA6_I2C0_SCL 0x00002000
#define PA7_SPI_TX 0x00000000
#define PA7_ETB_TRIG1 0x00004000
#define PA7_I2C0_SDA 0x00008000
#define PA8_SPI0_TX 0x00000000
#define PA8_PWM_FAULT 0x00010000
#define PA8_I2C1_SCL 0x00020000
#define PA9_SPI0_CS 0x00000000
#define PA9_PWM_CH0 0x00040000
#define PA9_I2C1_SDA 0x00080000
#define PA10_UART1_TX 0x00000000
#define PA10_PWM_CH1 0x00100000
#define PA10_UART1_SIROUT 0x00300000
#define PA11_UART1_RX 0x00000000
#define PA11_PWM_CH2 0x00400000
#define PA11_UART1_SIRIN 0x00C00000
#define PA12_UART1_CTS 0x00000000
#define PA12_PWM_CH3 0x01000000
#define PA12_SPI1_CLK 0x02000000
#define PA13_UART1_RTS 0x00000000
#define PA13_PWM_CH4 0x04000000
#define PA13_SPI1_TX 0x08000000
#define PA14_I2C1_SCL 0x00000000
#define PA14_PWM_CH5 0x10000000
#define PA14_SPI1_RX 0x20000000
#define PA15_I2C1_SDA 0x00000000
#define PA15_ETB_TRIG0 0x40000000
#define PA15_SPI1_CS0 0x80000000
/* IOMUX0H function definition */
#define PA16_SPI1_CLK 0x00000000
#define PA16_ETB_TRIG1 0x00000001
#define PA17_SPI1_TX 0x00000000
#define PA17_PWM_FAULT 0x00000004
#define PA18_SPI1_RX 0x00000000
#define PA18_PWM_CH0 0x00000010
#define PA19_SPI1_CS0 0x00000000
#define PA19_PWM_CH1 0x00000040
#define PA20_UART2_RX 0x00000000
#define PA20_PWM_CH2 0x00000100
#define PA21_SPI1_CS2 0x00000000
#define PA21_PWM_CH3 0x00000400
#define PA22_UART2_RX 0x00000000
#define PA22_PWM_CH4 0x00001000
#define PA22_UART2_SIRI 0x00003000
#define PA23_UART2_TX 0x00000000
#define PA23_PWM_CH5 0x00004000
#define PA23_UART2_SIROUT 0x0000C000
#define PA24_UART2_CTS 0x00000000
#define PA24_ETB_TRIG0 0x00010000
#define PA24_SPI1_CS1 0x00020000
#define PA25_UART2_RTS 0x00000000
#define PA25_ETB_TRIG1 0x00040000
#define PA25_SPI1_CS2 0x00080000
#define PA26_UART3_TX 0x00000000
#define PA26_PWM_FAULT 0x00100000
#define PA26_UART3_SIROUT 0x00300000
#define PA27_UART3_RX 0x00000000
#define PA27_PWM_CH0 0x00400000
#define PA27_UART3_SIRIN 0x00C00000
#define PA28_I2S_MCLK 0x00000000
#define PA28_PWM_CH1 0x01000000
#define PA29_I2S_SCLK 0x00000000
#define PA29_PWM_CH2 0x04000000
#define PA30_I2S_WSCLK 0x00000000
#define PA30_PWM_CH3 0x10000000
#define PA31_I2S_SDA 0x00000000
#define PA31_I2C0_SCL 0x40000000
#define PA31_PWM_CH4 0x80000000
/* IOMUX1L function definition */
#define PB0_ADC0 0x00000000
#define PB0_I2C0_SDA 0x00000001
#define PB0_PWM_CH5 0x00000002
#define PB1_ADC1 0x00000000
#define PB1_I2C1_SCL 0x00000004
#define PB1_USI_SCLK 0x00000008
#define PB2_ADC2 0x00000000
#define PB2_I2C1_SDA 0x00000010
#define PB2_USI_SD0 0x00000020
#define PB3_ADC3 0x00000000
#define PB3_SPI1_CLK 0x00000040
#define PB3_USI_SD1 0x00000080
#define PB4_ADC4 0x00000000
#define PB4_SPI1_TX 0x00000100
#define PB4_USI_NSS 0x00000200
#define PB5_ADC5 0x00000000
#define PB5_SPI1_RX 0x00000400
#define PB5_USI_SCLK 0x00000800
#define PB6_ADC6 0x00000000
#define PB6_SPI1_CS0 0x00001000
#define PB6_USI_SD0 0x00002000
#define PB7_ADC7 0x00000000
#define PB7_SPI1_CS1 0x00004000
#define PB7_USI_SD1 0x00008000
#define PB8_ETB_TRIG0 0x00000000
#define PB8_SPI1_CS2 0x00010000
#define PB8_USI_NSS 0x00020000
#define PB9_ETB_TRIG1 0x00000000
#define PB9_UART3_CTS 0x00040000
#define PB10_PWM_FAULT 0x00000000
#define PB10_UART3_RTS 0x00100000
/* flag as identification */
#define GPIO_SET_BIT0 0x00000001
#define GPIO_SET_BIT1 0x00000002
#define GPIO_SET_BIT2 0x00000004
#define GPIO_SET_BIT3 0x00000008
#define GPIO_SET_BIT4 0x00000010
#define GPIO_SET_BIT5 0x00000020
#define GPIO_SET_BIT6 0x00000040
#define GPIO_SET_BIT7 0x00000080
#define GPIO_SET_BIT8 0x00000100
#define GPIO_SET_BIT9 0x00000200
#define GPIO_SET_BIT10 0x00000400
#define GPIO_SET_BIT11 0x00000800
#define GPIO_SET_BIT12 0x00001000
#define GPIO_SET_BIT13 0x00002000
#define GPIO_SET_BIT14 0x00004000
#define GPIO_SET_BIT15 0x00008000
#define GPIO_SET_BIT16 0x00010000
#define GPIO_SET_BIT17 0x00020000
#define GPIO_SET_BIT18 0x00040000
#define GPIO_SET_BIT19 0x00080000
#define GPIO_SET_BIT20 0x00100000
#define GPIO_SET_BIT21 0x00200000
#define GPIO_SET_BIT22 0x00400000
#define GPIO_SET_BIT23 0x00800000
#define GPIO_SET_BIT24 0x01000000
#define GPIO_SET_BIT25 0x02000000
#define GPIO_SET_BIT26 0x04000000
#define GPIO_SET_BIT27 0x08000000
#define GPIO_SET_BIT28 0x10000000
#define GPIO_SET_BIT29 0x20000000
#define GPIO_SET_BIT30 0x40000000
#define GPIO_SET_BIT31 0x80000000
/******************************************************************************
* phobos gpio control and gpio reuse function
* selecting regester adddress
******************************************************************************/
#define PHOBOS_GIPO0_PORTCTL_REG 0x50018008
#define PHOBOS_GIPO1_PORTCTL_REG 0x60018008
#define PHOBOS_IOMUX0L_REG 0x50018100
#define PHOBOS_IOMUX0H_REG 0x50018104
#define PHOBOS_IOMUX1L_REG 0x50018108
/*************basic gpio reuse v1.0********************************************
* UART0(PA0,PA1)
* UART1(PA10,PA11)
* UART2(PA22,PA23)
* UART3(PA26,PA27)
* IIS(PA24,PA25,PA26,PA27)
* SPI1(PA16,PA17,PA18)
* IIC0(PA4,PA5)
******************************************************************************/
#define GPIO0_REUSE_EN (GPIO_SET_BIT0|GPIO_SET_BIT1|GPIO_SET_BIT4|GPIO_SET_BIT5|GPIO_SET_BIT6|GPIO_SET_BIT9|GPIO_SET_BIT10|GPIO_SET_BIT11|GPIO_SET_BIT16|GPIO_SET_BIT17|GPIO_SET_BIT18|GPIO_SET_BIT22|GPIO_SET_BIT23|GPIO_SET_BIT26|GPIO_SET_BIT27)
#define GPIO1_REUSE_EN (GPIO_SET_BIT0)
#define IOMUX0L_FUNCTION_SEL (PA0_UART0_TX|PA1_UART0_RX|PA4_I2C0_SCL|PA5_I2C0_SDA|PA6_ETB_TRIG0|PA9_PWM_CH0|PA10_UART1_TX|PA11_UART1_RX)
#define IOMUX0H_FUNCTION_SEL (PA16_SPI1_CLK|PA17_SPI1_TX|PA18_SPI1_RX|PA22_UART2_RX|PA23_UART2_TX|PA26_UART3_TX|PA27_UART3_RX)
#define IOMUX1L_FUNCTION_SEL (PB0_ADC0)
#define PWM_GPIO0_REUSE_EN (GPIO0_REUSE_EN|GPIO_SET_BIT0|GPIO_SET_BIT1|GPIO_SET_BIT2|GPIO_SET_BIT12|GPIO_SET_BIT13|GPIO_SET_BIT14)
#define PWM_IOMUX0L_FUNCTION_SEL (IOMUX0L_FUNCTION_SEL|PA0_PWM_CH0|PA1_PWM_CH1|PA2_PWM_CH2|PA12_PWM_CH3|PA13_PWM_CH4|PA14_PWM_CH5)
#endif /* PHOBOS_PINMUX_H */

View file

@ -0,0 +1,327 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**************************************************************************//**
* @file soc.h
* @brief CSI Core Peripheral Access Layer Header File for
* CSKYSOC Device Series
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef SOC_H
#define SOC_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SYSTEM_CLOCK
#define SYSTEM_CLOCK (20000000)
#endif
/* ------------------------- Interrupt Number Definition ------------------------ */
typedef enum IRQn
{
/* ---------------------- CSKYCK801 Specific Interrupt Numbers --------------------- */
GPIOA_IRQn = 0,
CORET_IRQn = 1, /* core Timer Interrupt */
TIMA0_IRQn = 2, /* timerA0 Interrupt */
TIMA1_IRQn = 3, /* timerA1 Interrupt */
WDT_IRQn = 5, /* wdt Interrupt */
UART0_IRQn = 6, /* uart0 Interrupt */
UART1_IRQn = 7, /* uart1 Interrupt */
UART2_IRQn = 8, /* uart2 Interrupt */
I2C0_IRQn = 9, /* i2c0 Interrupt */
I2C1_IRQn = 10, /* i2c1 Interrupt */
SPI1_IRQn = 11, /* spi0 Interrupt */
SPI0_IRQn = 12, /* spi1 Interrupt */
RTC_IRQn = 13, /* rtc Interrupt */
EXTWAK_IRQn = 14, /* extwakeup Interrupt */
DMAC_IRQn = 17, /* dmac Interrupt */
PMU_IRQn = 18, /* pmu Interrupt */
PWM_IRQn = 19, /* pwm Interrupt */
UART3_IRQn = 21, /* uart3 Interrupt */
TIMB0_IRQn = 23, /* timerB0 Interrupt */
TIMB1_IRQn = 24, /* timerB1 Interrupt */
GPIOB_IRQn = 27, /* GPIOB Interrupt */
AES_IRQn = 26, /* aes Interrupt */
RSA_IRQn = 28, /* rsa Interrupt */
SHA_IRQn = 29, /* sha Interrupt */
}
IRQn_Type;
/* ================================================================================ */
/* ================ Processor and Core Peripheral Section ================ */
/* ================================================================================ */
/* -------- Configuration of the CK801 Processor and Core Peripherals ------- */
#define __CK802_REV 0x0000U /* Core revision r0p0 */
#define __MGU_PRESENT 0 /* MGU present or not */
#define __NVIC_PRIO_BITS 2 /* Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */
#include "core_ck802.h" /* Processor and core peripherals */
#include "stdint.h"
typedef enum {
CKENUM_DMA_UART0_RX,
CKENUM_DMA_UART0_TX,
CKENUM_DMA_UART1_RX,
CKENUM_DMA_UART1_TX,
CKENUM_DMA_ADC_RX,
CKENUM_DMA_ADC_TX,
CKENUM_DMA_SPI1_RX,
CKENUM_DMA_SPI1_TX,
CKENUM_DMA_SPI0_RX,
CKENUM_DMA_SPI0_TX,
CKENUM_DMA_IIC_RX,
CKENUM_DMA_IIC_TX,
CKENUM_DMA_IIC1_RX,
CKENUM_DMA_IIC1_TX,
CKENUM_DMA_IIS_RX,
CKENUM_DMA_IIS_TX,
CKENUM_DMA_MEMORY
} ckenum_dma_device_e;
/* ================================================================================ */
/* ================ Device Specific Peripheral Section ================ */
/* ================================================================================ */
#if 0
/* ================================================================================ */
/* ============== Universal Asyncronous Receiver / Transmitter (UART) ============= */
/* ================================================================================ */
typedef struct {
union {
__IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */
__OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */
__IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */
};
union {
__IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */
__IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */
};
__IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */
__IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */
__IOM uint32_t MCR; /* Offset: 0x010 (R/W) Modem control register */
__IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */
__IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */
uint32_t RESERVED1[24];
__IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */
} CSKY_UART_TypeDef;
/* ================================================================================ */
/* ============== Inter-Integrated Circuit (IIC) ============= */
/* ================================================================================ */
typedef struct {
__IOM uint32_t IC_CON; /* Offset: 0x000 (R/W) Receive buffer register */
__IOM uint32_t IC_TAR; /* Offset: 0x004 (R/W) Transmission hold register */
__IOM uint32_t IC_SAR; /* Offset: 0x008 (R/W) Clock frequency division low section register */
__IOM uint32_t IC_HS_MADDR; /* Offset: 0x00c (R/W) Clock frequency division high section register */
__IOM uint32_t IC_DATA_CMD; /* Offset: 0x010 (R/W) Interrupt enable register */
__IOM uint32_t IC_SS_SCL_HCNT; /* Offset: 0x014 (R/W) Interrupt indicia register */
__IOM uint32_t IC_SS_SCL_LCNT; /* Offset: 0x018 (R/W) Transmission control register */
__IOM uint32_t IC_FS_SCL_HCNT; /* Offset: 0x01c (R/W) Modem control register */
__IOM uint32_t IC_FS_SCL_LCNT; /* Offset: 0x020 (R/W) Transmission state register */
__IOM uint32_t IC_HS_SCL_HCNT; /* Offset: 0x024 (R/W) Transmission state register */
__IOM uint32_t IC_HS_SCL_LCNT; /* Offset: 0x028 (R/W) Transmission state register */
__IOM uint32_t IC_INTR_STAT; /* Offset: 0x02c (R) Transmission state register */
__IOM uint32_t IC_INTR_MASK; /* Offset: 0x030 (R/W) Transmission state register */
__IOM uint32_t IC_RAW_INTR_STAT; /* Offset: 0x034 (R) Transmission state register */
__IOM uint32_t IC_RX_TL; /* Offset: 0x038 (R/W) Transmission state register */
__IOM uint32_t IC_TX_TL; /* Offset: 0x03c (R/W) Transmission state register */
__IOM uint32_t IC_CLR_INTR; /* Offset: 0x040 (R) Transmission state register */
__IOM uint32_t IC_CLR_RX_UNDER; /* Offset: 0x044 (R) Transmission state register */
__IOM uint32_t IC_CLR_RX_OVER; /* Offset: 0x048 (R) Transmission state register */
__IOM uint32_t IC_CLR_TX_OVER; /* Offset: 0x04c (R) Transmission state register */
__IOM uint32_t IC_CLR_RD_REQ; /* Offset: 0x050 (R) Transmission state register */
__IOM uint32_t IC_CLR_TX_ABRT; /* Offset: 0x054 (R) Transmission state register */
__IOM uint32_t IC_CLR_RX_DONE; /* Offset: 0x058 (R) Transmission state register */
__IOM uint32_t IC_CLR_ACTIVITY; /* Offset: 0x05c (R) Transmission state register */
__IOM uint32_t IC_CLR_STOP_DET; /* Offset: 0x060 (R) Transmission state register */
__IOM uint32_t IC_CLR_START_DET; /* Offset: 0x064 (R) Transmission state register */
__IOM uint32_t IC_CLR_GEN_CALL; /* Offset: 0x068 (R) Transmission state register */
__IOM uint32_t IC_ENABLE; /* Offset: 0x06c (R/W) Transmission state register */
__IOM uint32_t IC_STATUS; /* Offset: 0x070 (R) Transmission state register */
__IOM uint32_t IC_TXFLR; /* Offset: 0x074 (R) Transmission state register */
__IOM uint32_t IC_RXFLR; /* Offset: 0x078 (R) Transmission state register */
uint32_t RESERVED; /* Offset: 0x014 (R/ ) Transmission state register */
__IOM uint32_t IC_TX_ABRT_SOURCE; /* Offset: 0x080 (R/W) Transmission state register */
__IOM uint32_t IC_SAR1; /* Offset: 0x084 (R/W) Transmission state register */
__IOM uint32_t IC_DMA_CR; /* Offset: 0x088 (R/W) Transmission state register */
__IOM uint32_t IC_DMA_TDLR; /* Offset: 0x08c (R/W) Transmission state register */
__IOM uint32_t IC_DMA_RDLR; /* Offset: 0x090 (R/W) Transmission state register */
__IOM uint32_t IC_SAR2; /* Offset: 0x094 (R/W) Transmission state register */
__IOM uint32_t IC_SAR3; /* Offset: 0x098 (R/W) Transmission state register */
__IOM uint32_t IC_MULTI_SLAVE; /* Offset: 0x09c (R/W) Transmission state register */
__IOM uint32_t IC_GEN_CALL_EN; /* Offset: 0x0a0 (R/W) Transmission state register */
} CSKY_IIC_TypeDef;
/* ================================================================================ */
/* ============== TIMER ============= */
/* ================================================================================ */
typedef struct {
__IOM uint32_t TxLoadCount; /* Offset: 0x000 (R/W) Receive buffer register */
__IOM uint32_t TxCurrentValue; /* Offset: 0x004 (R) Transmission hold register */
__IOM uint32_t TxControl; /* Offset: 0x008 (R/W) Clock frequency division low section register */
__IOM uint32_t TxEOI; /* Offset: 0x00c (R) Clock frequency division high section register */
__IOM uint32_t TxIntStatus; /* Offset: 0x010 (R) Interrupt enable register */
} CSKY_TIMER_TypeDef;
/* ================================================================================ */
/* ============== TIMER Control ============= */
/* ================================================================================ */
typedef struct {
__IOM uint32_t TimersIntStatus; /* Offset: 0x000 (R) Interrupt indicia register */
__IOM uint32_t TimerEOI; /* Offset: 0x004 (R) Transmission control register */
__IOM uint32_t TimerRawIntStatus; /* Offset: 0x008 (R) Modem control register */
} CSKY_TIMER_Control_TypeDef;
/* ================================================================================ */
/* ============== GPIO ============= */
/* ================================================================================ */
typedef struct {
__IOM uint32_t SWPORT_DR; /* Offset: 0x000 (R/W) Interrupt indicia register */
__IOM uint32_t SWPORT_DDR; /* Offset: 0x004 (R/W) Interrupt indicia register */
__IOM uint32_t PORT_CTL; /* Offset: 0x008 (R/W) Interrupt indicia register */
} CKStruct_GPIO, *PCKStruct_GPIO;
typedef struct {
__IOM uint32_t SHA_CON; /* Offset: 0x000 (R/W) Control register */
__IOM uint32_t SHA_INTSTATE; /* Offset: 0x004 (R/W) Instatus register */
__IOM uint32_t SHA_H0L; /* Offset: 0x008 (R/W) H0L register */
__IOM uint32_t SHA_H1L; /* Offset: 0x00c (R/W) H1L register */
__IOM uint32_t SHA_H2L; /* Offset: 0x010 (R/W) H2L register */
__IOM uint32_t SHA_H3L; /* Offset: 0x014 (R/W) H3L register */
__IOM uint32_t SHA_H4L; /* Offset: 0x018 (R/W) H4L register */
__IOM uint32_t SHA_H5L; /* Offset: 0x01c (R/W) H5L register */
__IOM uint32_t SHA_H6L; /* Offset: 0x020 (R/W) H6L register */
__IOM uint32_t SHA_H7L; /* Offset: 0x024 (R/W) H7L register */
__IOM uint32_t SHA_H0H; /* Offset: 0x028 (R/W) H0H register */
__IOM uint32_t SHA_H1H; /* Offset: 0x02c (R/W) H1H register */
__IOM uint32_t SHA_H2H; /* Offset: 0x030 (R/W) H2H register */
__IOM uint32_t SHA_H3H; /* Offset: 0x034 (R/W) H3H register */
__IOM uint32_t SHA_H4H; /* Offset: 0x038 (R/W) H4H register */
__IOM uint32_t SHA_H5H; /* Offset: 0x03c (R/W) H5H register */
__IOM uint32_t SHA_H6H; /* Offset: 0x040 (R/W) H6H register */
__IOM uint32_t SHA_H7H; /* Offset: 0x044 (R/W) H7H register */
__IOM uint32_t SHA_DATA1; /* Offset: 0x048 (R/W) DATA1 register */
uint32_t REV[15];
__IOM uint32_t SHA_DATA2; /* Offset: 0x088 (R/W) DATA2 register */
} CSKY_SHA_TypeDef;
#endif
#define CONFIG_CRC_NUM 1
#define CONFIG_IIC_NUM 2
#define CONFIG_TRNG_NUM 1
#define CONFIG_EFLASH_NUM 1
#define CONFIG_AES_NUM 1
#define CONFIG_RSA_NUM 1
#define CONFIG_SHA_NUM 1
#define CONFIG_SPI_NUM 2
#define CONFIG_PWM_NUM 1
#define CONFIG_TIMER_NUM 4
#define CONFIG_RTC_NUM 1
#define CONFIG_WDT_NUM 1
#define CONFIG_DMAC_NUM 1
#define CONFIG_ETH_NUM 2
#define CSKY_I2C0_BASE (0x50014000UL)
#define CSKY_I2C1_BASE (0x60014000UL)
#define CONFIG_USART_NUM 4
#define CSKY_UART0_BASE (0x50010000UL)
#define CSKY_UART1_BASE (0x50010400UL)
#define CSKY_UART2_BASE (0x60010000UL)
#define CSKY_UART3_BASE (0x60010400UL)
/* ================================================================================ */
/* ================ Peripheral memory map ================ */
/* ================================================================================ */
/* -------------------------- CPU FPGA memory map ------------------------------- */
#define CSKY_EFLASH_BASE (0x10000000UL)
#define CSKY_SRAM_BASE (0x20000000UL)
#define CSKY_PMU_BASE (0x40000000UL)
#define CSKY_DMA_BASE (0x40001000UL)
#define CSKY_EFLASH_CONTROL_BASE (0x40005000UL)
#define CSKY_OTP_BASE (0x40006000UL)
#define CSKY_SRAM_CONTROL_BASE (0x40009000UL)
#define CSKY_AES_BASE (0x4000d000UL)
#define CSKY_SHA_BASE (0x4000e000UL)
#define CSKY_RSA_BASE (0x4000f000UL)
#define CSKY_CRC_BASE (0x40010000UL)
#define CSKY_TRNG_BASE (0x40015000UL)
#define CSKY_TIMERA0_BASE (0x50000000UL)
#define CSKY_TIMERA1_BASE (0x50000014UL)
#define CSKY_TIMERA_CONTROL_BASE (0x500000a0UL)
#define CSKY_RTC_BASE (0x50004000UL)
#define CSKY_WDT_BASE (0x50008000UL)
#define CSKY_SPI0_BASE (0x5000c000UL)
#define SHA_CONTEXT_SIZE 224
#define CONFIG_GPIO_NUM 2
#define CONFIG_GPIO_PIN_NUM 43
#define CSKY_GPIOA_BASE (0x50018000UL)
#define CSKY_GPIOA_CONTROL_BASE (0x50018030UL)
#define CSKY_PWM_BASE (0x5001c000UL)
#define CSKY_ADC_BASE (0x50020000UL)
#define CSKY_I2S0_BASE (0x50030000UL)
#define CSKY_TIMERB0_BASE (0x60000000UL)
#define CSKY_TIMERB1_BASE (0x60000014UL)
#define CSKY_SPI1_BASE (0x6000c000UL)
#define CSKY_GPIOB_BASE (0x60018000UL)
#define CSKY_GPIOB_CONTROL_BASE (0x60018030UL)
#define CSKY_TIMERB_CONTROL_BASE (0x600000a0UL)
#define CSKY_SIPC_BASE (0x6001c000UL)
#define CSKY_I2S1_BASE (0x60020000UL)
#define CSKY_ETB_BASE (0x60024000UL)
#define CSKY_USI_BASE (0x60028000UL)
/* ================================================================================ */
/* ================ Peripheral declaration ================ */
/* ================================================================================ */
#define CSKY_UART1 (( CSKY_UART_TypeDef *) CSKY_UART1_BASE)
#define CSKY_SHA (( CSKY_SHA_TypeDef *) CSKY_SHA_BASE)
#include <config.h>
#ifdef CONFIG_HAVE_VIC
#define ATTRIBUTE_ISR __attribute__((isr))
#else
#define ATTRIBUTE_ISR
#endif
#ifdef __cplusplus
}
#endif
#endif /* SOC_H */

View file

@ -0,0 +1,216 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file isr.c
* @brief source file for the interrupt server route
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <drv_common.h>
#include "config.h"
#include "soc.h"
#ifndef CONFIG_KERNEL_NONE
#include <csi_kernel.h>
#endif
extern void dw_usart_irqhandler(int32_t idx);
extern void dw_timer_irqhandler(int32_t idx);
extern void dw_gpio_irqhandler(int32_t idx);
extern void dw_iic_irqhandler(int32_t idx);
extern void ck_rtc_irqhandler(int32_t idx);
extern void dw_spi_irqhandler(int32_t idx);
extern void dw_wdt_irqhandler(int32_t idx);
extern void ck_dma_irqhandler(int32_t idx);
extern void ck_aes_irqhandler(int32_t idx);
extern void ck_sha_irqhandler(int32_t idx);
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
#ifndef CONFIG_KERNEL_NONE
#define CSI_INTRPT_ENTER() csi_kernel_intrpt_enter()
#define CSI_INTRPT_EXIT() csi_kernel_intrpt_exit()
#else
#define CSI_INTRPT_ENTER()
#define CSI_INTRPT_EXIT()
#endif
ATTRIBUTE_ISR void CORET_IRQHandler(void)
{
readl(0xE000E010);
}
#if defined(CONFIG_USART)
ATTRIBUTE_ISR void USART0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void USART1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(1);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void USART2_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(2);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void USART3_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_usart_irqhandler(3);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_TIMER)
ATTRIBUTE_ISR void TIMA0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIMA1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(1);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIMB0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(2);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIMB1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(3);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_GPIO)
ATTRIBUTE_ISR void GPIOA_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIOB_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(1);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_IIC)
ATTRIBUTE_ISR void I2C0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_iic_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void I2C1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_iic_irqhandler(1);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_RTC)
ATTRIBUTE_ISR void RTC_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_rtc_irqhandler(0);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_AES)
ATTRIBUTE_ISR void AES_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_aes_irqhandler(0);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_SHA)
ATTRIBUTE_ISR void SHA_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_sha_irqhandler(0);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_SPI) && defined(CONFIG_GPIO)
ATTRIBUTE_ISR void SPI0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_spi_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void SPI1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_spi_irqhandler(1);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_WDT)
ATTRIBUTE_ISR void WDT_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_wdt_irqhandler(0);
CSI_INTRPT_EXIT();
}
#endif
#if defined(CONFIG_DMAC)
ATTRIBUTE_ISR void DMAC_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_dma_irqhandler(0);
CSI_INTRPT_EXIT();
}
#endif

View file

@ -0,0 +1,150 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file pinmux.c
* @brief source file for the pinmux
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdint.h>
#include "pinmux.h"
#include "pin_name.h"
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
/*******************************************************************************
* function: phobos_ioreuse_inital
*
* description:
* initial phobos_pinmux
*******************************************************************************/
void phobos_ioreuse_initial(void)
{
unsigned int value;
/* gpio data source select */
value = readl(PHOBOS_GIPO0_PORTCTL_REG);
value |= GPIO0_REUSE_EN;
writel(value, PHOBOS_GIPO0_PORTCTL_REG);
value = readl(PHOBOS_GIPO1_PORTCTL_REG);
value |= GPIO1_REUSE_EN;
writel(value, PHOBOS_GIPO1_PORTCTL_REG);
/* reuse function select */
value = readl(PHOBOS_IOMUX0L_REG);
value |= IOMUX0L_FUNCTION_SEL;
writel(value, PHOBOS_IOMUX0L_REG);
value = readl(PHOBOS_IOMUX0H_REG);
value |= IOMUX1L_FUNCTION_SEL;
writel(value, PHOBOS_IOMUX0H_REG);
value = readl(PHOBOS_IOMUX1L_REG);
value |= IOMUX1L_FUNCTION_SEL;
writel(value, PHOBOS_IOMUX1L_REG);
}
void phobos_pwm_ioreuse(void)
{
unsigned int value;
/* gpio data source select */
value = readl(PHOBOS_GIPO0_PORTCTL_REG);
value |= PWM_GPIO0_REUSE_EN;
writel(value, PHOBOS_GIPO0_PORTCTL_REG);
/* reuse function select */
value = readl(PHOBOS_IOMUX0L_REG);
value |= PWM_IOMUX0L_FUNCTION_SEL;
writel(value, PHOBOS_IOMUX0L_REG);
}
int32_t pin_mux(pin_name_t pin, uint16_t function)
{
unsigned int val = 0;
unsigned int reg_val = 0;
uint8_t offset;
if (function > 3) {
if (pin < PB0_ADC0_SDA0_PWM5_XX) {
offset = pin;
/* gpio data source select */
val = readl(PHOBOS_GIPO0_PORTCTL_REG);
val &= ~(1 << offset);
writel(val, PHOBOS_GIPO0_PORTCTL_REG);
return 0;
} else if (pin >= PB0_ADC0_SDA0_PWM5_XX) {
offset = pin - 32;
/* gpio data source select */
val = readl(PHOBOS_GIPO1_PORTCTL_REG);
val &= ~(1 << offset);
writel(val, PHOBOS_GIPO1_PORTCTL_REG);
return 0;
} else {
return -1;
}
}
if (pin >= PB0_ADC0_SDA0_PWM5_XX) {
offset = pin - 32;
/* gpio data source select */
val = readl(PHOBOS_GIPO1_PORTCTL_REG);
val |= (1 << offset);
writel(val, PHOBOS_GIPO1_PORTCTL_REG);
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(PHOBOS_IOMUX1L_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, PHOBOS_IOMUX1L_REG);
return 0;
}
offset = pin;
/* gpio data source select */
val = readl(PHOBOS_GIPO0_PORTCTL_REG);
val |= (1 << offset);
writel(val, PHOBOS_GIPO0_PORTCTL_REG);
if (pin >= PA16_SPI1CLK_PWMTRIG1_XX_XX) {
offset = pin - 16;
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(PHOBOS_IOMUX0H_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, PHOBOS_IOMUX0H_REG);
return 0;
}
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(PHOBOS_IOMUX0L_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, PHOBOS_IOMUX0L_REG);
return 0;
}

View file

@ -0,0 +1,29 @@
/**
* Copyright (C) 2016 CSI Project. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__
#define CONFIG_USART 1
#define CONFIG_SYSTEM_SECURE
#define CONFIG_HAVE_VIC
#define CONFIG_SHA_SUPPORT_MUL_THREAD 1
#define CONFIG_KERNEL_NONE 1
#define CONFIG_DISABLE_IRQ 1
#endif /* __CSI_WIFI_H__ */

View file

@ -0,0 +1,189 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_aes.h
* @brief Header File for AES Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_AES_H_
#define _CSI_AES_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
#include <drv_errno.h>
/// definition for aes handle.
typedef void *aes_handle_t;
/****** AES specific error codes *****/
typedef enum {
AES_ERROR_MODE = (EDRV_SPECIFIC + 1) , ///< Specified Mode not supported
AES_ERROR_DATA_BITS , ///< Specified number of Data bits not supported
AES_ERROR_ENDIAN ///< Specified endian not supported
} drv_aes_error_e;
/*----- AES Control Codes: Mode -----*/
typedef enum {
AES_MODE_ECB = 0, ///< ECB Mode
AES_MODE_CBC , ///< CBC Mode
AES_MODE_CFB , ///< CFB Mode
AES_MODE_OFB , ///< OFB Mode
AES_MODE_CTR ///< CTR Mode
} aes_mode_e;
/*----- AES Control Codes: Crypto Mode -----*/
typedef enum {
AES_CRYPTO_MODE_ENCRYPT = 0, ///< encrypt Mode
AES_CRYPTO_MODE_DECRYPT , ///< decrypt Mode
} aes_crypto_mode_e;
/*----- AES Control Codes: Padding Mode -----*/
typedef enum {
AES_PADDING_MODE_NO = 0, ///< NO-PADDING
AES_PADDING_MODE_ZERO , ///< ZERO-PADDING
AES_PADDING_MODE_PKCS5 ///< PKCS5-PADDING
} aes_padding_mode_e;
/*----- AES Control Codes: Mode Parameters: Key length -----*/
typedef enum {
AES_KEY_LEN_BITS_128 = 0, ///< 128 Data bits
AES_KEY_LEN_BITS_192 , ///< 192 Data bits
AES_KEY_LEN_BITS_256 ///< 256 Data bits
} aes_key_len_bits_e;
/*----- AES Control Codes: Mode Parameters: Endian -----*/
typedef enum {
AES_ENDIAN_LITTLE = 0, ///< Little Endian
AES_ENDIAN_BIG ///< Big Endian
} aes_endian_mode_e;
/**
\brief AES Status
*/
typedef struct {
uint32_t busy : 1; ///< busy flag
} aes_status_t;
/****** AES Event *****/
typedef enum {
AES_EVENT_CRYPTO_COMPLETE = 0 ///< Encrypt completed
} aes_event_e;
typedef void (*aes_event_cb_t)(aes_event_e event); ///< Pointer to \ref aes_event_cb_t : AES Event call back.
/**
\brief AES Device Driver Capabilities.
*/
typedef struct {
uint32_t ecb_mode : 1; ///< supports ECB mode
uint32_t cbc_mode : 1; ///< supports CBC mode
uint32_t cfb_mode : 1; ///< supports CFB mode
uint32_t ofb_mode : 1; ///< supports OFB mode
uint32_t ctr_mode : 1; ///< supports CTR mode
uint32_t bits_128 : 1; ///< supports 128bits key length
uint32_t bits_192 : 1; ///< supports 192bits key length
uint32_t bits_256 : 1; ///< supports 256bits key length
} aes_capabilities_t;
// Function documentation
/**
\brief get aes instance count.
\return aes handle count
*/
int32_t csi_aes_get_instance_count(void);
/**
\brief Initialize AES Interface. 1. Initializes the resources needed for the AES interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_aes_get_instance_count().
\param[in] cb_event Pointer to \ref aes_event_cb_t
\return return aes handle if success
*/
aes_handle_t csi_aes_initialize(int32_t idx, aes_event_cb_t cb_event);
/**
\brief De-initialize AES Interface. stops operation and releases the software resources used by the interface
\param[in] handle aes handle to operate.
\return error code
*/
int32_t csi_aes_uninitialize(aes_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle aes handle to operate.
\return \ref aes_capabilities_t
*/
aes_capabilities_t csi_aes_get_capabilities(aes_handle_t handle);
/**
\brief config aes mode.
\param[in] handle aes handle to operate.
\param[in] mode \ref aes_mode_e
\param[in] keylen_bits \ref aes_key_len_bits_e
\param[in] endian \ref aes_endian_mode_e
\param[in] arg Pointer to the iv address when mode is cbc_mode
\return error code
*/
int32_t csi_aes_config(aes_handle_t handle,
aes_mode_e mode,
aes_key_len_bits_e keylen_bits,
aes_endian_mode_e endian,
uint32_t arg
);
/**
\brief set crypto key.
\param[in] handle aes handle to operate.
\param[in] context aes information context(NULL when hardware implementation)
\param[in] key Pointer to the key buf
\param[in] key_len Pointer to \ref aes_key_len_bits_e
\param[in] enc \ref aes_crypto_mode_e
\return error code
*/
int32_t csi_aes_set_key(aes_handle_t handle, void *context, void *key, aes_key_len_bits_e key_len, aes_crypto_mode_e enc);
/**
\brief encrypt or decrypt
\param[in] handle aes handle to operate.
\param[in] context aes information context(NULL when hardware implementation)
\param[in] in Pointer to the Source data
\param[out] out Pointer to the Result data.
\param[in] len the Source data len.
\param[in] padding \ref aes_padding_mode_e.
\return error code
*/
int32_t csi_aes_crypto(aes_handle_t handle, void *context, void *in, void *out, uint32_t len, aes_padding_mode_e padding);
/**
\brief Get AES status.
\param[in] handle aes handle to operate.
\return AES status \ref aes_status_t
*/
aes_status_t csi_aes_get_status(aes_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_AES_H_ */

View file

@ -0,0 +1,47 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_common.h
* @brief Header File for Common Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _DRV_COMMON_H_
#define _DRV_COMMON_H_
#include <stdint.h>
#include <drv_errno.h>
#include "config.h"
/** pin definition */
typedef int32_t pin_t;
/// \details driver handle
typedef void *drv_handle_t;
/**
\brief General power states
*/
typedef enum {
DRV_POWER_OFF, ///< Power off: no operation possible
DRV_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events
DRV_POWER_FULL ///< Power on: full operation at maximum performance
} csi_power_stat_e;
#endif /* _DRV_COMMON_H */

View file

@ -0,0 +1,150 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_crc.h
* @brief Header File for CRC Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_CRC_H_
#define _CSI_CRC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_errno.h>
#include <drv_common.h>
/****** CRC specific error codes *****/
#define CRC_ERROR_MODE (EDRV_SPECIFIC + 1) ///< Specified Mode not supported
/// definition for crc handle.
typedef void *crc_handle_t;
/*----- CRC Control Codes: Mode -----*/
typedef enum {
CRC_MODE_CRC8 = 0, ///< Mode CRC8
CRC_MODE_CRC16 , ///< Mode CRC16
CRC_MODE_CRC32 ///< Mode CRC32
} crc_mode_e;
/*----- CRC Control Codes: Mode Parameters: Key length -----*/
typedef enum {
CRC_STANDARD_CRC_ROHC = 0, ///< Standard CRC RHOC
CRC_STANDARD_CRC_MAXIM , ///< Standard CRC MAXIAM
CRC_STANDARD_CRC_X25 , ///< Standard CRC X25
CRC_STANDARD_CRC_CCITT , ///< Standard CRC CCITT
CRC_STANDARD_CRC_USB , ///< Standard CRC USB
CRC_STANDARD_CRC_IBM , ///< Standard CRC IBM
CRC_STANDARD_CRC_MODBUS ///< Standard CRC MODBUS
} crc_standard_crc_e;
/**
\brief CRC Status
*/
typedef struct {
uint32_t busy : 1; ///< busy flag
} crc_status_t;
/****** CRC Event *****/
typedef enum {
CRC_EVENT_CALCULATE_COMPLETE = 0, ///< Calculate completed
} crc_event_e;
typedef void (*crc_event_cb_t)(crc_event_e event); ///< Pointer to \ref crc_event_cb_t : CRC Event call back.
/**
\brief CRC Device Driver Capabilities.
*/
typedef struct {
uint32_t ROHC : 1; ///< supports ROHC mode
uint32_t MAXIM : 1; ///< supports MAXIM mode
uint32_t X25 : 1; ///< supports X25 mode
uint32_t CCITT : 1; ///< supports CCITT mode
uint32_t USB : 1; ///< supports USB mode
uint32_t IBM : 1; ///< supports IBM mode
uint32_t MODBUS : 1; ///< supports MODBUS mode
} crc_capabilities_t;
// Function documentation
/**
\brief get crc handle count.
\return crc handle count
*/
int32_t csi_crc_get_instance_count(void);
/**
\brief Initialize CRC Interface. 1. Initializes the resources needed for the CRC interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_crc_get_handle_count()
\param[in] cb_event Pointer to \ref crc_event_cb_t
\return return crc handle if success
*/
crc_handle_t csi_crc_initialize(int32_t idx, crc_event_cb_t cb_event);
/**
\brief De-initialize CRC Interface. stops operation and releases the software resources used by the interface
\param[in] handle crc handle to operate.
\return error code
*/
int32_t csi_crc_uninitialize(crc_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle crc handle to operate.
\return \ref crc_capabilities_t
*/
crc_capabilities_t csi_crc_get_capabilities(crc_handle_t handle);
/**
\brief config crc mode.
\param[in] handle crc handle to operate.
\param[in] mode \ref crc_mode_e
\param[in] standard \ref crc_standard_crc_e
\return error code
*/
int32_t csi_crc_config(crc_handle_t handle,
crc_mode_e mode,
crc_standard_crc_e standard
);
/**
\brief calculate crc.
\param[in] handle crc handle to operate.
\param[in] in Pointer to the input data
\param[out] out Pointer to the result.
\param[in] len intpu data len.
\return error code
*/
int32_t csi_crc_calculate(crc_handle_t handle, const void *in, void *out, uint32_t len);
/**
\brief Get CRC status.
\param[in] handle crc handle to operate.
\return CRC status \ref crc_status_t
*/
crc_status_t csi_crc_get_status(crc_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_CRC_H_ */

View file

@ -0,0 +1,171 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_dmac.h
* @brief header file for dmac driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_DMA_H_
#define _CSI_DMA_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for dmac handle.
typedef void *dmac_handle_t;
/**
\brief DMA Driver Capabilities.
*/
typedef struct {
uint32_t unalign_addr : 1; ///< support for unalign address transfer when memory is source
} dma_capabilities_t;
typedef enum {
DMA_STATE_FREE = 0, ///< DMA not yet initialized or disabled
DMA_STATE_READY, ///< DMA process success and ready for use, but not start yet
DMA_STATE_BUSY, ///< DMA process is ongoing
DMA_STATE_ERROR, ///< DMA transfer error
DMA_STATE_DONE, ///< DMA transfer done
} dma_status_e;
/****** DMA specific error codes *****/
typedef enum {
EDRV_DMA_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
} dma_error_e;
/****** DMA Event *****/
typedef enum {
DMA_EVENT_TRANSFER_DONE = 0, ///< transfer complete
DMA_EVENT_TRANSFER_ERROR = 1, ///< transfer error
} dma_event_e;
typedef enum {
DMA_ADDR_INC = 0,
DMA_ADDR_DEC,
DMA_ADDR_CONSTANT
} dma_addr_inc_e;
typedef enum {
DMA_MEM2MEM = 0,
DMA_MEM2PERH,
DMA_PERH2MEM,
DMA_PERH2PERH,
} dma_trans_type_e;
typedef struct {
dma_addr_inc_e src_inc; ///< source address increment
dma_addr_inc_e dst_inc; ///< destination address increment
uint8_t src_tw; ///< source transfer width in byte
uint8_t dst_tw; ///< destination transfer width in byte
uint8_t hs_if; ///< a hardware handshaking interface
dma_trans_type_e type; ///< transfer type
} dma_config_t;
typedef void (*dma_event_cb_t)(dma_event_e event, int32_t ch); ///< Pointer to \ref dma_event_cb_t : CRC Event call back.
/**
\brief get dma instance count.
\return dma instance count
*/
int32_t csi_dma_get_instance_count(void);
/**
\brief Initialize DMA Interface. 1. Initializes the resources needed for the DMA interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_dma_get_instance_count()
\return pointer to dma instances
*/
dmac_handle_t csi_dma_initialize(int32_t idx);
/**
\brief De-initialize DMA Interface. stops operation and releases the software resources used by the interface
\param[in] handle damc handle to operate.
\return error code
*/
int32_t csi_dma_uninitialize(dmac_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle damc handle to operate.
\return \ref dma_capabilities_t
*/
dma_capabilities_t csi_dma_get_capabilities(dmac_handle_t handle);
/**
\brief get one free dma channel
\param[in] handle damc handle to operate.
\param[in] ch channel num. if -1 then allocate a free channal in this dma
\return -1 - no channel can be used, other - channel index
*/
int32_t csi_dma_alloc_channel(dmac_handle_t handle, int32_t ch);
/**
\brief release dma channel and related resources
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return error code
*/
int32_t csi_dma_release_channel(dmac_handle_t handle, int32_t ch);
/**
\brief
\param[in] handle damc handle to operate.
\param[in] ch channel num. if -1 then allocate a free channal in this dma
\param[in] psrcaddr dma transfer source address
\param[in] pstdaddr dma transfer source address
\param[in] length dma transfer length
\param[in] config dma transfer configure
\param[in] cb_event Pointer to \ref dma_event_cb_t
\return error code
*/
int32_t csi_dma_config(dmac_handle_t handle, int32_t ch,
void *psrcaddr, void *pstdaddr,
uint32_t length, dma_config_t *config, dma_event_cb_t cb_event);
/**
\brief start generate dma signal.
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return error code
*/
int32_t csi_dma_start(dmac_handle_t handle, int32_t ch);
/**
\brief Stop generate dma signal.
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return error code
*/
int32_t csi_dma_stop(dmac_handle_t handle, int32_t ch);
/**
\brief Get DMA status.
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return DMA status \ref dma_status_e
*/
dma_status_e csi_dma_get_status(dmac_handle_t handle, int32_t ch);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_DMA_H_ */

View file

@ -0,0 +1,157 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_eflash.h
* @brief header file for eflash driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_EFLASH_H_
#define _CSI_EFLASH_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for eflash handle.
typedef void *eflash_handle_t;
/**
\brief Flash information
*/
typedef struct {
uint32_t start; ///< Chip Start address
uint32_t end; ///< Chip End address (start+size-1)
uint32_t sector_count; ///< Number of sectors
uint32_t sector_size; ///< Uniform sector size in bytes (0=sector_info used)
uint32_t page_size; ///< Optimal programming page size in bytes
uint32_t program_unit; ///< Smallest programmable unit in bytes
uint8_t erased_value; ///< Contents of erased memory (usually 0xFF)
} eflash_info_t;
/**
\brief Flash Status
*/
typedef struct {
uint32_t busy : 1; ///< Flash busy flag
uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation)
} eflash_status_t;
/****** EFLASH Event *****/
typedef enum {
EFLASH_EVENT_READY = 0, ///< Flash Ready
EFLASH_EVENT_ERROR , ///< Read/Program/Erase Error
} eflash_event_e;
typedef void (*eflash_event_cb_t)(eflash_event_e event); ///< Pointer to \ref eflash_event_cb_t : EFLASH Event call back.
/**
\brief Flash Driver Capabilities.
*/
typedef struct {
uint32_t event_ready : 1; ///< Signal Flash Ready event
uint32_t data_width : 2; ///< Data width: 0=8-bit, 1=16-bit, 2=32-bit
uint32_t erase_chip : 1; ///< Supports EraseChip operation
} eflash_capabilities_t;
// Function documentation
/**
\brief get eflash handle count.
\return eflash handle count
*/
int32_t csi_eflash_get_instance_count(void);
/**
\brief Initialize EFLASH Interface. 1. Initializes the resources needed for the EFLASH interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_eflash_get_instance_count()
\param[in] cb_event Pointer to \ref eflash_event_cb_t
\return pointer to eflash handle
*/
eflash_handle_t csi_eflash_initialize(int32_t idx, eflash_event_cb_t cb_event);
/**
\brief De-initialize EFLASH Interface. stops operation and releases the software resources used by the interface
\param[in] handle eflash handle to operate.
\return error code
*/
int32_t csi_eflash_uninitialize(eflash_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle eflash handle to operate.
\return \ref eflash_capabilities_t
*/
eflash_capabilities_t csi_eflash_get_capabilities(eflash_handle_t handle);
/**
\brief Read data from Flash.
\param[in] handle eflash handle to operate.
\param[in] addr Data address.
\param[out] data Pointer to a buffer storing the data read from Flash.
\param[in] cnt Number of data items to read.
\return number of data items read or error code
*/
int32_t csi_eflash_read(eflash_handle_t handle, uint32_t addr, void *data, uint32_t cnt);
/**
\brief Program data to Flash.
\param[in] handle eflash handle to operate.
\param[in] addr Data address.
\param[in] data Pointer to a buffer containing the data to be programmed to Flash..
\param[in] cnt Number of data items to program.
\return number of data items programmed or error code
*/
int32_t csi_eflash_program(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt);
/**
\brief Erase Flash Sector.
\param[in] handle eflash handle to operate.
\param[in] addr Sector address
\return error code
*/
int32_t csi_eflash_erase_sector(eflash_handle_t handle, uint32_t addr);
/**
\brief Erase complete Flash.
\param[in] handle eflash handle to operate.
\return error code
*/
int32_t csi_eflash_erase_chip(eflash_handle_t handle);
/**
\brief Get Flash information.
\param[in] handle eflash handle to operate.
\return Pointer to Flash information \ref eflash_info
*/
eflash_info_t *csi_eflash_get_info(eflash_handle_t handle);
/**
\brief Get EFLASH status.
\param[in] handle eflash handle to operate.
\return EFLASH status \ref eflash_status_t
*/
eflash_status_t csi_eflash_get_status(eflash_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_EFLASH_H_ */

View file

@ -0,0 +1,121 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_errno.h
* @brief header file for error num
* @version V1.0
* @date 02. June 2017
******************************************************************************/
/******************************************************************************
* @file
* @details Error code field difination
* Error number is devided into 4 field:
* 0x8******* : 8 : means < 0
* 0x*A****** : A : means type number: bsp(1), driver(2), hal(3), app(4)...
* 0x**AB**** : AB : means module number: timer(1), rtc(2), ....
* 0x****AB** : AB : means API number: module API's definition
* 0x******AB : AB : means sub error number
* 0 ~ 0x80 is common error such as EPERM, refer to errno.h
* 0x80 ~ 0xFF is specific error, can difine in module
*
* For example 0x81020113 means:
* 1. 0x8*******: value < 0, means error happened
* 2. 0x*1******: type number is 1, means bsp error
* 3. 0x**02****: module number is 02, means RTC error
* 4. 0x****01**: module API is 01, means RTC's init
* 5. 0x******13: specific error is 0x13=19=ENODEV, means no such device
*
* For special bsp module example, you can return:
* (BSP_ERRNO_TIMER_BASE | BSP_API_RTC_INIT | EPERM) for rtc init error
* (BSP_ERRNO_TIMER_BASE | BSP_API_RTC_SETTIME | ENXIO) for rtc settime error
*
* Here list the common sub error number (0x******AB) below(0~127 defined in errno.h as standard err code):
* Code Hex Deci Meaning
* -------------------------------------------------------
* EPERM 0x01 1 Operation not permitted
* EIO 0x05 5 I/O error
* ENXIO 0x06 6 No such device or address
* ENOMEM 0x0C 12 Out of memory
* EACCES 0x0D 13 Permission denied
* EINVAL 0x16 22 Invalid argument
* ...
* SPEC_ERR_BASE 0x80 128 module special error number base
* ...
* ERRNO_MAX 0xFF -- Max sub error number
******************************************************************************/
#ifndef _DRV_ERRNO_H_
#define _DRV_ERRNO_H_
#include <errno.h>
#define ERRNO_DRV_START 0X80
/* drvier General return codes */
typedef enum {
EDRV = ERRNO_DRV_START, ///< Unspecified error
EDRV_BUSY, ///< Driver is busy
EDRV_TIMEOUT, ///< Timeout occurred
EDRV_UNSUPPORTED, ///< Operation not supported
EDRV_PARAMETER, ///< Parameter error
EDRV_SPECIFIC ///< Start of driver specific errors
} drv_common_err_e;
/** Get error type */
#define GET_ERROR_TYPE(errno) \
(error & 0xFF000000 >> 24)
/** Get error module */
#define GET_ERROR_MODULE(error) \
(error & 0x00FF0000 >> 16)
/** Get error API */
#define GET_ERROR_API(error) \
(error & 0x0000FF00 >> 8)
/** Get errno */
#define GET_ERROR_NUM(error) \
(error & 0x000000FF)
#ifndef CSI_DRV_ERRNO_BASE
/** means bsp errors */
#define CSI_DRV_ERRNO_BASE 0x81000000
#endif
/** driver module id definition*/
#define CSI_DRV_ERRNO_GPIO_BASE 0x81010000
#define CSI_DRV_ERRNO_USART_BASE 0x81020000
#define CSI_DRV_ERRNO_SPI_BASE 0x81030000
#define CSI_DRV_ERRNO_I2C_BASE 0x81040000
#define CSI_DRV_ERRNO_FLASH_BASE 0x81050000
#define CSI_DRV_ERRNO_PWM_BASE 0x81060000
#define CSI_DRV_ERRNO_RTC_BASE 0x81070000
#define CSI_DRV_ERRNO_TIMER_BASE 0x81080000
#define CSI_DRV_ERRNO_WDT_BASE 0x81090000
#define CSI_DRV_ERRNO_AES_BASE 0x810A0000
#define CSI_DRV_ERRNO_CRC_BASE 0x810B0000
#define CSI_DRV_ERRNO_RSA_BASE 0x810C0000
#define CSI_DRV_ERRNO_SHA_BASE 0x810D0000
#define CSI_DRV_ERRNO_TRNG_BASE 0x810E0000
#define CSI_DRV_ERRNO_EFLASH_BASE 0x810F0000
#define CSI_DRV_ERRNO_DMA_BASE 0x81100000
#define CSI_DRV_ERRNO_NORFLASH_BASE 0x81110000
#define CSI_DRV_ERRNO_INTC_BASE 0x81120000
#define CSI_DRV_ERRNO_SPU_BASE 0x81110000
#define CSI_DRV_ERRNO_TEE_BASE 0x81130000
#define CSI_DRV_ERRNO_PMU_BASE 0x81140000
#endif /* CSI_DRV_ERRNO_H */

View file

@ -0,0 +1,105 @@
/**
* Copyright (C) 2016 CSI Project. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _CSI_NET_H_
#define _CSI_NET_H_
#ifdef __cplusplus
extern "C" {
#endif
#define CSI_ETH_VERSION_MAJOR_MINOR(major,minor) (((major) << 8) | (minor))
/**
\brief Driver Version
*/
typedef struct csi_driver_version {
uint16_t api; ///< API version
uint16_t drv; ///< Driver version
} csi_drv_version_t;
/* General return codes */
#define CSI_ETH_OK 0 ///< Operation succeeded
#define CSI_ETH_ERROR CSI_DRV_ERRNO_ETH_BASE+1 ///< Unspecified error
#define CSI_ETH_ERROR_BUSY CSI_DRV_ERRNO_ETH_BASE+2 ///< Driver is busy
#define CSI_ETH_ERROR_TIMEOUT CSI_DRV_ERRNO_ETH_BASE+3 ///< Timeout occurred
#define CSI_ETH_ERROR_UNSUPPORTED CSI_DRV_ERRNO_ETH_BASE+4 ///< Operation not supported
#define CSI_ETH_ERROR_PARAMETER CSI_DRV_ERRNO_ETH_BASE+5 ///< Parameter error
#define CSI_ETH_ERROR_SPECIFIC CSI_DRV_ERRNO_ETH_BASE+6 ///< Start of driver specific errors
/**
\brief General power states
*/
typedef enum eth_power_state {
CSI_ETH_POWER_OFF, ///< Power off: no operation possible
CSI_ETH_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events
CSI_ETH_POWER_FULL ///< Power on: full operation at maximum performance
} eth_power_state_t;
/**
\brief Ethernet Media Interface type
*/
#define CSI_ETH_INTERFACE_MII (0) ///< Media Independent Interface (MII)
#define CSI_ETH_INTERFACE_RMII (1) ///< Reduced Media Independent Interface (RMII)
#define CSI_ETH_INTERFACE_SMII (2) ///< Serial Media Independent Interface (SMII)
/**
\brief Ethernet link speed
*/
#define CSI_ETH_SPEED_10M (0) ///< 10 Mbps link speed
#define CSI_ETH_SPEED_100M (1) ///< 100 Mbps link speed
#define CSI_ETH_SPEED_1G (2) ///< 1 Gpbs link speed
/**
\brief Ethernet duplex mode
*/
#define CSI_ETH_DUPLEX_HALF (0) ///< Half duplex link
#define CSI_ETH_DUPLEX_FULL (1) ///< Full duplex link
/**
\brief Ethernet link state
*/
typedef enum eth_link_state {
ETH_LINK_DOWN, ///< Link is down
ETH_LINK_UP ///< Link is up
} eth_link_state_t;
/**
\brief Ethernet link information
*/
typedef volatile struct eth_link_info {
uint32_t speed : 2; ///< Link speed: 0= 10 MBit, 1= 100 MBit, 2= 1 GBit
uint32_t duplex : 1; ///< Duplex mode: 0= Half, 1= Full
uint32_t Autonegotiation : 1; ///< Set the interface to Auto Negotiation mode of transmission parameters
uint32_t Loopback : 1; ///< Set the interface into a Loop-back test mode
uint32_t Isolation : 1; ///< Set to indicate electrical isolation of PHY interface from MII/RMII interface
uint32_t reserved : 26;
} eth_link_info_t;
/**
\brief Ethernet MAC Address
*/
typedef struct eth_mac_addr {
uint8_t b[6]; ///< MAC Address (6 bytes), MSB first
} eth_mac_addr_t;
#ifdef __cplusplus
}
#endif
#endif /* CSI_NET_H_ */

View file

@ -0,0 +1,422 @@
/**
* Copyright (C) 2016 CSI Project. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _CSI_ETH_H_
#define _CSI_ETH_H_
#include "drv_eth.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void *eth_mac_handle_t;
#define MAX_FRAMELEN 1518 /* (note: maximum ethernet frame length would be 1518) */
#define CSI_ETH_MAC_API_VERSION CSI_DRIVER_VERSION_MAJOR_MINOR(2,1) /* API version */
#define _CSI_Driver_ETH_MAC_(n) Driver_ETH_MAC##n
#define CSI_Driver_ETH_MAC_(n) _CSI_Driver_ETH_MAC_(n)
/****** Ethernet MAC Control Codes *****/
#define CSI_ETH_MAC_CONFIGURE (0x01) ///< Configure MAC; arg = configuration
#define CSI_ETH_MAC_CONTROL_TX (0x02) ///< Transmitter; arg: 0=disabled (default), 1=enabled
#define CSI_ETH_MAC_CONTROL_RX (0x03) ///< Receiver; arg: 0=disabled (default), 1=enabled
#define CSI_ETH_MAC_FLUSH (0x04) ///< Flush buffer; arg = CSI_ETH_MAC_FLUSH_...
#define CSI_ETH_MAC_SLEEP (0x05) ///< Sleep mode; arg: 1=enter and wait for Magic packet, 0=exit
#define CSI_ETH_MAC_VLAN_FILTER (0x06) ///< VLAN Filter for received frames; arg15..0: VLAN Tag; arg16: optional CSI_ETH_MAC_VLAN_FILTER_ID_ONLY; 0=disabled (default)
/*----- Ethernet MAC Configuration -----*/
#define CSI_ETH_MAC_SPEED_Pos 0
#define CSI_ETH_MAC_SPEED_Msk (3UL << CSI_ETH_MAC_SPEED_Pos)
#define CSI_ETH_MAC_SPEED_10M (CSI_ETH_SPEED_10M << CSI_ETH_MAC_SPEED_Pos) ///< 10 Mbps link speed
#define CSI_ETH_MAC_SPEED_100M (CSI_ETH_SPEED_100M << CSI_ETH_MAC_SPEED_Pos) ///< 100 Mbps link speed
#define CSI_ETH_MAC_SPEED_1G (CSI_ETH_SPEED_1G << CSI_ETH_MAC_SPEED_Pos) ///< 1 Gpbs link speed
#define CSI_ETH_MAC_DUPLEX_Pos 2
#define CSI_ETH_MAC_DUPLEX_Msk (1UL << CSI_ETH_MAC_DUPLEX_Pos)
#define CSI_ETH_MAC_DUPLEX_HALF (CSI_ETH_DUPLEX_HALF << CSI_ETH_MAC_DUPLEX_Pos) ///< Half duplex link
#define CSI_ETH_MAC_DUPLEX_FULL (CSI_ETH_DUPLEX_FULL << CSI_ETH_MAC_DUPLEX_Pos) ///< Full duplex link
#define CSI_ETH_MAC_LOOPBACK (1UL << 4) ///< Loop-back test mode
#define CSI_ETH_MAC_CHECKSUM_OFFLOAD_RX (1UL << 5) ///< Receiver Checksum offload
#define CSI_ETH_MAC_CHECKSUM_OFFLOAD_TX (1UL << 6) ///< Transmitter Checksum offload
#define CSI_ETH_MAC_ADDRESS_BROADCAST (1UL << 7) ///< Accept frames with Broadcast address
#define CSI_ETH_MAC_ADDRESS_MULTICAST (1UL << 8) ///< Accept frames with any Multicast address
#define CSI_ETH_MAC_ADDRESS_ALL (1UL << 9) ///< Accept frames with any address (Promiscuous Mode)
/*----- Ethernet MAC Flush Flags -----*/
#define CSI_ETH_MAC_FLUSH_RX (1UL << 0) ///< Flush Receive buffer
#define CSI_ETH_MAC_FLUSH_TX (1UL << 1) ///< Flush Transmit buffer
/*----- Ethernet MAC VLAN Filter Flag -----*/
#define CSI_ETH_MAC_VLAN_FILTER_ID_ONLY (1UL << 16) ///< Compare only the VLAN Identifier (12-bit)
/****** Ethernet MAC Frame Transmit Flags *****/
#define CSI_ETH_MAC_TX_FRAME_FRAGMENT (1UL << 0) ///< Indicate frame fragment
#define CSI_ETH_MAC_TX_FRAME_EVENT (1UL << 1) ///< Generate event when frame is transmitted
#define CSI_ETH_MAC_TX_FRAME_TIMESTAMP (1UL << 2) ///< Capture frame time stamp
/****** Ethernet MAC Timer Control Codes *****/
#define CSI_ETH_MAC_TIMER_GET_TIME (0x01) ///< Get current time
#define CSI_ETH_MAC_TIMER_SET_TIME (0x02) ///< Set new time
#define CSI_ETH_MAC_TIMER_INC_TIME (0x03) ///< Increment current time
#define CSI_ETH_MAC_TIMER_DEC_TIME (0x04) ///< Decrement current time
#define CSI_ETH_MAC_TIMER_SET_ALCSI (0x05) ///< Set alarm time
#define CSI_ETH_MAC_TIMER_ADJUST_CLOCK (0x06) ///< Adjust clock frequency; time->ns: correction factor * 2^31
/**
\brief Ethernet MAC Time
*/
typedef struct eth_mac_time {
uint32_t ns; ///< Nano seconds
uint32_t sec; ///< Seconds
} eth_mac_time_t;
/****** Ethernet MAC Event *****/
#define CSI_ETH_MAC_EVENT_RX_FRAME (1UL << 0) ///< Frame Received
#define CSI_ETH_MAC_EVENT_TX_FRAME (1UL << 1) ///< Frame Transmitted
#define CSI_ETH_MAC_EVENT_WAKEUP (1UL << 2) ///< Wake-up (on Magic Packet)
#define CSI_ETH_MAC_EVENT_TIMER_ALCSI (1UL << 3) ///< Timer Alarm
#define CSI_ETH_MAC_EVENT_LINK_CHANGE (1UL << 4) ///< Link state
typedef void (*eth_event_cb_t)(eth_mac_handle_t handle, uint32_t event); ///< Pointer to \ref eth_event_cb_t : Signal Ethernet Event.
typedef enum
{
FRAME_FILTER_RULE_POSITIVE_MATCHING = 0, /*!< Specifies that a filter should match a given pattern */
FRAME_FILTER_RULE_NEGATIVE_MATCHING = 1, /*!< Specifies that a filter should NOT match a given pattern */
} frame_filter_rule_t;
/**
\brief Ethernet MAC Capabilities
*/
typedef struct eth_capabilities {
uint32_t checksum_offload_rx_ip4 : 1; ///< 1 = IPv4 header checksum verified on receive
uint32_t checksum_offload_rx_ip6 : 1; ///< 1 = IPv6 checksum verification supported on receive
uint32_t checksum_offload_rx_udp : 1; ///< 1 = UDP payload checksum verified on receive
uint32_t checksum_offload_rx_tcp : 1; ///< 1 = TCP payload checksum verified on receive
uint32_t checksum_offload_rx_icmp : 1; ///< 1 = ICMP payload checksum verified on receive
uint32_t checksum_offload_tx_ip4 : 1; ///< 1 = IPv4 header checksum generated on transmit
uint32_t checksum_offload_tx_ip6 : 1; ///< 1 = IPv6 checksum generation supported on transmit
uint32_t checksum_offload_tx_udp : 1; ///< 1 = UDP payload checksum generated on transmit
uint32_t checksum_offload_tx_tcp : 1; ///< 1 = TCP payload checksum generated on transmit
uint32_t checksum_offload_tx_icmp : 1; ///< 1 = ICMP payload checksum generated on transmit
uint32_t media_interface : 2; ///< Ethernet Media Interface type
uint32_t mac_address : 1; ///< 1 = driver provides initial valid MAC address
uint32_t event_rx_frame : 1; ///< 1 = callback event generated
uint32_t event_tx_frame : 1; ///< 1 = callback event generated
uint32_t event_wakeup : 1; ///< 1 = wakeup event generated
uint32_t precision_timer : 1; ///< 1 = Precision Timer supported
uint32_t reserved : 15; ///< Reserved (must be zero)
} eth_capabilities_t;
#if 0
/**
\brief Ethernet Frame filter
*/
typedef struct eth_frame_filter {
struct {
uint32_t and_or : 1; ///< 1 = AND: Packets will be rejected unless all enabled filters accept the packet; 0 = OR: Packets will be accepted unless all enabled filters reject the packet
uint32_t unicast_en : 1; ///< 1 = Packets with a destination address matching the local MAC address will be accepted
uint32_t multicast_en : 1; ///< 1 = Packets which have the Least Significant bit set in the destination address will be accepted
uint32_t broadcast_en : 1; ///< 1 = Packets which have a destination address of FF-FF-FF-FF-FF-FF will be accepted
uint32_t crc_en : 1; ///< 1 = All packets with an invalid CRC will be discarded
uint32_t patten_match_en : 1; ///< 1 = Packets which meet the Pattern Match criteria will be accepted
uint32_t magic_packet_en : 1; ///< 1 = Magic Packets for the local MAC address will be accepted
uint32_t hash_table_en : 1; ///< 1 = Packets which meet the Hash Table criteria will be accepted
} sum; ///< summary
uint32_t patten_match; ///< patten match filter
uint32_t magic_packet; ///< patten match filter
uint32_t hash_table; ///< hash table filter
} eth_frame_filter_t;
#else
/**
* Structure describing a frame filter list item
*/
typedef struct
{
uint32_t id; /*!< Unique identifier for a packet filter item */
frame_filter_rule_t rule; /*!< Filter matches are either POSITIVE or NEGATIVE matching */
uint16_t offset; /*!< Offset in bytes to start filtering (referenced to the start of the ethernet packet) */
uint16_t mask_size; /*!< Size of the mask in bytes */
uint8_t* mask; /*!< Pattern mask bytes to be ANDed with the pattern eg. "\xff00" (must be in network byte order) */
uint8_t* pattern; /*!< Pattern bytes used to filter eg. "\x0800" (must be in network byte order) */
bool enabled_status; /*!< When returned from mhd_get_packet_filters, indicates if the filter is enabled */
} eth_frame_filter_t;
struct eth_frame_filter_list
{
struct eth_frame_filter_list* next;
};
typedef struct eth_frame_filter_list eth_frame_filter_list_t;
#endif
typedef struct {
eth_event_cb_t cb_event;
eth_capabilities_t capabilities;
}eth_mac_priv_t;
/**
\brief Get driver version.
\param[in] handle ethernet handle
\return ethernet version including chip version and driver version
*/
csi_drv_version_t csi_eth_mac_get_version(eth_mac_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle ethernet handle
\return ethernet capabilities
*/
eth_capabilities_t csi_eth_mac_get_capabilities(eth_mac_handle_t handle);
/**
\brief This function is used to initialize Ethernet device and related resource, an event callback is registered. It is called when the middleware component like TCPIP starts operation.
\param[in] cb callback to handle ethernet event
\return return ethernet handle if success
*/
eth_mac_handle_t csi_eth_mac_initialize(eth_event_cb_t cb);
/**
\brief This function is used to de-initialize Ethernet device. It is called when the middleware component stops operation and releases the software resources used by the interface.
\param[in] handle ethernet handle
\return error code
*/
int32_t csi_eth_mac_uninitialize(eth_mac_handle_t handle);
/**
\brief Control Ethernet MAC Device Power.
\param[in] handle ethernet handle
\param[in] state Power state
\return error code
*/
int32_t csi_eth_mac_power_control(eth_mac_handle_t handle, eth_power_state_t state);
/**
\brief Get Ethernet MAC Address.
\param[in] handle ethernet handle
\param[in] mac Pointer to address
\return error code
*/
int32_t csi_eth_mac_get_macaddr(eth_mac_handle_t handle, eth_mac_addr_t *mac);
/**
\brief Set Ethernet MAC Address.
\param[in] handle ethernet handle
\param[in] mac Pointer to address
\return error code
*/
int32_t csi_eth_mac_set_macaddr(eth_mac_handle_t handle, const eth_mac_addr_t *mac);
/**
\brief Configure Address Filter.
\param[in] handle ethernet handle
\param[in] addr Pointer to addresses
\param[in] num_addr Number of addresses to configure
\return error code
*/
int32_t csi_eth_mac_set_addrfilter(eth_mac_handle_t handle, const eth_mac_addr_t *addr, uint32_t num_addr);
/**
\brief Send Ethernet frame.
\param[in] handle ethernet handle
\param[in] frame Pointer to frame buffer with data to send
\param[in] len Frame buffer length in bytes
\param[in] flags Frame transmit flags (see CSI_ETH_MAC_TX_FRAME_...)
\return error code
*/
int32_t csi_eth_mac_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len, uint32_t flags);
/**
\brief Read data of received Ethernet frame.
\param[in] handle ethernet handle
\param[in] frame Pointer to frame buffer for data to read into
\param[in] len Frame buffer length in bytes
\return number of data bytes read or execution status
- value >= 0: number of data bytes read
- value < 0: error occurred, value is execution status as defined with execution_status
*/
int32_t csi_eth_mac_read_frame(eth_mac_handle_t handle, uint8_t *frame, uint32_t len);
/**
\brief Get size of received Ethernet frame.
\param[in] handle ethernet handle
\return number of bytes in received frame
*/
int32_t csi_eth_mac_get_rx_framesize(eth_mac_handle_t handle);
/**
\brief Get time of received Ethernet frame.
\param[in] handle ethernet handle
\param[in] time Pointer to time structure for data to read into
\return error code
*/
int32_t csi_eth_mac_get_rx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time);
/**
\brief Get time of transmitted Ethernet frame.
\param[in] handle ethernet handle
\param[in] time Pointer to time structure for data to read into
\return error code
*/
int32_t csi_eth_mac_get_tx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time);
/**
\brief Control Ethernet Interface.
\param[in] handle ethernet handle
\param[in] control Operation
\param[in] arg Argument of operation (optional)
\return error code
*/
int32_t csi_eth_mac_control(eth_mac_handle_t handle, uint32_t control, uint32_t arg);
/**
\brief Control Precision Timer.
\param[in] handle ethernet handle
\param[in] control Operation
\param[in] time Pointer to time structure
\return error code
*/
int32_t csi_eth_mac_control_time(eth_mac_handle_t handle, uint32_t control, eth_mac_time_t *time);
/**
\brief Read Ethernet PHY Register through Management Interface.
\param[in] handle ethernet handle
\param[in] phy_addr 5-bit device address
\param[in] reg_addr 5-bit register address
\param[out] data Pointer where the result is written to
\return error code
*/
int32_t csi_eth_mac_phy_read(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
/**
\brief Write Ethernet PHY Register through Management Interface.
\param[in] handle ethernet handle
\param[in] phy_addr 5-bit device address
\param[in] reg_addr 5-bit register address
\param[in] data 16-bit data to write
\return error code
*/
int32_t csi_eth_mac_phy_write(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
/**
\brief Callback function that signals a Ethernet Event.
\param[in] handle ethernet handle
\param[in] event event notification mask
\return none
*/
void csi_eth_mac_signal_event(eth_mac_handle_t handle, uint32_t event);
/**
\brief Add Frame Filter Setting with Filter ID.
\param[in] handle ethernet handle
\param[in] filter Pointer to filter setting
\return error code
*/
int32_t csi_eth_mac_add_framefilter(eth_mac_handle_t handle, const eth_frame_filter_t *filter);
/**
\brief Remove Frame Filter Setting.
\param[in] handle ethernet handle
\param[in] filter_id Frame Filter ID
\return error code
*/
int32_t csi_eth_mac_remove_framefilter(eth_mac_handle_t handle, uint32_t filter_id);
/**
\brief Enable/Disable Specified Frame Filter ID.
\param[in] handle ethernet handle
\param[in] filter_id Frame Filter ID
\param[in] en Enable or disable
\return error code
*/
int32_t csi_eth_mac_en_framefilter(eth_mac_handle_t handle, uint32_t filter_id, bool en);
/**
\brief Get frame filter table list.
\param[in] handle ethernet handle
\param[in] list frame filter table list
\param[in] count_out the count of filter setting added
\param[in] max_count max filter setting can be supported
\return error code
*/
int32_t csi_eth_mac_get_framefilter(eth_mac_handle_t handle, eth_frame_filter_list_t* list, uint32_t* count_out, uint32_t max_count);
#ifdef CONFIG_ETH_ENC28J60_USE_PBUF
/**
\brief Begin to Send Ethernet frame.
\param[in] handle ethernet handle
\param[in] len Frame buffer length in bytes
\return error code
*/
int32_t csi_eth_mac_ex_send_frame_begin(eth_mac_handle_t handle, uint32_t len);
/**
* send a packet data
* @param address the packet data length
*
* @return
* - sent data length
*/
int32_t csi_eth_mac_ex_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len, uint32_t flags);
/**
\brief End Send Ethernet frame.
\param[in] handle ethernet handle
\return error code
*/
int32_t csi_eth_mac_ex_send_frame_end(eth_mac_handle_t handle);
/**
\brief Read data of received Ethernet frame.
\param[in] handle ethernet handle
\param[in] frame Pointer to frame buffer for data to read into
\param[in] len Frame buffer length in bytes
\return number of data bytes read or execution status
- value >= 0: number of data bytes read
- value < 0: error occurred, value is execution status as defined with execution_status
*/
int32_t csi_eth_mac_ex_read_frame(eth_mac_handle_t handle, uint8_t *frame, uint32_t len);
/**
\brief Begin to Read data of received Ethernet frame.
\param[in] handle ethernet handle
\param[in] len Frame buffer length in bytes
\return >0 data byte in hardware buffer
==0 no data
< 0 error
*/
int32_t csi_eth_mac_ex_read_frame_begin(eth_mac_handle_t handle);
/**
\brief Begin to Read data of received Ethernet frame.
\param[in] handle ethernet handle
\return error code
*/
int32_t csi_eth_mac_ex_read_frame_end(eth_mac_handle_t handle);
#endif
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,124 @@
/**
* Copyright (C) 2016 CSI Project. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _CSI_ETH_PHY_H_
#define _CSI_ETH_PHY_H_
#include "drv_eth.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void *eth_phy_handle_t;
#define CSI_ETH_PHY_API_VERSION CSI_ETH_VERSION_MAJOR_MINOR(2,1) /* API version */
#define _CSI_Driver_ETH_PHY_(n) Driver_ETH_PHY##n
#define CSI_Driver_ETH_PHY_(n) _CSI_Driver_ETH_PHY_(n)
/****** Ethernet PHY Mode *****/
#define CSI_ETH_PHY_SPEED_Pos 0
#define CSI_ETH_PHY_SPEED_Msk (3UL << CSI_ETH_PHY_SPEED_Pos)
#define CSI_ETH_PHY_SPEED_10M (CSI_ETH_SPEED_10M << CSI_ETH_PHY_SPEED_Pos) ///< 10 Mbps link speed
#define CSI_ETH_PHY_SPEED_100M (CSI_ETH_SPEED_100M << CSI_ETH_PHY_SPEED_Pos) ///< 100 Mbps link speed
#define CSI_ETH_PHY_SPEED_1G (CSI_ETH_SPEED_1G << CSI_ETH_PHY_SPEED_Pos) ///< 1 Gpbs link speed
#define CSI_ETH_PHY_DUPLEX_Pos 2
#define CSI_ETH_PHY_DUPLEX_Msk (1UL << CSI_ETH_PHY_DUPLEX_Pos)
#define CSI_ETH_PHY_DUPLEX_HALF (CSI_ETH_DUPLEX_HALF << CSI_ETH_PHY_DUPLEX_Pos) ///< Half duplex link
#define CSI_ETH_PHY_DUPLEX_FULL (CSI_ETH_DUPLEX_FULL << CSI_ETH_PHY_DUPLEX_Pos) ///< Full duplex link
#define CSI_ETH_PHY_AUTO_NEGOTIATE (1UL << 3) ///< Auto Negotiation mode
#define CSI_ETH_PHY_LOOPBACK (1UL << 4) ///< Loop-back test mode
#define CSI_ETH_PHY_ISOLATE (1UL << 5) ///< Isolate PHY from MII/RMII interface
typedef int32_t (*csi_eth_phy_read_t) (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data); ///< Read Ethernet PHY Register.
typedef int32_t (*csi_eth_phy_write_t) (uint8_t phy_addr, uint8_t reg_addr, uint16_t data); ///< Write Ethernet PHY Register.
typedef struct {
csi_eth_phy_read_t phy_read;
csi_eth_phy_write_t phy_write;
eth_link_info_t link_info;
}eth_phy_priv_t;
// Function documentation
/**
\brief Get driver version.
\param[in] handle ethernet phy handle
\return driver version
*/
csi_drv_version_t csi_eth_phy_get_version(eth_phy_handle_t handle);
/**
\brief Initialize Ethernet PHY Device.
\param[in] fn_read
\param[in] fn_write
\return ethernet phy handle
*/
eth_phy_handle_t csi_eth_phy_initialize(csi_eth_phy_read_t fn_read, csi_eth_phy_write_t fn_write);
/**
\brief De-initialize Ethernet PHY Device.
\param[in] handle ethernet phy handle
\return error code
*/
int32_t csi_eth_phy_uninitialize(eth_phy_handle_t handle);
/**
\brief Control Ethernet PHY Device Power.
\param[in] handle ethernet phy handle
\param[in] state Power state
\return error code
*/
int32_t csi_eth_phy_power_control(eth_phy_handle_t handle, eth_power_state_t state);
/**
\brief Set Ethernet Media Interface.
\param[in] handle ethernet phy handle
\param[in] interface Media Interface type
\return error code
*/
int32_t csi_eth_phy_set_interface(eth_phy_handle_t handle, uint32_t interface);
/**
\brief Set Ethernet PHY Device Operation mode.
\param[in] handle ethernet phy handle
\param[in] mode Operation Mode
\return error code
*/
int32_t csi_eth_phy_set_mode(eth_phy_handle_t handle, uint32_t mode);
/**
\brief Get Ethernet PHY Device Link state.
\param[in] handle ethernet phy handle
\return current link status \ref eth_link_state_t
*/
eth_link_state_t csi_eth_phy_get_linkstate(eth_phy_handle_t handle);
/**
\brief Get Ethernet PHY Device Link information.
\param[in] handle ethernet phy handle
\return current link parameters \ref eth_link_info_t
*/
eth_link_info_t csi_eth_phy_get_linkinfo(eth_phy_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,175 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_flash.c
* @brief header file for flash driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_FLASH_H_
#define _CSI_FLASH_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
typedef struct {
uint32_t base;
void *priv;
} csi_flash_t;
/**
\brief Flash Sector information
*/
typedef struct {
uint32_t start; ///< Sector Start address
uint32_t end; ///< Sector End address (start+size-1)
} const flash_sector;
/**
\brief Flash information
*/
typedef struct {
flash_sector *sector_info; ///< Sector layout information (NULL=Uniform sectors)
uint32_t sector_count; ///< Number of sectors
uint32_t sector_size; ///< Uniform sector size in bytes (0=sector_info used)
uint32_t page_size; ///< Optimal programming page size in bytes
uint32_t program_unit; ///< Smallest programmable unit in bytes
uint8_t erased_value; ///< Contents of erased memory (usually 0xFF)
} flash_info_t;
/**
\brief Flash Status
*/
typedef struct {
uint32_t busy : 1; ///< Flash busy flag
uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation)
} flash_status_t;
/****** FLASH Event *****/
typedef enum {
FLASH_EVENT_READY = 0, ///< Flash Ready
FLASH_EVENT_ERROR , ///< Read/Program/Erase Error
} flash_event_e;
typedef void (*flash_event_cb_t)(flash_event_e event); ///< Pointer to \ref flash_event_cb_t : FLASH Event call back.
/**
\brief Flash Driver Capabilities.
*/
typedef struct {
uint32_t event_ready : 1; ///< Signal Flash Ready event
uint32_t data_width : 2; ///< Data width: 0=8-bit, 1=16-bit, 2=32-bit
uint32_t erase_chip : 1; ///< Supports EraseChip operation
} flash_capabilities_t;
/**
\brief get flash instance count.
\return flash instance count
*/
int32_t drv_flash_get_instance_count(void);
/**
\brief get flash instance .
\param[in] idx must not exceed return value of drv_flash_get_instance_count()
\return pointer to flash instance
*/
csi_flash_t *drv_flash_get_instance(int32_t idx);
/**
\brief Get driver capabilities.
\param[in] instance flash instance to operate.
\return \ref flash_capabilities_t
*/
flash_capabilities_t drv_flash_get_capabilities(const csi_flash_t *instance);
/**
\brief Initialize FLASH Interface. 1. Initializes the resources needed for the FLASH interface 2.registers event callback function
\param[in] instance flash instance to operate.
\param[in] cb_event Pointer to \ref flash_event_cb_t
\return error code
*/
int32_t drv_flash_initialize(const csi_flash_t *instance, flash_event_cb_t cb_event);
/**
\brief De-initialize FLASH Interface. stops operation and releases the software resources used by the interface
\param[in] instance flash instance to operate.
\return error code
*/
int32_t drv_flash_uninitialize(const csi_flash_t *instance);
/**
\brief Get Flash information.
\param[in] instance flash instance to operate.
\return Pointer to Flash information \ref flash_info_t
*/
flash_info_t *drv_flash_get_info(const csi_flash_t *instance);
/**
\brief Read data from Flash.
\param[in] instance flash instance to operate.
\param[in] addr Data address.
\param[in] data Pointer to a buffer storing the data read from Flash.
\param[in] cnt Number of data items to read.
\return number of data items read or error code
*/
int32_t drv_flash_read(const csi_flash_t *instance, uint32_t addr, void *data, uint32_t cnt);
/**
\brief Program data to Flash.
\param[in] instance flash instance to operate.
\param[in] addr Data address.
\param[in] data Pointer to a buffer containing the data to be programmed to Flash..
\param[in] cnt Number of data items to program.
\return number of data items programmed or error code
*/
int32_t drv_flash_program(const csi_flash_t *instance, uint32_t addr, const void *data, uint32_t cnt);
/**
\brief Erase Flash Sector.
\param[in] instance flash instance to operate.
\param[in] addr Sector address
\return error code
*/
int32_t drv_flash_erase_sector(const csi_flash_t *instance, uint32_t addr);
/**
\brief Erase complete Flash.
\param[in] instance flash instance to operate.
\return error code
*/
int32_t drv_flash_erase_chip(const csi_flash_t *instance);
/**
\brief Get FLASH status.
\param[in] instance flash instance to operate.
\return FLASH status \ref flash_status_t
*/
flash_status_t drv_flash_get_status(const csi_flash_t *instance);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_FLASH_H_ */

View file

@ -0,0 +1,192 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_gpio.h
* @brief header file for gpio driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_GPIO_H_
#define _CSI_GPIO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include <drv_common.h>
#include <pin_name.h>
/// definition for gpio port handle.
typedef void *gpio_port_handle_t;
/// definition for gpio pin handle.
typedef void *gpio_pin_handle_t;
/****** GPIO specific error codes *****/
typedef enum {
GPIO_ERROR_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not suphandleed
GPIO_ERROR_DIRECTION, ///< Specified direction not suphandleed
GPIO_ERROR_IRQ_MODE, ///< Specified irq mode not suphandleed
} drv_gpio_error_e;
/*----- GPIO Control Codes: Mode -----*/
typedef enum {
GPIO_MODE_PULLNONE = 1, ///< pull none for input
GPIO_MODE_PULLUP = 5, ///< pull up for input
GPIO_MODE_PULLDOWM = 3, ///< pull down for input
GPIO_MODE_OPEN_DRAIN = 2, ///< open drain mode for output
GPIO_MODE_PUSH_PULL = 4 ///< push-pull mode for output
} gpio_mode_e;
/*----- GPIO Control Codes: Mode Parameters: Data Bits -----*/
typedef enum {
GPIO_DIRECTION_INPUT = 0, ///< gpio as input
GPIO_DIRECTION_OUTPUT , ///< gpio as output
} gpio_direction_e;
/*----- GPIO Control Codes: Mode Parameters: Parity -----*/
typedef enum {
GPIO_IRQ_MODE_RISING_EDGE = 0, ///< interrupt mode for rising edge
GPIO_IRQ_MODE_FALLING_EDGE , ///< interrupt mode for falling edge
GPIO_IRQ_MODE_DOUBLE_EDGE , ///< interrupt mode for double edge
GPIO_IRQ_MODE_LOW_LEVEL , ///< interrupt mode for low level
GPIO_IRQ_MODE_HIGH_LEVEL , ///< interrupt mode for high level
} gpio_irq_mode_e;
/**
\brief GPIO Driver Capabilities.
*/
typedef struct {
uint32_t interrupt_mode : 1; ///< suphandles GPIO interrupt mode
uint32_t pull_mode : 1;
} gpio_capabilities_t;
typedef void (*gpio_event_cb_t)(void *arg); ///< gpio Event call back.
/**
\brief Initialize GPIO module. 1. Initializes the resources needed for the GPIO handle 2.registers event callback function
3.get gpio_port_handle
\param[in] port port_name.
\return gpio_port_handle
*/
gpio_port_handle_t csi_gpio_port_initialize(port_name_t port);
/**
\brief De-initialize GPIO handle. stops operation and releases the software resources used by the handle
\param[in] handle gpio port handle to operate.
\return error code
*/
int32_t csi_gpio_port_uninitialize(gpio_port_handle_t handle);
/**
\brief Get gpio capabilities.all pins have same capabilities in one handle
\param[in] handle handle instance to operate.
\return \ref gpio_capabilities_t
*/
gpio_capabilities_t csi_gpio_get_io_capabilities(gpio_port_handle_t handle);
/**
\brief config multiple pin within one handle
\param[in] handle gpio port handle to operate.
\param[in] mask the bitmask to identify which bits in the handle should be included (0 - ignore)
\param[in] mode \ref gpio_mode_e
\param[in] dir \ref gpio_direction_e
\return error code
*/
int32_t csi_gpio_port_config(gpio_port_handle_t handle,
uint32_t mask,
gpio_mode_e mode,
gpio_direction_e dir);
/**
\brief Write value to the handle(write value to multiple pins on one handle at the same time)
\param[in] handle gpio port handle to operate.
\param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
\param[in] value the value to be set
\return error code
*/
int32_t csi_gpio_port_write(gpio_port_handle_t handle, uint32_t mask, uint32_t value);
/**
\brief Read the current value on the handle(read value of multiple pins on one handle at the same time)
\param[in] handle gpio port handle to operate.
\param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
\param[out] value an integer with each bit corresponding to an associated handle pin setting
\return error code
*/
int32_t csi_gpio_port_read(gpio_port_handle_t handle, uint32_t mask, uint32_t *value);
/**
\brief Initialize GPIO handle.
\param[in] gpio_pin Pointer to the pin_t.
\param[in] cb_event Pointer to \ref gpio_event_cb_t
\param[in] arg Pointer to \ref arg used for the callback
\return gpio_pin_handle
*/
gpio_pin_handle_t csi_gpio_pin_initialize(pin_t gpio_pin, gpio_event_cb_t cb_event, void *arg);
/**
\brief De-initialize GPIO pin handle.stops operation and releases the software resources used by the handle.
\param[in] handle gpio pin handle to operate.
\return error code
*/
int32_t csi_gpio_pin_uninitialize(gpio_pin_handle_t handle);
/**
\brief config pin
\param[in] pin gpio pin handle to operate.
\param[in] mode \ref gpio_mode_e
\param[in] dir \ref gpio_direction_e
\return error code
*/
int32_t csi_gpio_pin_config(gpio_pin_handle_t pin,
gpio_mode_e mode,
gpio_direction_e dir);
/**
\brief Set one or zero to the selected GPIO pin.
\param[in] pin gpio pin handle to operate.
\param[in] value the value to be set
\return error code
*/
int32_t csi_gpio_pin_write(gpio_pin_handle_t pin, bool value);
/**
\brief Get the value of selected GPIO pin.
\param[in] pin gpio pin handle to operate.
\param[out] value buf to store the pin value
\return error code
*/
int32_t csi_gpio_pin_read(gpio_pin_handle_t pin, bool *value);
/**
\brief set GPIO interrupt mode.
\param[in] pin gpio pin handle to operate.
\param[in] mode the irq mode to be set
\param[in] enable the enable flag
\return error code
*/
int32_t csi_gpio_pin_irq_set(gpio_pin_handle_t pin, gpio_irq_mode_e mode, bool enable);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_GPIO_H_ */

View file

@ -0,0 +1,288 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_iic.h
* @brief header file for iic driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_IIC_H_
#define _CSI_IIC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include <drv_common.h>
/// definition for iic handle.
typedef void *iic_handle_t;
/*----- IIC Control Codes: Mode -----*/
typedef enum {
IIC_MODE_MASTER, ///< IIC Master
IIC_MODE_SLAVE ///< IIC Slave
} iic_mode_e;
/*----- IIC Control Codes: IIC Bus Speed -----*/
typedef enum {
I2C_BUS_SPEED_STANDARD = 0, ///< Standard Speed (100kHz)
I2C_BUS_SPEED_FAST = 1, ///< Fast Speed (400kHz)
I2C_BUS_SPEED_FAST_PLUS = 2, ///< Fast+ Speed ( 1MHz)
I2C_BUS_SPEED_HIGH = 3 ///< High Speed (3.4MHz)
} iic_speed_e;
/*----- IIC Control Codes: IIC Address Mode -----*/
typedef enum {
I2C_ADDRESS_7BIT = 0, ///< 7-bit address mode
I2C_ADDRESS_10BIT = 1 ///< 10-bit address mode
} iic_address_mode_e;
/**
\brief IIC Status
*/
typedef struct {
uint32_t busy : 1; ///< Transmitter/Receiver 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(address 0) indication (cleared on start of next Slave operation)
uint32_t arbitration_lost : 1; ///< Master lost arbitration(in case of multi-masters) (cleared on start of next Master operation)
uint32_t bus_error : 1; ///< Bus error detected (cleared on start of next Master/Slave operation)
} iic_status_t;
/****** IIC Event *****/
typedef enum {
I2C_EVENT_TRANSFER_DONE = 0, ///< Master/Slave Transmit/Receive finished
I2C_EVENT_TRANSFER_INCOMPLETE = 1, ///< Master/Slave Transmit/Receive incomplete transfer
I2C_EVENT_SLAVE_TRANSMIT = 2, ///< Slave Transmit operation requested
I2C_EVENT_SLAVE_RECEIVE = 3, ///< Slave Receive operation requested
I2C_EVENT_ADDRESS_NACK = 4, ///< Address not acknowledged from Slave
I2C_EVENT_GENERAL_CALL = 5, ///< General Call indication
I2C_EVENT_ARBITRATION_LOST = 6, ///< Master lost arbitration
I2C_EVENT_BUS_ERROR = 7, ///< Bus error detected (START/STOP at illegal position)
I2C_EVENT_BUS_CLEAR = 8 ///< Bus clear finished
} iic_event_e;
typedef void (*iic_event_cb_t)(iic_event_e event, void *arg); ///< Pointer to \ref iic_event_cb_t : IIC Event call back.
/**
\brief IIC Driver Capabilities.
*/
typedef struct {
uint32_t address_10_bit : 1; ///< supports 10-bit addressing
} iic_capabilities_t;
/**
\brief Initialize IIC Interface specified by pins. \n
1. Initializes the resources needed for the IIC interface 2.registers event callback function
\param[in] scl scl pin of iic.
\param[in] sda sda pin of iic.
\param[in] cb_event Pointer to \ref iic_event_cb_t
\param[in] cb_arg argument for call back function
\return 0 for success, negative for error code
*/
iic_handle_t csi_iic_initialize(pin_t scl, pin_t sda, iic_event_cb_t cb_event, void *cb_arg);
/**
\brief De-initialize IIC Interface. stops operation and releases the software resources used by the interface
\param[in] handle iic handle to operate.
\return 0 for success, negative for error code
*/
int32_t csi_iic_uninitialize(iic_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle iic handle to operate.
\return \ref iic_capabilities_t
*/
iic_capabilities_t csi_iic_get_capabilities(iic_handle_t handle);
/**
\brief config iic attributes.
\param[in] handle iic handle to operate.
\param[in] mode iic mode \ref iic_mode_e. if negative, then this attribute not changed.
\param[in] speed iic speed \ref iic_speed_e. if negative, then this attribute not changed.
\param[in] addr_mode iic address mode \ref iic_address_mode_e. if negative, then this attribute not changed.
\param[in] slave_addr iic address of slave. if negative, then this attribute not changed.
\return 0 for success, negative for error code
*/
int32_t csi_iic_config(iic_handle_t handle,
iic_mode_e mode,
iic_speed_e speed,
iic_address_mode_e addr_mode,
int32_t slave_addr);
/**
\brief Start transmitting data as I2C Master.
This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
\ref csi_iic_get_status can indicates transmission status.
\param[in] handle iic handle to operate.
\param[in] data data to send to I2C Slave
\param[in] num Number of data items to send
\param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
\return 0 for success, negative for error code
*/
int32_t csi_iic_master_send(iic_handle_t handle, const void *data, uint32_t num, bool xfer_pending);
/**
\brief Start receiving data as I2C Master.
This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
\ref csi_iic_get_status can indicates transmission status.
\param[in] handle iic handle to operate.
\param[out] data Pointer to buffer for data to receive from IIC receiver
\param[in] num Number of data items to receive
\param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
\return 0 for success, negative for error code
*/
int32_t csi_iic_master_receive(iic_handle_t handle, void *data, uint32_t num, bool xfer_pending);
/**
\brief Start transmitting data as I2C Slave.
This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
\ref csi_iic_get_status can indicates transmission status.
\param[in] handle iic handle to operate.
\param[in] data Pointer to buffer with data to transmit to I2C Master
\param[in] num Number of data items to send
\return 0 for success, negative for error code
*/
int32_t csi_iic_slave_send(iic_handle_t handle, const void *data, uint32_t num);
/**
\brief Start receiving data as I2C Slave.
This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
\ref csi_iic_get_status can indicates transmission status.
\param[in] handle iic handle to operate.
\param[out] data Pointer to buffer for data to receive from I2C Master
\param[in] num Number of data items to receive
\return 0 for success, negative for error code
*/
int32_t csi_iic_slave_receive(iic_handle_t handle, const void *data, uint32_t num);
/**
\brief abort transfer.
\param[in] handle iic handle to operate.
\return 0 for success, negative for error code
*/
int32_t csi_iic_abort_transfer(iic_handle_t handle);
/**
\brief Get IIC status.
\param[in] handle iic handle to operate.
\return IIC status \ref iic_status_t
*/
iic_status_t csi_iic_get_status(iic_handle_t handle);
/**
\brief control IIC power.
\param[in] handle iic handle to operate.
\param[in] state power state.\ref csi_power_stat_e.
\return error code
*/
int32_t csi_iic_power_control(iic_handle_t handle, csi_power_stat_e state);
/**
\brief config iic mode.
\param[in] handle iic handle to operate.
\param[in] mode \ref iic_mode_e.if negative, then this attribute not changed
\return error code
*/
int32_t csi_iic_config_mode(iic_handle_t handle, iic_mode_e mode);
/**
\brief config iic speed.
\param[in] handle iic handle to operate.
\param[in] speed \ref iic_speed_e.if negative, then this attribute not changed
\return error code
*/
int32_t csi_iic_config_speed(iic_handle_t handle, iic_speed_e speed);
/**
\brief config iic address mode.
\param[in] handle iic handle to operate.
\param[in] addr_mode \ref iic_address_mode_e.if negative, then this attribute not changed
\return error code
*/
int32_t csi_iic_config_addr_mode(iic_handle_t handle, iic_address_mode_e addr_mode);
/**
\brief config iic slave address.
\param[in] handle iic handle to operate.
\param[in] slave_addr slave address.if negative, then this attribute not changed
\return error code
*/
int32_t csi_iic_config_slave_addr(iic_handle_t handle, int32_t slave_addr);
/**
\brief Get IIC transferred data count.
\param[in] handle iic handle to operate.
\return number of data bytes transferred
*/
uint32_t csi_iic_get_data_count(iic_handle_t handle);
/**
\brief Send START command.
\param[in] handle iic handle to operate.
\return error code
*/
int32_t csi_iic_send_start(iic_handle_t handle);
/**
\brief Send STOP command.
\param[in] handle iic handle to operate.
\return error code
*/
int32_t csi_iic_send_stop(iic_handle_t handle);
/**
\brief Reset I2C peripheral.
\param[in] handle iic handle to operate.
\return error code
*/
int32_t csi_iic_reset(iic_handle_t handle);
/**
\brief Read a single byte from the I2C bus.
\param[in] handle iic handle to operate.
\param[in] last Acknoledge,indicates if the byte is to be acknowledged (1 = acknowledge)
\return error code if negative, else the data is the lowest byte of return value
*/
int32_t csi_iic_read_byte(iic_handle_t handle, int32_t last);
/**
\brief Write one byte.
\param[in] handle iic handle to operate.
\return 0 if NAK was received, 1 if ACK was received, 2 for timeout. negative for error
*/
int32_t csi_iic_write_byte(iic_handle_t handle, uint8_t data);
/**
\brief Check to see if the I2C slave has been addressed.
\param[in] handle iic handle to operate.
\return 1 - read addressed, 2 - write to all slaves,
3 - write addressed, 0 - the slave has not been addressed.
negative for error
*/
int32_t csi_iic_slave_check_addressed(iic_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_IIC_H_ */

View file

@ -0,0 +1,163 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_intc.h
* @brief header file for intc driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_INTC_H_
#define _CSI_INTC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
typedef enum int_trigger_mode_t
{
INT_MODE_LOW_LEVEL,
INT_MODE_HIGH_LEVEL,
INT_MODE_RISING_EDGE,
INT_MODE_FALLING_EDGE,
INT_MODE_DOUBLE_EDGE,
} int_trigger_mode_t;
/**
\brief initialize the INTC interrupt controller
\param [in] prio_bits the priority bits of INTC interrupt controller.
*/
void csi_intc_init(void);
/**
\brief Enable External Interrupt
\details Enables a device-specific interrupt in the INTC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
void csi_intc_enable_irq(int32_t IRQn);
/**
\brief Disable External Interrupt
\details Disables a device-specific interrupt in the INTC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
void csi_intc_disable_irq(int32_t IRQn);
/**
\brief Get Pending Interrupt
\details Reads the pending register in the INTC and returns the pending bit for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
uint32_t csi_intc_get_pending_irq(int32_t IRQn);
/**
\brief Set Pending Interrupt
\details Sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
void csi_intc_set_pending_irq(int32_t IRQn);
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
void csi_intc_clear_pending_irq(int32_t IRQn);
/**
\brief Get Wake up Interrupt
\details Reads the wake up register in the INTC and returns the pending bit for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt is not set as wake up interrupt.
\return 1 Interrupt is set as wake up interrupt.
*/
uint32_t csi_intc_get_wakeup_irq(int32_t IRQn);
/**
\brief Set Wake up Interrupt
\details Sets the wake up bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
void csi_intc_set_wakeup_irq(int32_t IRQn);
/**
\brief Clear Wake up Interrupt
\details Clears the wake up bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
void csi_intc_clear_wakeup_irq(int32_t IRQn);
/**
\brief Get Active Interrupt
\details Reads the active register in the INTC and returns the active bit for the device specific interrupt.
\param [in] IRQn Device specific interrupt number.
\return 0 Interrupt status is not active.
\return 1 Interrupt status is active.
\note IRQn must not be negative.
*/
uint32_t csi_intc_get_active(int32_t IRQn);
/**
\brief Set Threshold register
\details set the threshold register in the INTC.
\param [in] VectThreshold specific vecter threshold.
\param [in] PrioThreshold specific priority threshold.
*/
void csi_intc_set_threshold(uint32_t VectThreshold, uint32_t PrioThreshold);
/**
\brief Set Interrupt Priority
\details Sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
void csi_intc_set_prio(int32_t IRQn, uint32_t priority);
/**
\brief Get Interrupt Priority
\details Reads the priority of an interrupt.
The interrupt number can be positive to specify an external (device specific) interrupt,
or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
uint32_t csi_intc_get_prio(int32_t IRQn);
/**
\brief funciton is acknowledge the IRQ. this interface is internally used by irq system
\param[in] irq irq number to operate
\return 0 on success; -1 on failure
*/
int csi_intc_ack_irq(int32_t IRQn);
/**
\briefThis function is set the attributes of an IRQ.
\param[in] irq irq number to operate
\param[in] priority interrupt priority
\param[in] trigger_mode interrupt trigger_mode
\return 0 on success; -1 on failure
*/
int csi_intc_set_attribute(int32_t IRQn, uint32_t priority,int_trigger_mode_t trigger_mode);
#endif /* _CSI_INTC_H_ */

View file

@ -0,0 +1,125 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_pmu.h
* @brief header file for pmu driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_PMU_H_
#define _CSI_PMU_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <drv_common.h>
/// definition for pmu handle.
typedef void *pmu_handle_t;
/****** PMU specific error codes *****/
typedef enum {
EDRV_PMU_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
} pmu_error_e;
/*----- PMU Control Codes: Mode -----*/
typedef enum {
PMU_MODE_RUN = 0, ///< Running mode
PMU_MODE_SLEEP , ///< Sleep mode
PMU_MODE_DORMANT , ///< Dormant mode
PMU_MODE_STDBY , ///< Standby mode
PMU_MODE_SHUTDOWN ///< Shutdown mode
} pmu_mode_e;
/*----- PMU Control Codes: Wakeup type -----*/
typedef enum {
PMU_WAKEUP_TYPE_PULSE = 0, ///< Pulse interrupt
PMU_WAKEUP_TYPE_LEVEL ///< Level interrupt
} pmu_wakeup_type_e;
/*----- PMU Control Codes: Wakeup polarity -----*/
typedef enum {
PMU_WAKEUP_POL_LOW = 0, ///< Low or negedge
PMU_WAKEUP_POL_HIGH ///< High or posedge
} pmu_wakeup_pol_e;
/****** PMU Event *****/
typedef enum {
PMU_EVENT_SLEEP_DONE = 0, ///< Send completed; however PMU may still transmit data
PMU_EVENT_BEFORE_SLEEP = 1
} pmu_event_e;
typedef void (*pmu_event_cb_t)(int32_t idx, pmu_event_e event, pmu_mode_e mode); ///< Pointer to \ref pmu_event_cb_t : PMU Event call back.
typedef int32_t (*pmu_action_cb_t)(pmu_event_e event);
/**
\brief Initialize PMU Interface. 1. Initializes the resources needed for the PMU interface 2.registers event callback function
\param[in] idx the id of the pmu
\param[in] cb_event Pointer to \ref pmu_event_cb_t
\return return pmu handle if success
*/
pmu_handle_t drv_pmu_initialize(int32_t idx, pmu_event_cb_t cb_event);
/**
\brief De-initialize PMU Interface. stops operation and releases the software resources used by the interface
\param[in] handle pmu handle to operate.
\return error code
*/
int32_t drv_pmu_uninitialize(pmu_handle_t handle);
int32_t drv_pmu_power_control(int32_t idx, csi_power_stat_e state);
/**
\brief choose the pmu mode to enter
\param[in] handle pmu handle to operate.
\param[in] mode \ref pmu_mode_e
\return error code
*/
int32_t drv_pmu_enter_sleep(pmu_handle_t handle, pmu_mode_e mode);
/**
\brief choose the pmu mode to enter
\param[in] handle pmu handle to operate.
\param[in] callback Pointer to \ref pmu_action_cb_t
\return error code
*/
int32_t drv_pmu_register_module(pmu_action_cb_t callback);
/**
\brief exit the pmu mode
\param[in] handle pmu handle to operate.
\return error code
*/
int32_t drv_pmu_exit_sleep(pmu_handle_t handle);
/**
\brief Config the wakeup source.
\param[in] handle pmu handle to operate
\param[in] type \ref pmu_wakeup_type
\param[in] pol \ref pmu_wakeup_pol
\param[in] enable flag control the wakeup source is enable or not
\return error code
*/
int32_t drv_pmu_config_wakeup_source(pmu_handle_t handle, uint32_t irq_num, pmu_wakeup_type_e type, pmu_wakeup_pol_e pol, uint8_t enable);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_PMU_H_ */

View file

@ -0,0 +1,94 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_pwm.h
* @brief header file for pwm driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_PWM_H_
#define _CSI_PWM_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for pwm handle.
typedef void *pwm_handle_t;
/****** PWM specific error codes *****/
typedef enum {
EDRV_PWM_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
} drv_pwm_error_e;
/**
\brief Initialize PWM Interface. 1. Initializes the resources needed for the PWM interface 2.registers event callback function
\param[in] pwm_pin pin name of pwm
\return handle pwm handle to operate.
*/
pwm_handle_t drv_pwm_initialize(pin_t pwm_pin);
/**
\brief De-initialize PWM Interface. stops operation and releases the software resources used by the interface
\param[in] handle pwm handle to operate.
\return error code
*/
int32_t drv_pwm_uninitialize(pwm_handle_t handle);
/**
\brief config pwm mode.
\param[in] handle pwm handle to operate.
\param[in] sysclk configured system clock.
\param[in] period_us the PWM period in us
\param[in] duty the PMW duty. ( 0 - 10000 represents 0% - 100% ,other values are invalid)
\return error code
*/
int32_t drv_pwm_config(pwm_handle_t handle,
uint32_t sysclk,
uint32_t period_us,
uint32_t duty);
/**
\brief start generate pwm signal.
\param[in] handle pwm handle to operate.
\return error code
*/
int32_t drv_pwm_start(pwm_handle_t handle);
/**
\brief Stop generate pwm signal.
\param[in] handle pwm handle to operate.
\return error code
*/
int32_t drv_pwm_stop(pwm_handle_t handle);
/**
\brief Get PWM status.
\param[in] handle pwm handle to operate.
\return PWM status \ref pwm_status_t
pwm_status_t drv_pwm_get_status(pwm_handle_t handle);
*/
#ifdef __cplusplus
}
#endif
#endif /* _CSI_PWM_H_ */

View file

@ -0,0 +1,223 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_rsa.h
* @brief header file for rsa driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_RSA_H_
#define _CSI_RSA_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for rsa handle.
typedef void *rsa_handle_t;
/****** RSA specific error codes *****/
typedef enum {
RSA_ERROR_DATA_BITS , ///< Specified number of Data bits not supported
RSA_ERROR_ENDIAN ///< Specified endian not supported
} drv_rsa_error_e;
/*----- RSA Control Codes: Mode Parameters: Data Bits -----*/
typedef enum {
RSA_DATA_BITS_192 = 0, ///< 192 Data bits
RSA_DATA_BITS_256 , ///< 256 Data bits
RSA_DATA_BITS_512 , ///< 512 Data bits
RSA_DATA_BITS_1024 , ///< 1024 Data bits (default)
RSA_DATA_BITS_2048 ///< 2048 Data bits
} rsa_data_bits_e;
/*----- RSA Control Codes: Mode Parameters: Endian -----*/
typedef enum {
RSA_ENDIAN_MODE_LITTLE = 0, ///< RSA Little Endian Mode
RSA_ENDIAN_MODE_BIG ///< RSA Big Endian Mode
} rsa_endian_mode_e;
typedef enum {
RSA_PADDING_MODE_PKCS1 = 1, ///< RSA PKCS1 Padding Mode
RSA_PADDING_MODE_NO , ///< RSA NO Padding Mode
RSA_PADDING_MODE_SSLV23 , ///< RSA SSLV23 Padding Mode
RSA_PADDING_MODE_PKCS1_OAEP , ///< RSA PKCS1 OAEP Padding Mode
RSA_PADDING_MODE_X931 , ///< RSA X931 Padding Mode
RSA_PADDING_MODE_PSS ///< RSA PSS Padding Mode
} rsa_padding_type_e;
typedef enum {
RSA_HASH_TYPE_MD5 = 0,
RSA_HASH_TYPE_SHA1 ,
RSA_HASH_TYPE_SHA224 ,
RSA_HASH_TYPE_SHA256 ,
RSA_HASH_TYPE_SHA384 ,
RSA_HASH_TYPE_SHA512
} rsa_hash_type_e;
/*----- RSA Control Codes: Mode Parameters: Padding mode -----*/
typedef struct {
rsa_padding_type_e padding_type;
rsa_hash_type_e hash_type;
} rsa_padding_t;
/**
\brief RSA Status
*/
typedef struct {
uint32_t busy : 1; ///< Calculate busy flag
} rsa_status_t;
/****** RSA Event *****/
typedef enum {
RSA_EVENT_ENCRYPT_COMPLETE = 0, ///< Encrypt completed
RSA_EVENT_DECRYPT_COMPLETE , ///< Decrypt completed
RSA_EVENT_SIGN_COMPLETE , ///< Sign completed
RSA_EVENT_VERIFY_COMPLETE , ///< Verify completed
} rsa_event_e;
typedef void (*rsa_event_cb_t)(rsa_event_e event); ///< Pointer to \ref rsa_event_cb_t : RSA Event call back.
/**
\brief RSA Device Driver Capabilities.
*/
typedef struct {
uint32_t bits_192 : 1; ///< supports 192bits modular length
uint32_t bits_256 : 1; ///< supports 256bits modular length
uint32_t bits_512 : 1; ///< supports 512bits modular length
uint32_t bits_1024 : 1; ///< supports 1024bits modular length
uint32_t bits_2048 : 1; ///< supports 2048bits modular length
} rsa_capabilities_t;
// Function documentation
/**
\brief get rsa handle count.
\return rsa handle count
*/
int32_t csi_rsa_get_instance_count(void);
/**
\brief Initialize RSA Interface. 1. Initializes the resources needed for the RSA interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_rsa_get_instance_count()
\param[in] cb_event Pointer to \ref rsa_event_cb_t
\return pointer to rsa handle
*/
rsa_handle_t csi_rsa_initialize(int32_t idx, rsa_event_cb_t cb_event);
/**
\brief De-initialize RSA Interface. stops operation and releases the software resources used by the interface
\param[in] handle rsa handle to operate.
\return error code
*/
int32_t csi_rsa_uninitialize(rsa_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle rsa handle to operate.
\return \ref rsa_capabilities_t
*/
rsa_capabilities_t csi_rsa_get_capabilities(rsa_handle_t handle);
/**
\brief config rsa mode.
\param[in] handle rsa handle to operate.
\param[in] data_bits \ref rsa_data_bits_e
\param[in] endian \ref rsa_endian_mode_e
\return error code
*/
int32_t csi_rsa_config(rsa_handle_t handle,
rsa_data_bits_e data_bits,
rsa_endian_mode_e endian,
void *arg
);
/**
\brief encrypt
\param[in] handle rsa handle to operate.
\param[in] n Pointer to the public modulus
\param[in] e Pointer to the public exponent
\param[in] src Pointer to the source data.
\param[in] src_size the source data len
\param[out] out Pointer to the result buffer
\param[out] out_size the result size
\param[in] padding \ref rsa_padding_t
\return error code
*/
int32_t csi_rsa_encrypt(rsa_handle_t handle, void *n, void *e, void *src, int32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding);
/**
\brief decrypt
\param[in] handle rsa handle to operate.
\param[in] n Pointer to the public modulus
\param[in] d Pointer to the privte exponent
\param[in] src Pointer to the source data.
\param[in] src_size the source data len
\param[out] out Pointer to the result buffer
\param[out] out_size the result size
\param[in] padding \ref rsa_padding_t
\return error code
*/
int32_t csi_rsa_decrypt(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding);
/**
\brief rsa sign
\param[in] handle rsa handle to operate.
\param[in] n Pointer to the public modulus
\param[in] d Pointer to the privte exponent
\param[in] src Pointer to the source data.
\param[in] src_size the source data len
\param[out] signature Pointer to the signature
\param[out] sig_size the signature size
\param[in] padding \ref rsa_padding_t
\return error code
*/
int32_t csi_rsa_sign(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *signature, void *sig_size, rsa_padding_t padding);
/**
\brief rsa verify
\param[in] handle rsa handle to operate.
\param[in] n Pointer to the public modulus
\param[in] e Pointer to the public exponent
\param[in] src Pointer to the source data.
\param[in] src_size the source data len
\param[in] signature Pointer to the signature
\param[in] sig_size the signature size
\param[out] result Pointer to the result
\param[in] padding \ref rsa_padding_t
\return error code
*/
int32_t csi_rsa_verify(rsa_handle_t handle, void *n, void *e, void *src, uint32_t src_size, void *signature, uint32_t sig_size, void *result, rsa_padding_t padding);
/**
\brief Get RSA status.
\param[in] handle rsa handle to operate.
\return RSA status \ref rsa_status_t
*/
rsa_status_t csi_rsa_get_status(rsa_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_RSA_H_ */

View file

@ -0,0 +1,161 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_rtc.h
* @brief header file for rtc driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_RTC_H_
#define _CSI_RTC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
#include <time.h>
/// definition for rtc handle.
typedef void *rtc_handle_t;
/****** rtc specific error codes *****/
typedef enum {
EDRV_RTC_TIME = (EDRV_SPECIFIC + 1), ///< timer data not supported
} drv_rtc_error_e;
/**
\brief RTC Status
*/
typedef struct {
uint32_t active : 1; ///< rtc is running or not
} rtc_status_t;
/****** RTC Event *****/
typedef enum {
RTC_EVENT_TIMER_INTRERRUPT = 0 ///< generate interrupt
} rtc_event_e;
typedef void (*rtc_event_cb_t)(rtc_event_e event); ///< Pointer to \ref rtc_event_cb_t : RTC Event call back.
/**
\brief RTC Device Driver Capabilities.
*/
typedef struct {
uint32_t interrupt_mode : 1; ///< supports Interrupt mode
uint32_t wrap_mode : 1; ///< supports wrap mode
} rtc_capabilities_t;
/**
\brief get rtc instance count.
\return rtc instance count
*/
int32_t csi_rtc_get_instance_count(void);
/**
\brief Initialize RTC Interface. 1. Initializes the resources needed for the RTC interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_rtc_get_instance_count()
\param[in] cb_event Pointer to \ref rtc_event_cb_t
\return pointer to rtc instance
*/
rtc_handle_t csi_rtc_initialize(int32_t idx, rtc_event_cb_t cb_event);
/**
\brief De-initialize RTC Interface. stops operation and releases the software resources used by the interface
\param[in] handle rtc handle to operate.
\return error code
*/
int32_t csi_rtc_uninitialize(rtc_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle rtc handle to operate.
\return \ref rtc_capabilities_t
*/
rtc_capabilities_t csi_rtc_get_capabilities(rtc_handle_t handle);
/**
\brief Set RTC timer.
\param[in] handle rtc handle to operate.
\param[in] rtctime pointer to rtc time
\return error code
*/
int32_t csi_rtc_set_time(rtc_handle_t handle, const struct tm *rtctime);
/**
\brief Get RTC timer.
\param[in] handle rtc handle to operate.
\param[in] rtctime pointer to rtc time
\return error code
*/
int32_t csi_rtc_get_time(rtc_handle_t handle, struct tm *rtctime);
/**
\brief Start RTC timer.
\param[in] handle rtc handle to operate.
\return error code
*/
int32_t csi_rtc_start(rtc_handle_t handle);
/**
\brief Stop RTC timer.
\param[in] handle rtc handle to operate.
\return error code
*/
int32_t csi_rtc_stop(rtc_handle_t handle);
/**
\brief config rtc mode.
\param[in] handle rtc handle to operate.
\return error code
*/
//int32_t drv_rtc_config (rtc_handle_t handle/*,rtc_mode_e mode*/);
/**
\brief Get RTC status.
\param[in] handle rtc handle to operate.
\return RTC status \ref rtc_status_t
*/
rtc_status_t csi_rtc_get_status(rtc_handle_t handle);
/**
\brief config RTC timer.
\param[in] handle rtc handle to operate.
\param[in] rtctime time to wake up
\return error code
*/
int32_t csi_rtc_timer_config(rtc_handle_t handle, const struct tm *rtctime);
/**
\brief disable or enable RTC timer.
\param[in] handle rtc handle to operate.
\param[in] en set 1 enable for rtc timer
\return error code
*/
int32_t csi_rtc_timer_enable(rtc_handle_t handle, uint8_t en);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_RTC_H_ */

View file

@ -0,0 +1,172 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_sha.h
* @brief header file for sha driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_SHA_H_
#define _CSI_SHA_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
#include <drv_errno.h>
/// definition for sha handle.
typedef void *sha_handle_t;
/****** SHA specific error codes *****/
typedef enum {
SHA_ERROR_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
SHA_ERROR_ENDIAN ///< Specified endian not supported
} drv_sha_error_e;
/*----- SHA Control Codes: Mode -----*/
typedef enum {
SHA_MODE_1 = 1, ///< SHA_1 mode
SHA_MODE_256 , ///< SHA_256 mode
SHA_MODE_224 , ///< SHA_224 mode
SHA_MODE_512 , ///< SHA_512 mode
SHA_MODE_384 , ///< SHA_384 mode
SHA_MODE_512_256 , ///< SHA_512_256 mode
SHA_MODE_512_224 ///< SHA_512_224 mode
} sha_mode_e;
/*----- SHA Control Codes: Mode Parameters: Endian -----*/
typedef enum {
SHA_ENDIAN_MODE_BIG = 0, ///< Big Endian Mode
SHA_ENDIAN_MODE_LITTLE , ///< Little Endian Mode
} sha_endian_mode_e;
/**
\brief SHA Status
*/
typedef struct {
uint32_t busy : 1; ///< calculate busy flag
} sha_status_t;
/****** SHA Event *****/
typedef enum {
SHA_EVENT_COMPLETE = 0 ///< calculate completed
} sha_event_e;
typedef void (*sha_event_cb_t)(sha_event_e event); ///< Pointer to \ref sha_event_cb_t : SHA Event call back.
/**
\brief SHA Device Driver Capabilities.
*/
typedef struct {
uint32_t sha1 : 1; ///< supports sha1 mode
uint32_t sha224 : 1; ///< supports sha224 mode
uint32_t sha256 : 1; ///< supports sha256 mode
uint32_t sha384 : 1; ///< supports sha384 mode
uint32_t sha512 : 1; ///< supports sha512 mode
uint32_t sha512_224 : 1; ///< supports sha512_224 mode
uint32_t sha512_256 : 1; ///< supports sha512_256 mode
uint32_t endianmode : 1; ///< supports endian mode control
uint32_t interruptmode : 1; ///< supports interrupt mode
} sha_capabilities_t;
// Function documentation
/**
\brief get sha handle count.
\return sha handle count
*/
int32_t csi_sha_get_instance_count(void);
/**
\brief Initialize SHA Interface. 1. Initializes the resources needed for the SHA interface 2.registers event callback function
\param[in] handle Pointer to the buffer store the sha context
\param[in] cb_event Pointer to \ref sha_event_cb_t
\return return sha handle if success
*/
sha_handle_t csi_sha_initialize(sha_handle_t handle, sha_event_cb_t cb_event);
/**
\brief De-initialize SHA Interface. stops operation and releases the software resources used by the interface
\param[in] handle sha handle to operate.
\return error code
*/
int32_t csi_sha_uninitialize(sha_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle sha handle to operate.
\return \ref sha_capabilities_t
*/
sha_capabilities_t csi_sha_get_capabilities(sha_handle_t handle);
/**
\brief config sha mode.
\param[in] handle sha handle to operate.
\param[in] mode \ref sha_mode_e
\param[in] endian \ref sha_endian_mode_e
\return error code
*/
int32_t csi_sha_config(sha_handle_t handle,
sha_mode_e mode,
sha_endian_mode_e endian
);
/**
\brief start the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\return error code
*/
int32_t csi_sha_starts(sha_handle_t handle, void *context);
/**
\brief updata the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\param[in] input Pointer to the Source data
\param[in] len the data len
\return error code
*/
int32_t csi_sha_update(sha_handle_t handle, void *context, const void *input, uint32_t len);
/**
\brief finish the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\param[out] output Pointer to the dest data
\return error code
*/
int32_t csi_sha_finish(sha_handle_t handle, void *context, void *output);
/**
\brief Get SHA status.
\param[in] handle sha handle to operate.
\return SHA status \ref sha_status_t
*/
sha_status_t csi_sha_get_status(sha_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_SHA_H_ */

View file

@ -0,0 +1,320 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_spi.h
* @brief header file for spi driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_SPI_H_
#define _CSI_SPI_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
#include <config.h>
#ifdef CONFIG_SPI_DMA
#include <drv_dmac.h>
#endif
/// definition for spi handle.
typedef void *spi_handle_t;
/****** SPI specific error codes *****/
typedef enum {
EDRV_SPI_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
EDRV_SPI_FRAME_FORMAT, ///< Specified Frame Format not supported
EDRV_SPI_DATA_BITS, ///< Specified number of Data bits not supported
EDRV_SPI_BIT_ORDER, ///< Specified Bit order not supported
EDRV_SPI_SS_MODE ///< Specified Slave Select Mode not supported
} drv_spi_err_e;
/*----- SPI Control Codes: Mode -----*/
typedef enum {
SPI_MODE_INACTIVE = 0, ///< SPI Inactive
SPI_MODE_MASTER, ///< SPI Master (Output on MOSI, Input on MISO); arg = Bus Speed in bps
SPI_MODE_SLAVE, ///< SPI Slave (Output on MISO, Input on MOSI)
SPI_MODE_MASTER_SIMPLEX, ///< SPI Master (Output/Input on MOSI); arg = Bus Speed in bps
SPI_MODE_SLAVE_SIMPLEX ///< SPI Slave (Output/Input on MISO)
} spi_mode_e;
/*----- SPI Control Codes: Mode Parameters: Frame Format -----*/
typedef enum {
SPI_FORMAT_CPOL0_CPHA0 = 0, ///< Clock Polarity 0, Clock Phase 0 (default)
SPI_FORMAT_CPOL0_CPHA1, ///< Clock Polarity 0, Clock Phase 1
SPI_FORMAT_CPOL1_CPHA0, ///< Clock Polarity 1, Clock Phase 0
SPI_FORMAT_CPOL1_CPHA1, ///< Clock Polarity 1, Clock Phase 1
} spi_format_e;
/*----- SPI Control Codes: Mode Parameters: Bit Order -----*/
typedef enum {
SPI_ORDER_MSB2LSB = 0, ///< SPI Bit order from MSB to LSB (default)
SPI_ORDER_LSB2MSB ///< SPI Bit order from LSB to MSB
} spi_bit_order_e;
/*----- SPI Control Codes: Mode Parameters: Data Width in bits -----*/
#define SPI_DATAWIDTH_MAX 32 /* 1 ~ 32 bit*/
/*----- SPI Control Codes: Mode Parameters: Slave Select Mode -----*/
typedef enum {
/*options for SPI_MODE_MASTER/SPI_MODE_MASTER_SIMPLEX */
SPI_SS_MASTER_UNUSED = 0, ///< SPI Slave Select when Master: Not used (default).SS line is not controlled by master, For example,SS line connected to a fixed low level
SPI_SS_MASTER_SW, ///< SPI Slave Select when Master: Software controlled. SS line is configured by software
SPI_SS_MASTER_HW_OUTPUT, ///< SPI Slave Select when Master: Hardware controlled Output.SS line is activated or deactivated automatically by hardware
SPI_SS_MASTER_HW_INPUT, ///< SPI Slave Select when Master: Hardware monitored Input.Used in multi-master configuration where a master does not drive the Slave Select when driving the bus, but rather monitors it
/*options for SPI_MODE_SLAVE/SPI_MODE_SLAVE_SIMPLEX */
SPI_SS_SLAVE_HW, ///< SPI Slave Select when Slave: Hardware monitored (default).Hardware monitors the Slave Select line and accepts transfers only when the line is active
SPI_SS_SLAVE_SW ///< SPI Slave Select when Slave: Software controlled.Used only when the Slave Select line is not used. Software controls if the slave is responding or not(enables or disables transfers)
} spi_ss_mode_e;
/****** SPI Slave Select Signal definitions *****/
typedef enum {
SPI_SS_INACTIVE = 0, ///< SPI Slave Select Signal/line Inactive
SPI_SS_ACTIVE ///< SPI Slave Select Signal/line Active
} spi_ss_stat_e;
/**
\brief SPI Status
*/
typedef struct {
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)
} spi_status_t;
/****** SPI Event *****/
typedef enum {
SPI_EVENT_TRANSFER_COMPLETE = 0, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation
SPI_EVENT_TX_COMPLETE, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation
SPI_EVENT_RX_COMPLETE, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation
SPI_EVENT_DATA_LOST, ///< Data lost: Receive overflow / Transmit underflow. Occurs in slave mode when data is requested/sent by master but send/receive/transfer operation has not been started and indicates that data is lost. Occurs also in master mode when driver cannot transfer data fast enough.
SPI_EVENT_MODE_FAULT ///< Master Mode Fault (SS deactivated when Master).Occurs in master mode when Slave Select is deactivated and indicates Master Mode Fault. The driver is ready for the next transfer operation.
} spi_event_e;
typedef void (*spi_event_cb_t)(spi_event_e event, void *arg); ///< Pointer to \ref spi_event_cb_t : SPI Event call back.
/**
\brief SPI Driver Capabilities.
*/
typedef struct {
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 spi_event_e
} spi_capabilities_t;
/**
\brief Initialize SPI Interface. 1. Initializes the resources needed for the SPI interface 2.registers event callback function
\param[in] mosi spi pin of mosi
\param[in] miso spi pin of miso
\param[in] sclk spi pin of sclk
\param[in] ssel spi pin of ssel
\param[in] cb_event event call back function \ref spi_event_cb_t
\param[in] cb_arg argument for call back function
\return return spi handle if success
*/
spi_handle_t csi_spi_initialize(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel, spi_event_cb_t cb_event, void *cb_arg);
/**
\brief De-initialize SPI Interface. stops operation and releases the software resources used by the interface
\param[in] handle spi handle to operate.
\return error code
*/
int32_t csi_spi_uninitialize(spi_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle spi handle to operate.
\return \ref spi_capabilities_t
*/
spi_capabilities_t csi_spi_get_capabilities(spi_handle_t handle);
/**
\brief config spi mode.
\param[in] handle spi handle to operate.
\param[in] sysclk sysclk for spi module.
\param[in] baud spi baud rate. if negative, then this attribute not changed
\param[in] mode \ref spi_mode_e . if negative, then this attribute not changed
\param[in] format \ref spi_format_e . if negative, then this attribute not changed
\param[in] order \ref spi_bit_order_e . if negative, then this attribute not changed
\param[in] ss_mode \ref spi_ss_mode_e . if negative, then this attribute not changed
\param[in] bit_width spi data bitwidth: (1 ~ SPI_DATAWIDTH_MAX) . if negative, then this attribute not changed
\return error code
*/
int32_t csi_spi_config(spi_handle_t handle,
int32_t sysclk,
int32_t baud,
spi_mode_e mode,
spi_format_e format,
spi_bit_order_e order,
spi_ss_mode_e ss_mode,
int32_t bit_width);
/**
\brief config spi default tx value.
\param[in] handle spi handle to operate.
\param[in] value default tx value
\return error code
*/
int32_t csi_spi_set_default_tx_value(spi_handle_t handle, uint32_t value);
/**
\brief sending data to SPI transmitter,(received data is ignored).
if non-blocking mode, this function only start the sending,
\ref spi_event_e is signaled when operation completes or error happens.
\ref csi_spi_get_status can indicates operation status.
if blocking mode, this function return after operation completes or error happens.
\param[in] handle spi handle to operate.
\param[in] data Pointer to buffer with data to send to SPI transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits,
\param[in] num Number of data items to send.
\param[in] block_mode blocking and non_blocking to selcect
\return error code
*/
int32_t csi_spi_send(spi_handle_t handle, const void *data, uint32_t num, uint8_t block_mode);
/**
\brief receiving data from SPI receiver.transmits the default value as specified by csi_spi_set_default_tx_value
if non-blocking mode, this function only start the receiving,
\ref spi_event_e is signaled when operation completes or error happens.
\ref csi_spi_get_status can indicates operation status.
if blocking mode, this function return after operation completes or error happens.
\param[in] handle spi handle to operate.
\param[out] data Pointer to buffer for data to receive from SPI receiver
\param[in] num Number of data items to receive
\param[in] block_mode blocking and non_blocking to selcect
\return error code
*/
int32_t csi_spi_receive(spi_handle_t handle, void *data, uint32_t num, uint8_t block_mode);
/**
\brief sending/receiving data to/from SPI transmitter/receiver.
if non-blocking mode, this function only start the transfer,
\ref spi_event_e is signaled when operation completes or error happens.
\ref csi_spi_get_status can indicates operation status.
if blocking mode, this function return after operation completes or error happens.
\param[in] handle spi handle to operate.
\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_out Number of data items to send
\param[in] num_in Number of data items to receive
\param[in] block_mode blocking and non_blocking to selcect
\return error code
*/
int32_t csi_spi_transfer(spi_handle_t handle, const void *data_out, void *data_in, uint32_t num_out, uint32_t num_in, uint8_t block_mode);
/**
\brief abort spi transfer.
\param[in] handle spi handle to operate.
\return error code
*/
int32_t csi_spi_abort_transfer(spi_handle_t handle);
/**
\brief Get SPI status.
\param[in] handle spi handle to operate.
\return SPI status \ref spi_status_t
*/
spi_status_t csi_spi_get_status(spi_handle_t handle);
/**
\brief config the SPI mode.
\param[in] handle spi handle
\param[in] mode spi mode. \ref spi_mode_e
\return error code
*/
int32_t csi_spi_config_mode(spi_handle_t handle, spi_mode_e mode);
/**
\brief Set the SPI clock divider.
\param[in] handle spi handle
\param[in] baud spi baud rate
\param[in] apbfreq sysclk for spi module.
\return error code
*/
int32_t csi_spi_config_baudrate(spi_handle_t handle, int32_t baud, int32_t apbfreq);
/**
\brief config the SPI mode.
\param[in] handle spi handle
\param[in] order spi bit order.\ref spi_bit_order_e
\return error code
*/
int32_t csi_spi_config_bit_order(spi_handle_t handle, spi_bit_order_e order);
/**
\brief Set the SPI datawidth.
\param[in] handle spi handle
\param[in] datawidth date frame size in bits
\return error code
*/
int32_t csi_spi_config_datawidth(spi_handle_t handle, int32_t datawidth);
/**
\brief config the SPI format.
\param[in] handle spi handle
\param[in] format spi format. \ref spi_format_e
\return error code
*/
int32_t csi_spi_config_format(spi_handle_t handle, spi_format_e format);
/**
\brief config the SPI slave select mode.
\param[in] handle spi handle
\param[in] ss_mode spi slave select mode. \ref spi_ss_mode_e
\return error code
*/
int32_t csi_spi_config_ss_mode(spi_handle_t handle, spi_ss_mode_e ss_mode);
/**
\brief Get spi transferred data count.
\param[in] handle spi handle to operate.
\return number of data bytes transferred
*/
uint32_t csi_spi_get_data_count(spi_handle_t handle);
/**
\brief control spi power.
\param[in] handle spi handle to operate.
\param[in] state power state.\ref csi_power_stat_e.
\return error code
*/
int32_t csi_spi_power_control(spi_handle_t handle, csi_power_stat_e state);
/**
\brief Check if a value is available to read.
\param[in] handle spi handle to operate.
\return non-zero if a value is available
*/
int32_t csi_spi_slave_readable(spi_handle_t handle);
/**
\brief Control the Slave Select signal (SS).
\param[in] handle spi handle to operate.
\param[in] stat SS state. \ref spi_ss_stat_e.
\return error code
*/
int32_t csi_spi_ss_control(spi_handle_t handle, spi_ss_stat_e stat);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_SPI_H_ */

View file

@ -0,0 +1,640 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_tee.h
* @brief Header File for TEE
* @version V1.0
* @date 12 Sep 2017
******************************************************************************/
#ifndef _CSI_AES_H_
#define _CSI_AES_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/****** TEE AES mode *****/
typedef enum {
TEE_AES_MODE_ECB = 0, ///< TEE AES ECB mode
TEE_AES_MODE_CBC = 1, ///< TEE AES CBC mode
TEE_AES_MODE_MAX, ///< invaild mode
}
tee_aes_mode_e;
/**
\brief TEE AES encrypt
\note Length should be a multiple of the block size (16 bytes)
After calling this function, the content of iv is updated.
\param[in] in Pointer to plaintext buffer
\param[in] in_len Plaintext buffer length
\param[in] key Pointer to secret key
\param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256
\param[out] out Pointer to ciphertext buffer
\param[in] mode \ref tee_aes_mode_e
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_aes_encrypt(const uint8_t *in, uint32_t in_len,
const uint8_t *key, uint32_t key_len,
uint8_t iv[16],
uint8_t *out,
tee_aes_mode_e mode);
/**
\brief TEE AES decrypt
\note Length should be a multiple of the block size (16 bytes)
After calling this function, the content of iv is updated.
\param[in] in Pointer to ciphertext buffer
\param[in] in_len Ciphertext buffer length
\param[in] key Pointer to secret key
\param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256
\param[out] out Pointer to plaintext buffer
\param[in] mode \ref tee_aes_mode_e
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_aes_decrypt(const uint8_t *in, uint32_t in_len,
const uint8_t *key, uint32_t key_len,
uint8_t iv[16],
uint8_t *out,
uint32_t mode);
/**
\brief TEE AES ECB encrypt
\note Length should be a multiple of the block size (16 bytes)
After calling this function, the content of iv is updated.
\param[in] in Pointer to plaintext buffer
\param[in] in_len Plaintext buffer length
\param[in] key Pointer to secret key
\param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256
\param[out] out Pointer to ciphertext buffer
\return return 0 if successful,otherwise error code
*/
#define csi_tee_aes_encrypt_ecb(in, in_len, key, key_len, out) \
csi_tee_aes_encrypt(in, in_len, key, key_len, NULL, out, TEE_AES_MODE_ECB)
/**
\brief TEE AES ECB decrypt
\note Length should be a multiple of the block size (16 bytes)
After calling this function, the content of iv is updated.
\param[in] in Pointer to ciphertext buffer
\param[in] in_len Ciphertext buffer length
\param[in] key Pointer to secret key
\param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256
\param[out] out Pointer to plaintext buffer
\return return 0 if successful,otherwise error code
*/
#define csi_tee_aes_decrypt_ecb(in, in_len, key, key_len, out) \
csi_tee_aes_decrypt(in, in_len, key, key_len, NULL, out, TEE_AES_MODE_ECB)
/**
\brief TEE AES CBC encrypt
\note Length should be a multiple of the block size (16 bytes)
After calling this function, the content of iv is updated.
\param[in] in Pointer to ciphertext buffer
\param[in] in_len Ciphertext buffer length
\param[in] key Pointer to secret key
\param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256
\param[out] out Pointer to plaintext buffer
\return return 0 if successful,otherwise error code
*/
#define csi_tee_aes_encrypt_cbc(in, in_len, key, key_len, iv, out) \
csi_tee_aes_encrypt(in, in_len, key, key_len, iv, out, TEE_AES_MODE_CBC)
/**
\brief TEE AES CBC decrypt
\note Length should be a multiple of the block size (16 bytes)
After calling this function, the content of iv is updated.
\param[in] in Pointer to ciphertext buffer
\param[in] in_len Ciphertext buffer length
\param[in] key Pointer to secret key
\param[in] key_len Secret key size,must be 16 bytes for AES128,24 bytes for AES192 or 32byes for AES256
\param[out] out Pointer to plaintext buffer
\return return 0 if successful,otherwise error code
*/
#define csi_tee_aes_decrypt_cbc(in, in_len, key, key_len, iv, out) \
csi_tee_aes_decrypt(in, in_len, key, key_len, iv, out, TEE_AES_MODE_CBC)
/**
\brief TEE BASE64 encode/decode
\param[in] in Pointer to input data buffer
\param[in] in_len input data buffer length
\param[out] out Pointer to output data buffer
\param[out] out_len output data buffer length
\param[in] is_encode 1 encode 0 decode
\param[in] wsafe base64 websafe feature,set 1, replace "+/" with "-_"
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_base64(const uint8_t *in, uint32_t in_len,
uint8_t *out, uint32_t *out_len,
uint32_t is_encode,
uint32_t wsafe);
/**
\brief TEE BASE64 encode
\param[in] in Pointer to input data buffer
\param[in] in_len input data buffer length
\param[out] out Pointer to output data buffer
\param[out] out_len output data buffer length
\return return 0 if successful,otherwise error code
*/
#define csi_tee_base64_encode(in,in_len,out,out_len) \
csi_tee_base64(in,in_len,out,out_len,1,0)
/**
\brief TEE BASE64 decode
\param[in] in Pointer to input data buffer
\param[in] in_len input data buffer length
\param[out] out Pointer to output data buffer
\param[out] out_len output data buffer length
\return return 0 if successful,otherwise error code
*/
#define csi_tee_base64_decode(in,in_len,out,out_len) \
csi_tee_base64(in,in_len,out,out_len,0,0)
/**
\brief TEE BASE64 web safe encode
\param[in] in Pointer to input data buffer
\param[in] in_len input data buffer length
\param[out] out Pointer to output data buffer
\param[out] out_len output data buffer length
\return return 0 if successful,otherwise error code
*/
#define csi_tee_base64_websafe_encode(in,in_len,out,out_len) \
csi_tee_base64(in,in_len,out,out_len,1,1)
/**
\brief TEE BASE64 web safe decode
\param[in] in Pointer to input data buffer
\param[in] in_len input data buffer length
\param[out] out Pointer to output data buffer
\param[out] out_len output data buffer length
\return return 0 if successful,otherwise error code
*/
#define csi_tee_base64_websafe_decode(in,in_len,out,out_len) \
csi_tee_base64(in,in_len,out,out_len,0,1)
/**
\brief TEE obtain CID from Key Provisioning
\param[out] out Pointer to cid buffer
\param[out] out_len cid buffer length,if cid obtain successfully,
out_len is updated to actual cid sizes
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_get_cid(uint8_t *out, uint32_t *out_len);
/****** lpm mode *****/
typedef enum {
TEE_LPM_MODE_WAIT = 0, ///< lpm wait
TEE_LPM_MODE_DOZE = 1, ///< lpm doze
TEE_LPM_MODE_STOP = 2, ///< lpm stop
TEE_LPM_MODE_STANDBY = 3, ///< lpm standby
TEE_LPM_MODE_MAX,
} tee_lpm_mode_e;
/**
\brief TEE set low power mode
\param[in] gate not use for now
\param[in] irqid not use for now
\param[in] mode \ref tee_lpm_mode_e
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_enter_lpm(uint32_t gate, uint32_t irqid, tee_lpm_mode_e mode);
/**
\brief TEE obtain manifest info from manifest table
\note call csi_tee_get_sys_img_info, csi_tee_get_sys_os_version or csi_tee_get_sys_partition is better
\param[out] out Pointer to info buffer
\param[out] out_len Info buffer length,if info obtain successfully,
out_len is updated to actual sizes
\param[in] name info name
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_get_manifest_info(uint8_t *out, uint32_t *out_len, char *name);
/**
\brief TEE obtain image buffer from manifest table
\param[out] out Pointer to image buffer
\param[out] out_len Image buffer length,if info obtain successfully,
out_len is updated to actual image buffer sizes
\param[in] img_name image name
\return return 0 if successful,otherwise error code
*/
#define csi_tee_get_sys_img_info(out,out_len,img_name) \
csi_tee_get_manifest_info(out,out_len,img_name)
/**
\brief TEE obtain os version from manifest table
\param[out] out Pointer to os version buffer
\param[out] out_len OS version buffer length,if info obtain successfully,
out_len is updated to actual os version buffer sizes
\return return 0 if successful,otherwise error code
*/
#define csi_tee_get_sys_os_version(out,out_len) \
csi_tee_get_manifest_info(out,out_len,"os_v")
/**
\brief TEE obtain partition buffer from manifest table
\param[out] out Pointer to partition buffer
\param[out] out_len Partition buffer length,if info obtain successfully,
out_len is updated to actual partition buffer sizes
\return return 0 if successful,otherwise error code
*/
#define csi_tee_get_sys_partition(out,out_len) \
csi_tee_get_manifest_info(out,out_len,"sys_p")
/**
\brief TEE set random seed
\param[in] Seed random sedd
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_rand_seed(uint32_t seed);
/**
\brief TEE ramdom date generation
\param[out] out Pointer to random data buffer
\param[in] out_len Data buffer length
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_rand_generate(uint8_t *out, uint32_t out_len);
/****** TEE RSA sign type *****/
typedef enum {
TEE_RSA_MD5 = 0, ///< MD5
TEE_RSA_SHA1 = 1, ///< SHA1
TEE_RSA_SHA256 = 3, ///< SHA256
TEE_RSA_SIGN_TYPE_MAX, ///< invailed type
} tee_rsa_sign_type_e;
/**
\brief TEE RSA sign with private key
\param[in] in Pointer to digest buffer
\param[in] in_len Digest buffer length
\param[in] key Pointer to private key,key contains n, e, d
\param[in] key_len Private key size,must be 128*3 = 384 bytes for RSA1024, 256*3 = 768 bytes for RSA2048
\param[out] sign Pointer to sign buffer
\param[out] sign_len Sign buffer length
\param[in] type \ref tee_rsa_sign_type_e
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_rsa_sign(const uint8_t *in, uint32_t in_len,
const uint8_t *key, uint32_t key_len,
uint8_t *sign, uint32_t *sign_len,
tee_rsa_sign_type_e type);
/**
\brief TEE RSA verify with public key
\param[in] in Pointer to digest buffer
\param[in] in_len Digest buffer length
\param[in] key Pointer to public key,key contains n, e
\param[in] key_len Public key size,must be 128*2 = 256 bytes for RSA1024, 256*2 = 512 bytes for RSA2048
\param[in] sign Pointer to sign buffer
\param[in] sign_len Sign buffer length
\param[in] type \ref tee_rsa_sign_type_e
\return return 0 if verify successful,otherwise error code
*/
int32_t csi_tee_rsa_verify(const uint8_t *in, uint32_t in_len,
const uint8_t *key, uint32_t key_len,
uint8_t *sign, uint32_t sign_len,
tee_rsa_sign_type_e type);
/****** TEE RSA padding mode *****/
typedef enum {
TEE_RSA_PKCS1_PADDING = 0x01, ///< RSA PKCS padding mode
TEE_RSA_NO_PADDING = 0x02, ///< RSA no padding mode
} tee_rsa_padding_mode_e;
/**
\brief TEE RSA encrypt with public key
\param[in] in Pointer to plaintext buffer
\param[in] in_len Plaintext buffer length
\param[in] key Pointer to public key,key contains n, e
\param[in] key_len Public key size, must be 128*2 = 256 bytes for RSA1024, 256*2 = 512 bytes for RSA2048
\param[in] out Pointer to ciphertext buffer
\param[in] out_len Ciphertext buffer length
\param[in] padding \ref tee_rsa_padding_mode_e
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_rsa_encrypt(const uint8_t *in, uint32_t in_len,
const uint8_t *key, uint32_t key_len,
uint8_t *out, uint32_t *out_len,
tee_rsa_padding_mode_e padding);
/**
\brief TEE RSA decrypt with private key
\param[in] in Pointer to ciphertext buffer
\param[in] in_len Ciphertext buffer length
\param[in] key Pointer to private key,key contains n, e, d
\param[in] key_len Private key size,must be 128*3 = 384 bytes for RSA1024, 256*3 = 768 bytes for RSA2048
\param[in] out Pointer to plaintext buffer
\param[in] out_len Plaintext buffer length
\param[in] padding \ref tee_rsa_padding_mode_e
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_rsa_decrypt(const uint8_t *in, uint32_t in_len,
const uint8_t *key, uint32_t key_len,
uint8_t *out, uint32_t *out_len,
tee_rsa_padding_mode_e padding);
/**
\brief TEE RSA sign with internal private key
\note Only use if key provisioning exist
\param[in] in Pointer to digest buffer
\param[in] in_len Digest buffer length
\param[out] sign Pointer to sign buffer
\param[out] sign_len Sign buffer length
\param[in] type \ref tee_rsa_sign_type_e
\return return 0 if successful,otherwise error code
*/
#define csi_tee_cid_rsa_sign(in,in_len,sign,sign_len,type) \
csi_tee_rsa_sign(in,in_len,NULL,0,sign,sign_len,type)
/**
\brief TEE RSA verify with internal public key
\note Only use if key provisioning exist
\param[in] in Pointer to digest buffer
\param[in] in_len Digest buffer length
\param[in] sign Pointer to sign buffer
\param[in] sign_len Sign buffer length
\param[in] type \ref tee_rsa_sign_type_e
\return return 0 if verify successful,otherwise error code
*/
#define csi_tee_cid_rsa_verify(in,in_len,sign,sign_len,type) \
csi_tee_rsa_verify(in,in_len,NULL,0,sign,sign_len,type)
/**
\brief TEE RSA encrypt with internal public key
\note Only use if key provisioning exist
\param[in] in Pointer to plaintext buffer
\param[in] in_len Plaintext buffer length
\param[in] out Pointer to ciphertext buffer
\param[in] out_len Ciphertext buffer length
\param[in] padding \ref tee_rsa_padding_mode_e
\return return 0 if successful,otherwise error code
*/
#define csi_tee_cid_rsa_encrypt(in,in_len,out,out_len,padding) \
csi_tee_rsa_encrypt(in,in_len,NULL,0,out,out_len,padding)
/**
\brief TEE RSA decrypt with internal private key
\note Only use if key provisioning exist
\param[in] in Pointer to ciphertext buffer
\param[in] in_len Ciphertext buffer length
\param[in] key Pointer to private key,key contains n, e, d
\param[in] key_len Private key size,must be 128*3 = 384 bytes for RSA1024, 256*3 = 768 bytes for RSA2048
\param[in] out Pointer to plaintext buffer
\param[in] out_len Plaintext buffer length
\param[in] padding \ref tee_rsa_padding_mode_e
\return return 0 if successful,otherwise error code
*/
#define csi_tee_cid_rsa_decrypt(in,in_len,out,out_len,padding) \
csi_tee_rsa_decrypt(in,in_len,NULL,0,out,out_len,padding)
/**
\brief verify boot image with boot public key
\note Only use if key provisioning exist
\param[in] in Pointer to digest buffer
\param[in] in_len Digest buffer length
\param[in] sign Pointer to sign buffer
\param[in] sign_len Sign buffer length
\param[in] type \ref tee_rsa_sign_type_e
\return return 0 if verify successful,otherwise error code
*/
int32_t csi_tee_img_rsa_verify(const uint8_t *in, uint32_t in_len,
uint8_t *sign, uint32_t sign_len,
tee_rsa_sign_type_e type);
/****** TEE HASH operation mode *****/
typedef enum {
TEE_HASH_OP_NONE = 0, ///< No operation
TEE_HASH_OP_START = 1, ///< HASH init
TEE_HASH_OP_UPDATA = 2, ///< HASH update
TEE_HASH_OP_FINISH = 3, ///< HASH finish
TEE_HASH_OP_MAX, ///< invailed operation
} tee_hash_op_e;
/****** TEE HMAC type *****/
typedef enum {
TEE_HMAC_SHA1 = 1, ///< HMAC with SHA1
} tee_hmac_type_e;
/**
\brief TEE HAMC
\note Call csi_tee_hmac_digest is better
out buffer size must be large enough according to type, eg. 20 bytes for TEE_HMAC_SHA1
\param[in] in Pointer to input data buffer
\param[in] in_len Input data buffer length
\param[in] key Pointer to key buffer
\param[in] key_len Key buffer size
\param[out] out Pointer to output date buffer
\param[in] type \ref tee_hmac_type_e
\param[in] hash_op \ref tee_hash_op_e
\param[in] ctx Pointer to context of hmac
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_hmac(const uint8_t *in, uint32_t in_len,
const uint8_t *key, uint32_t key_len,
uint8_t *out,
tee_hmac_type_e type,
tee_hash_op_e hash_op,
uint32_t *ctx);
/**
\brief TEE HAMC digest
\note out buffer size must be large enough according to type, eg. 20 bytes for TEE_HMAC_SHA1
\param[in] in Pointer to input data buffer
\param[in] in_len Input data buffer length
\param[in] key Pointer to key buffer
\param[in] key_len Key buffer size
\param[out] out Pointer to output date buffer
\param[in] type \ref tee_hmac_type_e
\return return 0 if successful,otherwise error code
*/
#define csi_tee_hmac_digest(in,in_len,key,key_len,out,type) \
csi_tee_hmac(in,in_len,key,key_len,out,type,TEE_HASH_OP_NONE,NULL)
/****** TEE SHA type *****/
typedef enum {
TEE_SHA1 = 0, ///< SHA1
TEE_SHA256 = 1, ///< SHA256
TEE_SHA224 = 2, ///< SHA224
TEE_SHA384 = 3, ///< SHA384
TEE_SHA512 = 4, ///< SHA512
TEE_SHA_MAX, ///< invaild sha type
} tee_sha_type_t;
/**
\brief TEE SHA
\note Call csi_tee_sha_digest, csi_tee_sha_start, csi_tee_sha_update or csi_tee_sha_finish is better
out buffer size must be large enough according to type, eg. 20 bytes for TEE_SHA1, 32 bytes for TEE_SHA256
\param[in] in Pointer to input data buffer
\param[in] in_len Input data buffer length
\param[out] out Pointer to output date buffer
\param[in] type \ref tee_sha_type_t
\param[in] hash_op \ref tee_hash_op_e
\param[in] ctx Pointer to context of sha
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_sha(const uint8_t *in, uint32_t in_len,
uint8_t *out,
tee_sha_type_t type,
tee_hash_op_e hash_op,
void *ctx);
/**
\brief TEE SHA digest
\note out buffer size must be large enough according to type, eg. 20 bytes for TEE_SHA1, 32 bytes for TEE_SHA256
\param[in] in Pointer to input data buffer
\param[in] in_len Input data buffer length
\param[out] out Pointer to output date buffer
\param[in] type \ref tee_sha_type_t
\return return 0 if successful,otherwise error code
*/
#define csi_tee_sha_digest(in,in_len,out,type) \
csi_tee_sha(in,in_len,out,type,TEE_HASH_OP_NONE,NULL);
/**
\brief TEE SHA start, initial sha
\param[in] type \ref tee_sha_type_t
\param[in] ctx Pointer to context of sha
\return return 0 if successful,otherwise error code
*/
#define csi_tee_sha_start(type,ctx) \
csi_tee_sha(NULL,0,NULL,type,TEE_HASH_OP_START,ctx);
/**
\brief TEE SHA update, update data
\param[in] in Pointer to input data buffer
\param[in] in_len Input data buffer length
\param[in] ctx Pointer to context of sha
\return return 0 if successful,otherwise error code
*/
#define csi_tee_sha_update(in,in_len,ctx) \
csi_tee_sha(in,in_len,NULL,0,TEE_HASH_OP_UPDATA,ctx);
/**
\brief TEE SHA digest, get sha digest
\note out buffer size must be large enough according to type, eg. 20 bytes for TEE_SHA1, 32 bytes for TEE_SHA256
\param[out] out Pointer to output date buffer
\param[in] ctx Pointer to context of sha
\return return 0 if successful,otherwise error code
*/
#define csi_tee_sha_finish(out,ctx) \
csi_tee_sha(NULL,0,out,0,TEE_HASH_OP_FINISH,ctx);
/**
\brief TEE get device name and product key
\param[in] name_encrypted Pointer to device name ciphertext
\param[in] name_encrypted_len device name ciphertext length
\param[in] product_key_encrypted Pointer to device product key ciphertext
\param[in] product_key_encrypted_len Device product key ciphertext length
\param[out] name Pointer to device name
\param[out] name_len Device name length
\param[out] product_key Pointer to device product key
\param[out] product_key_len Device product key length
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_dev_info_get(const uint8_t *name_encrypted, uint32_t name_encrypted_len,
const uint8_t *product_key_encrypted, uint32_t product_key_encrypted_len,
const uint8_t *name, uint32_t *name_len,
const uint8_t *product_key, uint32_t *product_key_len);
/**
\brief TEE device info sign
\param[in] in Pointer to input date buffer
\param[in] in_len Input data buffer length
\param[in] device_secret Pointer to device secret ciphertext
\param[in] device_secret_len Device secret ciphertext length
\param[out] sign Pointer to signed buffer
\param[out] sign_len Signed buffer length
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_dev_info_sign(const uint8_t *in, uint32_t in_len,
const uint8_t *device_secret, uint32_t device_secret_len,
const uint8_t *sign, uint32_t *sign_len);
/**
\brief TEE device info encrypt/decrypt
\param[in] in Pointer to input date buffer
\param[in] in_len Input data buffer length
\param[in] out Pointer to output date buffer
\param[in] out_len Onput data buffer length
\param[in] is_enc 1 incrypt 0 decrypt
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_dev_info_crypt(const uint8_t *in, uint32_t in_len,
uint8_t *out, uint32_t *out_len,
uint8_t is_enc);
/**
\brief TEE device info encrypt
\param[in] in Pointer to input date buffer
\param[in] in_len Input data buffer length
\param[in] out Pointer to output date buffer
\param[in] out_len Onput data buffer length
\return return 0 if successful,otherwise error code
*/
#define csi_tee_dev_info_encrypt(in, in_len, out, out_len) \
csi_tee_dev_info_crypt(in, in_len, out, out_len, 1)
/**
\brief TEE device info decrypt
\param[in] in Pointer to input date buffer
\param[in] in_len Input data buffer length
\param[in] out Pointer to output date buffer
\param[in] out_len Onput data buffer length
\return return 0 if successful,otherwise error code
*/
#define csi_tee_dev_info_decrypt(in, in_len, out, out_len) \
csi_tee_dev_info_crypt(in, in_len, out, out_len, 0)
/****** system clock source type *****/
typedef enum {
IHS_CLK = 0, ///< internel clock source
EHS_CLK = 1 ///< externel clock source
} clk_src_e;
/****** system clock value scope *****/
typedef enum {
OSR_8M_CLK_16M = 0x80204, ///< register value for clock 16M
OSR_8M_CLK_24M = 0x80206, ///< register value for clock 24M
OSR_8M_CLK_32M = 0x80208, ///< register value for clock 32M
OSR_8M_CLK_40M = 0x8020a, ///< register value for clock 40M
OSR_8M_CLK_48M = 0x8020c ///< register value for clock 48M
} clk_val_e;
/**
\brief Set system frequence
\param[in] clk_src indicate clock source type
\param[in] clk_val system freqence to be set
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_set_sys_freq(uint32_t clk_src, uint32_t clk_val);
/**
\brief Get system frequence
\param[in] clk_val value address to store system freqence
\return return 0 if successful,otherwise error code
*/
int32_t csi_tee_get_sys_freq(uint32_t *clk_val);
int32_t csi_tee_xor(uint8_t *out, uint32_t *out_len);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_AES_H_ */

View file

@ -0,0 +1,168 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_timer.h
* @brief header file for timer driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_TIMER_H_
#define _CSI_TIMER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for timer handle.
typedef void *timer_handle_t;
/*----- TIMER Control Codes: Mode -----*/
typedef enum {
TIMER_MODE_FREE_RUNNING = 0, ///< free running mode
TIMER_MODE_RELOAD ///< reload mode
} timer_mode_e;
/**
\brief TIMER Status
*/
typedef struct {
uint32_t active : 1; ///< timer active flag
uint32_t timeout : 1; ///< timeout flag
} timer_status_t;
/**
\brief TIMER Event
*/
typedef enum {
TIMER_EVENT_TIMEOUT = 0 ///< time out event
} timer_event_e;
typedef void (*timer_event_cb_t)(timer_event_e event, void *arg); ///< Pointer to \ref timer_event_cb_t : TIMER Event call back.
/**
\brief TIMER Device Driver Capabilities.
*/
typedef struct {
uint32_t interrupt_mode : 1; ///< supports Interrupt mode
} timer_capabilities_t;
/**
\brief get timer instance count.
\return timer instance count
*/
int32_t csi_timer_get_instance_count(void);
/**
\brief Initialize TIMER Interface. 1. Initializes the resources needed for the TIMER interface 2.registers event callback function
\param[in] idx instance timer index
\param[in] cb_event Pointer to \ref timer_event_cb_t
\param[in] cb_arg arguments of cb_event
\return pointer to timer instance
*/
timer_handle_t csi_timer_initialize(int32_t idx, timer_event_cb_t cb_event, void *cb_arg);
/**
\brief De-initialize TIMER Interface. stops operation and releases the software resources used by the interface
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_uninitialize(timer_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle timer handle to operate.
\return \ref timer_capabilities_t
*/
timer_capabilities_t csi_timer_get_capabilities(timer_handle_t handle);
/**
\brief config timer mode.
\param[in] handle timer handle to operate.
\param[in] mode \ref timer_mode_e
\return error code
*/
int32_t csi_timer_config(timer_handle_t handle, timer_mode_e mode);
/**
\brief Set timer.
\param[in] handle timer handle to operate.
\param[in] timeout the timeout value in microseconds(us).
\return error code
*/
int32_t csi_timer_set_timeout(timer_handle_t handle, uint32_t timeout);
/**
\brief Start timer.
\param[in] handle timer handle to operate.
\param[in] apbfreq APB frequency
\return error code
*/
int32_t csi_timer_start(timer_handle_t handle, uint32_t apbfreq);
/**
\brief Stop timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_stop(timer_handle_t handle);
/**
\brief suspend timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_suspend(timer_handle_t handle);
/**
\brief resume timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_resume(timer_handle_t handle);
/**
\brief get timer current value
\param[in] handle timer handle to operate.
\param[in] value timer current value
\return error code
*/
int32_t csi_timer_get_current_value(timer_handle_t handle, uint32_t *value);
/**
\brief Get TIMER status.
\param[in] handle timer handle to operate.
\return TIMER status \ref timer_status_t
*/
timer_status_t csi_timer_get_status(timer_handle_t handle);
/**
\brief get timer reload value
\param[in] handle timer handle to operate.
\param[in] value timer reload value
\return error code
*/
int32_t csi_timer_get_load_value(timer_handle_t handle, uint32_t *value);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_TIMER_H_ */

View file

@ -0,0 +1,118 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_trng.h
* @brief header file for trng driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_TRNG_H_
#define _CSI_TRNG_H_
#include "drv_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/// definition for trng handle.
typedef void *trng_handle_t;
/****** TRNG specific error codes *****/
typedef enum {
TRNG_ERROR_MODE = 0, ///< Specified Mode not supported
} drv_trng_error_e;
/*----- TRNG Control Codes: Mode -----*/
typedef enum {
TRNG_MODE_LOWPOWER = 0, ///< TRNG Low power Mode
TRNG_MODE_NORMAL ///< TRNG Normal Mode
} trng_mode_e;
/**
\brief TRNG Status
*/
typedef struct {
uint32_t busy : 1;
uint32_t data_valid : 1; ///< Data is valid flag
} trng_status_t;
/****** TRNG Event *****/
typedef enum {
TRNG_EVENT_DATA_GENERATE_COMPLETE = 0 ///< Get data from TRNG success
} trng_event_e;
typedef void (*trng_event_cb_t)(trng_event_e event); ///< Pointer to \ref trng_event_cb_t : TRNG Event call back.
/**
\brief TRNG Device Driver Capabilities.
*/
typedef struct {
uint32_t lowper_mode : 1; ///< supports low power mode
} trng_capabilities_t;
// Function documentation
/**
\brief get trng handle count.
\return trng handle count
*/
int32_t csi_trng_get_instance_count(void);
/**
\brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_trng_get_instance_count()
\param[in] cb_event Pointer to \ref trng_event_cb_t
\return pointer to trng handle
*/
trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event);
/**
\brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface
\param[in] handle trng handle to operate.
\return error code
*/
int32_t csi_trng_uninitialize(trng_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle trng handle to operate.
\return \ref trng_capabilities_t
*/
trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle);
/**
\brief Get data from the TRNG.
\param[in] handle trng handle to operate.
\param[out] data Pointer to buffer with data get from TRNG
\param[in] num Number of data items to obtain
\return error code
*/
int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num);
/**
\brief Get TRNG status.
\param[in] handle trng handle to operate.
\return TRNG status \ref trng_status_t
*/
trng_status_t csi_trng_get_status(trng_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_TRNG_H_ */

View file

@ -0,0 +1,495 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_usart.h
* @brief header file for usart driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_USART_H_
#define _CSI_USART_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <drv_common.h>
/// definition for usart handle.
typedef void *usart_handle_t;
/****** USART specific error codes *****/
typedef enum {
EDRV_USART_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
EDRV_USART_BAUDRATE, ///< Specified baudrate not supported
EDRV_USART_DATA_BITS, ///< Specified number of Data bits not supported
EDRV_USART_PARITY, ///< Specified Parity not supported
EDRV_USART_STOP_BITS, ///< Specified number of Stop bits not supported
EDRV_USART_FLOW_CONTROL, ///< Specified Flow Control not supported
EDRV_USART_CPOL, ///< Specified Clock Polarity not supported
EDRV_USART_CPHA ///< Specified Clock Phase not supported
} drv_usart_error_e;
/*----- USART Control Codes: Mode -----*/
typedef enum {
USART_MODE_ASYNCHRONOUS = 0, ///< USART (Asynchronous)
USART_MODE_SYNCHRONOUS_MASTER , ///< Synchronous Master
USART_MODE_SYNCHRONOUS_SLAVE , ///< Synchronous Slave (external clock signal)
USART_MODE_SINGLE_WIRE , ///< USART Single-wire (half-duplex)
USART_MODE_SINGLE_IRDA , ///< UART IrDA
USART_MODE_SINGLE_SMART_CARD , ///< UART Smart Card
} usart_mode_e;
/*----- USART Control Codes: Mode Parameters: Data Bits -----*/
typedef enum {
USART_DATA_BITS_5 = 0, ///< 5 Data bits
USART_DATA_BITS_6 , ///< 6 Data bit
USART_DATA_BITS_7 , ///< 7 Data bits
USART_DATA_BITS_8 , ///< 8 Data bits (default)
USART_DATA_BITS_9 ///< 9 Data bits
} usart_data_bits_e;
/*----- USART Control Codes: Mode Parameters: Parity -----*/
typedef enum {
USART_PARITY_NONE = 0, ///< No Parity (default)
USART_PARITY_EVEN , ///< Even Parity
USART_PARITY_ODD , ///< Odd Parity
USART_PARITY_1 , ///< Parity forced to 1
USART_PARITY_0 ///< Parity forced to 0
} usart_parity_e;
/*----- USART Control Codes: Mode Parameters: Stop Bits -----*/
typedef enum {
USART_STOP_BITS_1 = 0, ///< 1 Stop bit (default)
USART_STOP_BITS_2 , ///< 2 Stop bits
USART_STOP_BITS_1_5 , ///< 1.5 Stop bits
USART_STOP_BITS_0_5 ///< 0.5 Stop bits
} usart_stop_bits_e;
/*----- USART Control Codes: Mode Parameters: Clock Polarity (Synchronous mode) -----*/
typedef enum {
USART_CPOL0 = 0, ///< CPOL = 0 (default). data are captured on rising edge (low->high transition)
USART_CPOL1 ///< CPOL = 1. data are captured on falling edge (high->lowh transition)
} usart_cpol_e;
/*----- USART Control Codes: Mode Parameters: Clock Phase (Synchronous mode) -----*/
typedef enum {
USART_CPHA0 = 0, ///< CPHA = 0 (default). sample on first (leading) edge
USART_CPHA1 ///< CPHA = 1. sample on second (trailing) edge
} usart_cpha_e;
/*----- USART Control Codes: flush data type-----*/
typedef enum {
USART_FLUSH_WRITE,
USART_FLUSH_READ
} usart_flush_type_e;
/*----- USART Control Codes: flow control type-----*/
typedef enum {
USART_FLOWCTRL_NONE,
USART_FLOWCTRL_CTS,
USART_FLOWCTRL_RTS,
USART_FLOWCTRL_CTS_RTS
} usart_flowctrl_type_e;
/*----- USART Modem Control -----*/
typedef enum {
USART_RTS_CLEAR, ///< Deactivate RTS
USART_RTS_SET, ///< Activate RTS
USART_DTR_CLEAR, ///< Deactivate DTR
USART_DTR_SET ///< Activate DTR
} usart_modem_ctrl_e;
/*----- USART Modem Status -----*/
typedef struct {
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
} usart_modem_stat_t;
/*----- USART Control Codes: on-off intrrupte type-----*/
typedef enum {
USART_INTR_WRITE,
USART_INTR_READ
} usart_intr_type_e;
/**
\brief USART Status
*/
typedef struct {
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)(Synchronous Slave)
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)
} usart_status_t;
/****** USART Event *****/
typedef enum {
USART_EVENT_SEND_COMPLETE = 0, ///< Send completed; however USART may still transmit data
USART_EVENT_RECEIVE_COMPLETE = 1, ///< Receive completed
USART_EVENT_TRANSFER_COMPLETE = 2, ///< Transfer completed
USART_EVENT_TX_COMPLETE = 3, ///< Transmit completed (optional)
USART_EVENT_TX_UNDERFLOW = 4, ///< Transmit data not available (Synchronous Slave)
USART_EVENT_RX_OVERFLOW = 5, ///< Receive data overflow
USART_EVENT_RX_TIMEOUT = 6, ///< Receive character timeout (optional)
USART_EVENT_RX_BREAK = 7, ///< Break detected on receive
USART_EVENT_RX_FRAMING_ERROR = 8, ///< Framing error detected on receive
USART_EVENT_RX_PARITY_ERROR = 9, ///< Parity error detected on receive
USART_EVENT_CTS = 10, ///< CTS state changed (optional)
USART_EVENT_DSR = 11, ///< DSR state changed (optional)
USART_EVENT_DCD = 12, ///< DCD state changed (optional)
USART_EVENT_RI = 13, ///< RI state changed (optional)
USART_EVENT_RECEIVED = 14, ///< Received data, but no send()/receive()/transfer() called
} usart_event_e;
typedef void (*usart_event_cb_t)(usart_event_e event, void *cb_arg); ///< Pointer to \ref usart_event_cb_t : USART Event call back.
/**
\brief USART Driver Capabilities.
*/
typedef struct {
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
} usart_capabilities_t;
/**
\brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
\param[in] tx usart pin of tx
\param[in] rx usart pin of rx
\param[in] cb_event Pointer to \ref usart_event_cb_t
\param[in] cb_arg argument for cb_event
\return return usart handle if success
*/
usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg);
/**
\brief De-initialize USART Interface. stops operation and releases the software resources used by the interface
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_uninitialize(usart_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle usart handle to operate.
\return \ref usart_capabilities_t
*/
usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle);
/**
\brief config usart mode.
\param[in] handle usart handle to operate.
\param[in] sysclk system clock.
\param[in] baud baud rate.
\param[in] mode \ref usart_mode_e .
\param[in] parity \ref usart_parity_e .
\param[in] stopbits \ref usart_stop_bits_e .
\param[in] bits \ref usart_data_bits_e .
\return error code
*/
int32_t csi_usart_config(usart_handle_t handle,
uint32_t sysclk,
uint32_t baud,
usart_mode_e mode,
usart_parity_e parity,
usart_stop_bits_e stopbits,
usart_data_bits_e bits);
/**
\brief config usart default tx value. used in synchronous mode
\param[in] handle usart handle to operate.
\param[in] value default tx value
\return error code
*/
int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value);
/**
\brief Start sending data to USART transmitter,(received data is ignored).
This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens.
\ref csi_usart_get_status can indicates operation status.
\param[in] handle usart handle to operate.
\param[in] data Pointer to buffer with data to send to USART transmitter. data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[in] num Number of data items to send
\return error code
*/
int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num/*,bool asynch*/);
/**
\brief Abort Send data to USART transmitter
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_send(usart_handle_t handle);
/**
\brief Start receiving data from USART receiver.transmits the default value as specified by csi_usart_set_default_tx_value. \n
This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens.
\ref csi_usart_get_status can indicates operation status.
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from USART receiver.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[in] num Number of data items to receive
\return error code
*/
int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num/*,bool asynch*/);
/**
\brief query data from UART receiver FIFO.
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from UART receiver
\param[in] num Number of data items to receive
\return receive fifo data num
*/
int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num/*,bool asynch*/);
/**
\brief Abort Receive data from USART receiver
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_receive(usart_handle_t handle);
/**
\brief Start synchronously sends data to the USART transmitter and receives data from the USART receiver. used in synchronous mode
This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens.
\ref csi_usart_get_status can indicates operation status.
\param[in] handle usart handle to operate.
\param[in] data_out Pointer to buffer with data to send to USART transmitter.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[out] data_in Pointer to buffer for data to receive from USART receiver.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[in] num Number of data items to transfer
\return error code
*/
int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num/*,bool asynch*/);
/**
\brief abort sending/receiving data to/from USART transmitter/receiver.
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_transfer(usart_handle_t handle);
/**
\brief Get USART status.
\param[in] handle usart handle to operate.
\return USART status \ref usart_status_t
*/
usart_status_t csi_usart_get_status(usart_handle_t handle);
/**
\brief flush receive/send data.
\param[in] handle usart handle to operate.
\param[in] type \ref usart_flush_type_e .
\return \ref execution_status
*/
int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type);
/**
\brief control interrupt on/off.
\param[in] handle usart handle to operate.
\param[in] type \ref usart_intr_type_e.
\param[in] flag 0-OFF, 1-ON.
\return error code
*/
int32_t csi_usart_interrupt_on_off(usart_handle_t handle, usart_intr_type_e type, int flag);
/**
\brief set the baut drate of usart.
\param[in] addr usart base to operate.
\param[in] baudrate baud rate
\param[in] apbfreq the frequency of the apb.
\return error code
*/
int32_t csi_usart_config_baudrate(usart_handle_t handle, uint32_t baudrate, uint32_t apbfreq);
/**
\brief config usart mode.
\param[in] handle usart handle to operate.
\param[in] mode \ref usart_mode_e
\return error code
*/
int32_t csi_usart_config_mode(usart_handle_t handle, usart_mode_e mode);
/**
\brief config usart parity.
\param[in] handle usart handle to operate.
\param[in] parity \ref usart_parity_e
\return error code
*/
int32_t csi_usart_config_parity(usart_handle_t handle, usart_parity_e parity);
/**
\brief config usart stop bit number.
\param[in] handle usart handle to operate.
\param[in] stopbits \ref usart_stop_bits_e
\return error code
*/
int32_t dw_usart_config_stopbits(usart_handle_t handle, usart_stop_bits_e stopbit);
/**
\brief config usart data length.
\param[in] handle usart handle to operate.
\param[in] databits \ref usart_data_bits_e
\return error code
*/
int32_t csi_usart_config_databits(usart_handle_t handle, usart_data_bits_e databits);
/**
\brief get character in query mode.
\param[in] handle usart handle to operate.
\param[in] the pointer to the received character if return 0.
\return error code
*/
int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch);
/**
\brief transmit character in query mode.
\param[in] handle usart handle to operate.
\param[in] ch the input character
\return error code
*/
int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch);
/**
\brief Get usart send data count.
\param[in] handle usart handle to operate.
\return number of data bytes transferred
*/
uint32_t csi_usart_get_tx_count(usart_handle_t handle);
/**
\brief Get usart receive data count.
\param[in] handle usart handle to operate.
\return number of data bytes transferred
*/
uint32_t csi_usart_get_rx_count(usart_handle_t handle);
/**
\brief control usart power.
\param[in] handle usart handle to operate.
\param[in] state power state.\ref csi_power_stat_e.
\return error code
*/
int32_t csi_usart_power_control(usart_handle_t handle, csi_power_stat_e state);
/**
\brief config usart flow control type.
\param[in] handle usart handle to operate.
\param[in] flowctrl_type flow control type.\ref usart_flowctrl_type_e.
\param[in] tx_flow The TX flow pin name
\param[in] rx_flow The RX flow pin name
\return error code
*/
int32_t csi_usart_config_flowctrl(usart_handle_t handle,
usart_flowctrl_type_e flowctrl_type,
pin_t tx_flow, pin_t rx_flow);
/**
\brief usart modem control.
\param[in] handle usart handle to operate.
\param[in] modem_ctrl modem control action.\ref usart_modem_ctrl_e.
\return error code
*/
int32_t csi_usart_modem_ctrl(usart_handle_t handle, usart_modem_ctrl_e modem_ctrl);
/**
\brief get usart modem status.
\param[in] handle usart handle to operate.
\param[in] modem_ctrl modem control action.\ref usart_modem_ctrl_e.
\return modem status.\ref usart_modem_stat_t.
*/
usart_modem_stat_t csi_usart_get_modem_stat(usart_handle_t handle);
/**
\brief config usart clock Polarity and Phase.
\param[in] handle usart handle to operate.
\param[in] cpol Clock Polarity.\ref usart_cpol_e.
\param[in] cpha Clock Phase.\ref usart_cpha_e.
\return error code
*/
int32_t csi_usart_config_clock(usart_handle_t handle, usart_cpol_e cpol, usart_cpha_e cpha);
/**
\brief config usart guard time.
\param[in] handle usart handle to operate.
\param[in] num_of_bits guard time in number of bit periods.
\return error code
*/
int32_t csi_usart_config_guard_time(usart_handle_t handle, uint32_t num_of_bits);
/**
\brief check if usart is readable(data received).
\param[in] handle usart handle to operate.
\return 1 - a character can be read, 0 if nothing to read ,negative for error code
*/
int32_t csi_usart_readable(usart_handle_t handle);
/**
\brief check if usart is writable(free for data sending).
\param[in] handle usart handle to operate.
\return 1 - a character can be written, 0 - cannot be written ,negative for error code
*/
int32_t csi_usart_writable(usart_handle_t handle);
/**
\brief control the transmit.
\param[in] handle usart handle to operate.
\param[in] 1 - enable the transmitter. 0 - disable the transmitter
\return error code
*/
int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable);
/**
\brief control the receive.
\param[in] handle usart handle to operate.
\param[in] 1 - enable the receiver. 0 - disable the receiver
\return error code
*/
int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable);
/**
\brief control the break.
\param[in] handle usart handle to operate.
\param[in] 1- Enable continuous Break transmission,0 - disable continuous Break transmission
\return error code
*/
int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_USART_H_ */

View file

@ -0,0 +1,119 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_wdt.h
* @brief header file for wdt driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_WDT_H_
#define _CSI_WDT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for wdt handle.
typedef void *wdt_handle_t;
/****** WDT Event *****/
typedef enum {
WDT_EVENT_TIMEOUT = 0 ///< generate the interrupt
} wdt_event_e;
typedef void (*wdt_event_cb_t)(wdt_event_e event); ///< Pointer to \ref wdt_event_cb_t : WDT Event call back.
/**
\brief WDT Device Driver Capabilities.
*/
typedef struct {
uint32_t interrupt : 1; ///< supports interrupt
} wdt_capabilities_t;
/**
\brief get wdt instance count.
\return wdt instance count
*/
int32_t csi_wdt_get_instance_count(void);
/**
\brief Initialize WDT Interface. 1. Initializes the resources needed for the WDT interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_wdt_get_instance_count()
\param[in] cb_event Pointer to \ref wdt_event_cb_t
\return pointer to wdt instance
*/
wdt_handle_t csi_wdt_initialize(int32_t idx, wdt_event_cb_t cb_event);
/**
\brief De-initialize WDT Interface. stops operation and releases the software resources used by the interface
\param[in] handle wdt handle to operate.
\return error code
*/
int32_t csi_wdt_uninitialize(wdt_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle wdt handle to operate.
\return \ref wdt_capabilities_t
*/
wdt_capabilities_t csi_wdt_get_capabilities(wdt_handle_t handle);
/**
\brief Set the WDT value.
\param[in] handle wdt handle to operate.
\param[in] value the timeout value(ms).
\return error code
*/
int32_t csi_wdt_set_timeout(wdt_handle_t handle, uint32_t value);
/**
\brief Start the WDT.
\param[in] handle wdt handle to operate.
\return error code
*/
int32_t csi_wdt_start(wdt_handle_t handle);
/**
\brief Stop the WDT.
\param[in] handle wdt handle to operate.
\return error code
*/
int32_t csi_wdt_stop(wdt_handle_t handle);
/**
\brief Restart the WDT.
\param[in] handle wdt handle to operate.
\return error code
*/
int32_t csi_wdt_restart(wdt_handle_t handle);
/**
\brief Read the WDT Current value.
\param[in] handle wdt handle to operate.
\param[in] value Pointer to the Value.
\return error code
*/
int32_t csi_wdt_read_current_value(wdt_handle_t handle, uint32_t *value);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_WDT_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,101 @@
/**
* Copyright (C) 2016 CSI Project. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CSI_WIFI_WPS_H__
#define __CSI_WIFI_WPS_H__
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup WiFi_APIs WiFi Related APIs
* @brief WiFi APIs
*/
/** @addtogroup WiFi_APIs
* @{
*/
/** \defgroup WPS_APIs WPS APIs
* @brief WPS APIs
*
* WPS can only be used when station is enabled.
*
*/
/** @addtogroup WPS_APIs
* @{
*/
#define CSI_ERR_WIFI_REGISTRAR (CSI_DRV_ERRNO_WIFI_BASE + 51) /*!< WPS registrar is not supported */
#define CSI_ERR_WIFI_WPS_TYPE (CSI_DRV_ERRNO_WIFI_BASE + 52) /*!< WPS type error */
#define CSI_ERR_WIFI_WPS_SM (CSI_DRV_ERRNO_WIFI_BASE + 53) /*!< WPS state machine is not initialized */
typedef enum wps_type {
WPS_TYPE_DISABLE = 0,
WPS_TYPE_PBC,
WPS_TYPE_PIN,
WPS_TYPE_MAX,
} wps_type_t;
/**
* @brief Enable Wi-Fi WPS function.
*
* @attention WPS can only be used when station is enabled.
*
* @param wps_type : WPS type, so far only WPS_TYPE_PBC and WPS_TYPE_PIN is supported
*
* @return
* - CSI_OK : succeed
* - CSI_ERR_WIFI_WPS_TYPE : wps type is invalid
* - CSI_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on
* - CSI_ERR_WIFI_FAIL : wps initialization fails
*/
int32_t csi_wifi_wps_enable(wps_type_t wps_type);
/**
* @brief Disable Wi-Fi WPS function and release resource it taken.
*
* @return
* - CSI_OK : succeed
* - CSI_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on
*/
int32_t csi_wifi_wps_disable(void);
/**
* @brief WPS starts to work.
*
* @attention WPS can only be used when station is enabled.
*
* @param timeout_ms : maximum blocking time before API return.
* - 0 : non-blocking
* - 1~120000 : blocking time
*
* @return
* - CSI_OK : succeed
* - CSI_ERR_WIFI_WPS_TYPE : wps type is invalid
* - CSI_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on
* - CSI_ERR_WIFI_WPS_SM : wps state machine is not initialized
* - CSI_ERR_WIFI_FAIL : wps initialization fails
*/
int32_t csi_wifi_wps_start(int timeout_ms);
#ifdef __cplusplus
}
#endif
#endif /* __CSI_WIFI_H__ */

View file

@ -0,0 +1,33 @@
#include <stdint.h>
#include <soc.h>
#include <csi_core.h>
extern void CORET_IRQHandler(void);
extern void Default_handler(void);
extern void console_init();
void (*g_irqvector[32])(void);
void irq_vectors_init(void)
{
int i;
for (i = 0; i < 32; i++) {
g_irqvector[i] = Default_handler;
}
g_irqvector[CORET_IRQn] = CORET_IRQHandler;
}
#define CONFIG_SYSTICK_HZ 100
#define CONFIG_SYSTEM_FREQ 24000000
void SystemInit(void)
{
irq_vectors_init();
drv_coret_config(CONFIG_SYSTEM_FREQ / CONFIG_SYSTICK_HZ, CORET_IRQn); //10ms
drv_nvic_enable_irq(CORET_IRQn);
console_init();
return;
}