first submission
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : buf.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2022/06/30
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "ch32v20x.h"
|
||||
#include "buf.h"
|
||||
|
||||
#ifdef CONFIG_SIMPLE_BUF_DBG
|
||||
#define SIMPLE_BUF_DBG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define SIMPLE_BUF_DBG(...)
|
||||
#endif
|
||||
struct simple_buf *simple_buf_create(struct simple_buf *buf,
|
||||
uint8_t *buf_pool, uint16_t pool_size)
|
||||
{
|
||||
buf->data = buf_pool;
|
||||
buf->len = 0;
|
||||
buf->size = pool_size;
|
||||
buf->__buf = buf_pool;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void *simple_buf_add(struct simple_buf *buf, size_t len)
|
||||
{
|
||||
uint8_t *tail = buf->data + buf->len;
|
||||
|
||||
SIMPLE_BUF_DBG("buf %p add len %ld\n", buf, len);
|
||||
|
||||
if((buf->size - (buf->data - buf->__buf) - buf->len) < len) {
|
||||
SIMPLE_BUF_DBG("simple_buf_add: no memory\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
buf->len += len;
|
||||
|
||||
return tail;
|
||||
}
|
||||
|
||||
void *simple_buf_pull(struct simple_buf *buf, size_t len)
|
||||
{
|
||||
void *data = buf->data;
|
||||
|
||||
SIMPLE_BUF_DBG("buf %p pull len %ld\n", buf, len);
|
||||
|
||||
if(buf->len < len) {
|
||||
SIMPLE_BUF_DBG("simple_buf_pull: no data\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
buf->len -= len;
|
||||
buf->data += len;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void *simple_buf_add_mem(struct simple_buf *buf, const void *mem,
|
||||
size_t len)
|
||||
{
|
||||
SIMPLE_BUF_DBG("buf %p add len %ld\n", buf, len);
|
||||
|
||||
return memcpy(simple_buf_add(buf, len), mem, len);
|
||||
}
|
||||
|
||||
uint8_t *simple_buf_add_u8(struct simple_buf *buf, uint8_t val)
|
||||
{
|
||||
uint8_t *u8;
|
||||
|
||||
SIMPLE_BUF_DBG("buf %p add val 0x%02x\n", buf, val);
|
||||
|
||||
u8 = simple_buf_add(buf, 1);
|
||||
*u8 = val;
|
||||
|
||||
return u8;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* Description : Main Interrupt Service Routines.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "ch32v20x_it.h"
|
||||
#include "CONFIG.h"
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void BB_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void LLE_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NMI_Handler
|
||||
*
|
||||
* @brief This function handles NMI exception.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HardFault_Handler
|
||||
*
|
||||
* @brief This function handles Hard Fault exception.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn BB_IRQHandler
|
||||
*
|
||||
* @brief BB Interrupt for BLE.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void BB_IRQHandler(void)
|
||||
{
|
||||
BB_IRQLibHandler();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn LLE_IRQHandler
|
||||
*
|
||||
* @brief LLE Interrupt for BLE.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void LLE_IRQHandler(void)
|
||||
{
|
||||
LLE_IRQLibHandler();
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : hci_test.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2022/06/30
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "hci_test.h"
|
||||
#include "config.h"
|
||||
|
||||
static uint16_t _opcode;
|
||||
static uint8_t hci_pool[100];
|
||||
static struct simple_buf hci_buffer;
|
||||
|
||||
struct simple_buf *bt_hci_cmd_complete_create(uint16_t op, uint8_t plen)
|
||||
{
|
||||
struct simple_buf *buf;
|
||||
struct bt_hci_evt_cmd_complete *cc;
|
||||
struct bt_hci_evt_hdr *hdr;
|
||||
struct bt_hci_pkt_type *pt;
|
||||
|
||||
buf = simple_buf_create(&hci_buffer, hci_pool, sizeof(hci_pool));
|
||||
|
||||
pt = simple_buf_add(buf, sizeof(*pt));
|
||||
pt->type = BT_HCI_PKT_TYPE_EVT;
|
||||
|
||||
hdr = simple_buf_add(buf, sizeof(*hdr));
|
||||
hdr->evt = BT_HCI_EVT_CMD_COMPLETE;
|
||||
hdr->len = sizeof(*cc) + plen;
|
||||
|
||||
cc = simple_buf_add(buf, sizeof(*cc));
|
||||
cc->ncmd = 1U;
|
||||
cc->opcode = op;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void *hci_cmd_complete(struct simple_buf **buf, uint8_t plen)
|
||||
{
|
||||
*buf = bt_hci_cmd_complete_create(_opcode, plen);
|
||||
|
||||
return simple_buf_add(*buf, plen);
|
||||
}
|
||||
|
||||
struct simple_buf *cmd_complete_status(uint8_t status)
|
||||
{
|
||||
struct simple_buf *buf;
|
||||
struct bt_hci_evt_cc_status *ccst;
|
||||
|
||||
buf = bt_hci_cmd_complete_create(_opcode, sizeof(*ccst));
|
||||
ccst = simple_buf_add(buf, sizeof(*ccst));
|
||||
ccst->status = status;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void reset(struct simple_buf *buf, struct simple_buf **evt)
|
||||
{
|
||||
if (buf) {
|
||||
PRINT("%s:\n", __FUNCTION__);
|
||||
*evt = cmd_complete_status(0x00);
|
||||
}
|
||||
}
|
||||
|
||||
static void le_rx_test(struct simple_buf *buf, struct simple_buf **evt)
|
||||
{
|
||||
struct bt_hci_cp_le_rx_test *cmd = (void *)buf->data;
|
||||
uint8_t status;
|
||||
|
||||
PRINT("%s:\n", __FUNCTION__);
|
||||
PRINT(" rx channel: %#x\n", cmd->rx_ch);
|
||||
|
||||
status = API_LE_ReceiverTestCmd((uint8_t *)cmd, BT_HCI_OP_LE_RX_TEST);
|
||||
*evt = cmd_complete_status(status);
|
||||
}
|
||||
|
||||
/* Modulation_Index feature is not currently supported */
|
||||
static void le_rx_test_v2(struct simple_buf *buf, struct simple_buf **evt)
|
||||
{
|
||||
struct bt_hci_cp_le_rx_test_v2 *cmd = (void *)buf->data;
|
||||
uint8_t status;
|
||||
|
||||
PRINT("%s:\n", __FUNCTION__);
|
||||
PRINT(" rx channel: %#x\n", cmd->rx_ch);
|
||||
PRINT(" phy: ");
|
||||
switch(cmd->phy) {
|
||||
case BT_HCI_LE_RX_PHY_1M:
|
||||
PRINT("1M\n");
|
||||
break;
|
||||
case BT_HCI_LE_RX_PHY_2M:
|
||||
PRINT("2M\n");
|
||||
break;;
|
||||
case BT_HCI_LE_RX_PHY_CODED:
|
||||
PRINT("CODED\n");
|
||||
break;
|
||||
default:
|
||||
PRINT("Invalid\n");
|
||||
break;
|
||||
}
|
||||
PRINT(" mod_index: %#x\n", cmd->mod_index);
|
||||
|
||||
status = API_LE_ReceiverTestCmd((uint8_t *)cmd, BT_HCI_OP_LE_RX_TEST_V2);
|
||||
*evt = cmd_complete_status(status);
|
||||
}
|
||||
|
||||
static void le_tx_test(struct simple_buf *buf, struct simple_buf **evt)
|
||||
{
|
||||
struct bt_hci_cp_le_tx_test *cmd = (void *)buf->data;
|
||||
uint8_t status;
|
||||
|
||||
PRINT("%s:\n", __FUNCTION__);
|
||||
PRINT(" tx channel: %#x\n", cmd->tx_ch);
|
||||
PRINT(" test data len: %d\n", cmd->test_data_len);
|
||||
PRINT(" pkt payload: ");
|
||||
switch (cmd->pkt_payload) {
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_PRBS9:
|
||||
PRINT("PRBS9\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_11110000:
|
||||
PRINT("11110000\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_10101010:
|
||||
PRINT("10101010\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_PRBS15:
|
||||
PRINT("PRBS15\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_11111111:
|
||||
PRINT("11111111\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_00000000:
|
||||
PRINT("00000000\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_00001111:
|
||||
PRINT("00001111\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_01010101:
|
||||
PRINT("01010101\n");
|
||||
break;
|
||||
default:
|
||||
PRINT("Invalid\n");
|
||||
break;
|
||||
}
|
||||
|
||||
status =API_LE_TransmitterTestCmd((uint8_t *)cmd, BT_HCI_OP_LE_TX_TEST);
|
||||
*evt = cmd_complete_status(status);
|
||||
}
|
||||
|
||||
static void le_tx_test_v2(struct simple_buf *buf, struct simple_buf **evt)
|
||||
{
|
||||
struct bt_hci_cp_le_tx_test_v2 *cmd = (void *)buf->data;
|
||||
uint8_t status;
|
||||
|
||||
PRINT("%s:", __FUNCTION__);
|
||||
PRINT(" tx channel: %#x\n", cmd->tx_ch);
|
||||
PRINT(" test data len: %d\n", cmd->test_data_len);
|
||||
PRINT(" pkt payload: ");
|
||||
switch (cmd->pkt_payload) {
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_PRBS9:
|
||||
PRINT("PRBS9\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_11110000:
|
||||
PRINT("11110000\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_10101010:
|
||||
PRINT("10101010\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_PRBS15:
|
||||
PRINT("PRBS15\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_11111111:
|
||||
PRINT("11111111\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_00000000:
|
||||
PRINT("00000000\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_00001111:
|
||||
PRINT("00001111\n");
|
||||
break;
|
||||
case BT_HCI_TEST_PKT_PAYLOAD_01010101:
|
||||
PRINT("01010101\n");
|
||||
break;
|
||||
default:
|
||||
PRINT("Invalid\n");
|
||||
break;
|
||||
}
|
||||
|
||||
PRINT(" phy: ");
|
||||
switch(cmd->phy) {
|
||||
case BT_HCI_LE_TX_PHY_1M:
|
||||
PRINT("1M\n");
|
||||
break;
|
||||
case BT_HCI_LE_TX_PHY_2M:
|
||||
PRINT("2M\n");
|
||||
break;;
|
||||
case BT_HCI_LE_TX_PHY_CODED_S8:
|
||||
PRINT("CODED_S8\n");
|
||||
break;
|
||||
case BT_HCI_LE_TX_PHY_CODED_S2:
|
||||
PRINT("CODED_S2\n");
|
||||
break;
|
||||
default:
|
||||
PRINT("Invalid\n");
|
||||
break;
|
||||
}
|
||||
|
||||
status = API_LE_TransmitterTestCmd((uint8_t *)cmd, BT_HCI_OP_LE_TX_TEST_V2);
|
||||
*evt = cmd_complete_status(status);
|
||||
}
|
||||
|
||||
static void le_test_end(struct simple_buf *buf, struct simple_buf **evt)
|
||||
{
|
||||
struct bt_hci_rp_le_test_end *rp;
|
||||
uint16_t rx_pkt_count;
|
||||
uint8_t status;
|
||||
|
||||
PRINT("%s:\n", __FUNCTION__);
|
||||
|
||||
LL_TestEnd((uint8_t *)&rx_pkt_count);
|
||||
status = API_LE_TestEndCmd();
|
||||
|
||||
PRINT(" status: %#x\n", status);
|
||||
PRINT(" pkt count: %ld\n", rx_pkt_count);
|
||||
|
||||
rp = hci_cmd_complete(evt, sizeof(*rp));
|
||||
rp->status = status;
|
||||
rp->rx_pkt_count = rx_pkt_count;
|
||||
}
|
||||
|
||||
static void le_set_txpower(struct simple_buf *buf, struct simple_buf **evt)
|
||||
{
|
||||
struct bt_hci_set_txpower *tp = (void *)buf->data;
|
||||
uint8_t status;
|
||||
|
||||
PRINT("%s:\n", __FUNCTION__);
|
||||
PRINT(" tx power: %#x\n", tp->tx_power);
|
||||
|
||||
status = LL_SetTxPowerLevel(tp->tx_power);
|
||||
*evt = cmd_complete_status(status);
|
||||
}
|
||||
|
||||
static void le_set_xt32m_tune(struct simple_buf *buf, struct simple_buf **evt)
|
||||
{
|
||||
struct bt_hci_xt32m_tune *xt = (void *)buf->data;
|
||||
uint8_t status;
|
||||
|
||||
PRINT("%s:\n", __FUNCTION__);
|
||||
PRINT(" xt32m tune: %#x\n", xt->xt32m_tune);
|
||||
|
||||
if(xt->xt32m_tune > 7) {
|
||||
*evt = cmd_complete_status(0x12); //Invalid hci comd param
|
||||
}
|
||||
|
||||
OSC->HSE_CAL_CTRL &= ~(0x07<<28);
|
||||
OSC->HSE_CAL_CTRL |= xt->xt32m_tune<<28;
|
||||
|
||||
*evt = cmd_complete_status(0x00);
|
||||
}
|
||||
|
||||
static void le_set_single_carrier(struct simple_buf *buf, struct simple_buf **evt)
|
||||
{
|
||||
struct bt_hci_single_carrier *sc = (void *)buf->data;
|
||||
uint8_t status;
|
||||
|
||||
PRINT("%s:\n", __FUNCTION__);
|
||||
PRINT(" single carrier: %#x\n", sc->single_carrier);
|
||||
|
||||
status = LL_SingleChannel(sc->single_carrier);
|
||||
*evt = cmd_complete_status(status);
|
||||
}
|
||||
|
||||
static int ctrl_bb_cmd_handle(uint16_t ocf, struct simple_buf *cmd,
|
||||
struct simple_buf **evt)
|
||||
{
|
||||
switch (ocf) {
|
||||
case BT_OCF(BT_HCI_OP_RESET):
|
||||
reset(cmd, evt);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int controller_cmd_handle(uint16_t ocf, struct simple_buf *cmd,
|
||||
struct simple_buf **evt)
|
||||
{
|
||||
switch (ocf) {
|
||||
case BT_OCF(BT_HCI_OP_LE_RX_TEST):
|
||||
le_rx_test(cmd, evt);
|
||||
break;
|
||||
case BT_OCF(BT_HCI_OP_LE_TX_TEST):
|
||||
le_tx_test(cmd, evt);
|
||||
break;
|
||||
case BT_OCF(BT_HCI_OP_LE_RX_TEST_V2):
|
||||
le_rx_test_v2(cmd, evt);
|
||||
break;
|
||||
case BT_OCF(BT_HCI_OP_LE_TX_TEST_V2):
|
||||
le_tx_test_v2(cmd, evt);
|
||||
break;
|
||||
case BT_OCF(BT_HCI_OP_LE_TEST_END):
|
||||
le_test_end(cmd, evt);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hci_vendor_cmd_handle(uint16_t ocf, struct simple_buf *cmd,
|
||||
struct simple_buf **evt)
|
||||
{
|
||||
switch (ocf)
|
||||
{
|
||||
case BT_OCF(BT_HCI_SET_TXPOWER):
|
||||
le_set_txpower(cmd, evt);
|
||||
break;
|
||||
case BT_OCF(BT_HCI_XT32M_TUNE):
|
||||
le_set_xt32m_tune(cmd, evt);
|
||||
break;
|
||||
case BT_OCF(BT_HCI_SINGLE_CARRIER):
|
||||
le_set_single_carrier(cmd, evt);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct simple_buf *hci_cmd_handle(struct simple_buf *cmd)
|
||||
{
|
||||
struct bt_hci_pkt_type *pt;
|
||||
struct bt_hci_cmd_hdr *chdr;
|
||||
struct simple_buf *evt = NULL;
|
||||
uint16_t ocf;
|
||||
int err;
|
||||
|
||||
pt = simple_buf_pull(cmd, sizeof(*pt));
|
||||
if(pt->type != BT_HCI_PKT_TYPE_CMD) {
|
||||
PRINT("Invalid HCI CMD packet type\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cmd->len < sizeof(*chdr)) {
|
||||
PRINT("No HCI Command header\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
chdr = simple_buf_pull(cmd, sizeof(*chdr));
|
||||
|
||||
if (cmd->len < chdr->param_len) {
|
||||
PRINT("Invalid HCI CMD packet length\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* store in a global for later CC/CS event creation */
|
||||
_opcode = chdr->opcode;
|
||||
|
||||
ocf = BT_OCF(_opcode);
|
||||
|
||||
switch (BT_OGF(_opcode)) {
|
||||
case BT_OGF_BASEBAND:
|
||||
err = ctrl_bb_cmd_handle(ocf, cmd, &evt);
|
||||
break;
|
||||
case BT_OGF_LE:
|
||||
err = controller_cmd_handle(ocf, cmd, &evt);
|
||||
break;
|
||||
case BT_OGF_VS:
|
||||
err = hci_vendor_cmd_handle(ocf, cmd, &evt);
|
||||
break;
|
||||
default:
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return evt;
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2015, Wind River Systems, Inc.
|
||||
* Copyright (c) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_SYS_ATOMIC_H_
|
||||
#define ZEPHYR_INCLUDE_SYS_ATOMIC_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int atomic_t;
|
||||
typedef atomic_t atomic_val_t;
|
||||
typedef void *atomic_ptr_t;
|
||||
typedef atomic_ptr_t atomic_ptr_val_t;
|
||||
|
||||
#include <atomic_builtin.h>
|
||||
|
||||
|
||||
/* Portable higher-level utilities: */
|
||||
|
||||
/**
|
||||
* @defgroup atomic_apis Atomic Services APIs
|
||||
* @ingroup kernel_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize an atomic variable.
|
||||
*
|
||||
* This macro can be used to initialize an atomic variable. For example,
|
||||
* @code atomic_t my_var = ATOMIC_INIT(75); @endcode
|
||||
*
|
||||
* @param i Value to assign to atomic variable.
|
||||
*/
|
||||
#define ATOMIC_INIT(i) (i)
|
||||
|
||||
/**
|
||||
* @brief Initialize an atomic pointer variable.
|
||||
*
|
||||
* This macro can be used to initialize an atomic pointer variable. For
|
||||
* example,
|
||||
* @code atomic_ptr_t my_ptr = ATOMIC_PTR_INIT(&data); @endcode
|
||||
*
|
||||
* @param p Pointer value to assign to atomic pointer variable.
|
||||
*/
|
||||
#define ATOMIC_PTR_INIT(p) (p)
|
||||
|
||||
/**
|
||||
* @cond INTERNAL_HIDDEN
|
||||
*/
|
||||
|
||||
#define ATOMIC_BITS (sizeof(atomic_val_t) * 8)
|
||||
#define ATOMIC_MASK(bit) (1U << ((uint32_t)(bit) & (ATOMIC_BITS - 1U)))
|
||||
#define ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / ATOMIC_BITS))
|
||||
|
||||
/**
|
||||
* INTERNAL_HIDDEN @endcond
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This macro computes the number of atomic variables necessary to
|
||||
* represent a bitmap with @a num_bits.
|
||||
*
|
||||
* @param num_bits Number of bits.
|
||||
*/
|
||||
#define ATOMIC_BITMAP_SIZE(num_bits) (1 + ((num_bits) - 1) / ATOMIC_BITS)
|
||||
|
||||
/**
|
||||
* @brief Define an array of atomic variables.
|
||||
*
|
||||
* This macro defines an array of atomic variables containing at least
|
||||
* @a num_bits bits.
|
||||
*
|
||||
* @note
|
||||
* If used from file scope, the bits of the array are initialized to zero;
|
||||
* if used from within a function, the bits are left uninitialized.
|
||||
*
|
||||
* @cond INTERNAL_HIDDEN
|
||||
* @note
|
||||
* This macro should be replicated in the PREDEFINED field of the documentation
|
||||
* Doxyfile.
|
||||
* @endcond
|
||||
*
|
||||
* @param name Name of array of atomic variables.
|
||||
* @param num_bits Number of bits needed.
|
||||
*/
|
||||
#define ATOMIC_DEFINE(name, num_bits) \
|
||||
atomic_t name[ATOMIC_BITMAP_SIZE(num_bits)]
|
||||
|
||||
/**
|
||||
* @brief Atomically test a bit.
|
||||
*
|
||||
* This routine tests whether bit number @a bit of @a target is set or not.
|
||||
* The target may be a single atomic variable or an array of them.
|
||||
*
|
||||
* @param target Address of atomic variable or array.
|
||||
* @param bit Bit number (starting from 0).
|
||||
*
|
||||
* @return true if the bit was set, false if it wasn't.
|
||||
*/
|
||||
static inline bool atomic_test_bit(const atomic_t *target, int bit)
|
||||
{
|
||||
atomic_val_t val = atomic_get(ATOMIC_ELEM(target, bit));
|
||||
|
||||
return (1 & (val >> (bit & (ATOMIC_BITS - 1)))) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Atomically test and clear a bit.
|
||||
*
|
||||
* Atomically clear bit number @a bit of @a target and return its old value.
|
||||
* The target may be a single atomic variable or an array of them.
|
||||
*
|
||||
* @param target Address of atomic variable or array.
|
||||
* @param bit Bit number (starting from 0).
|
||||
*
|
||||
* @return true if the bit was set, false if it wasn't.
|
||||
*/
|
||||
static inline bool atomic_test_and_clear_bit(atomic_t *target, int bit)
|
||||
{
|
||||
atomic_val_t mask = ATOMIC_MASK(bit);
|
||||
atomic_val_t old;
|
||||
|
||||
old = atomic_and(ATOMIC_ELEM(target, bit), ~mask);
|
||||
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Atomically set a bit.
|
||||
*
|
||||
* Atomically set bit number @a bit of @a target and return its old value.
|
||||
* The target may be a single atomic variable or an array of them.
|
||||
*
|
||||
* @param target Address of atomic variable or array.
|
||||
* @param bit Bit number (starting from 0).
|
||||
*
|
||||
* @return true if the bit was set, false if it wasn't.
|
||||
*/
|
||||
static inline bool atomic_test_and_set_bit(atomic_t *target, int bit)
|
||||
{
|
||||
atomic_val_t mask = ATOMIC_MASK(bit);
|
||||
atomic_val_t old;
|
||||
|
||||
old = atomic_or(ATOMIC_ELEM(target, bit), mask);
|
||||
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Atomically clear a bit.
|
||||
*
|
||||
* Atomically clear bit number @a bit of @a target.
|
||||
* The target may be a single atomic variable or an array of them.
|
||||
*
|
||||
* @param target Address of atomic variable or array.
|
||||
* @param bit Bit number (starting from 0).
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
static inline void atomic_clear_bit(atomic_t *target, int bit)
|
||||
{
|
||||
atomic_val_t mask = ATOMIC_MASK(bit);
|
||||
|
||||
(void)atomic_and(ATOMIC_ELEM(target, bit), ~mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Atomically set a bit.
|
||||
*
|
||||
* Atomically set bit number @a bit of @a target.
|
||||
* The target may be a single atomic variable or an array of them.
|
||||
*
|
||||
* @param target Address of atomic variable or array.
|
||||
* @param bit Bit number (starting from 0).
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
static inline void atomic_set_bit(atomic_t *target, int bit)
|
||||
{
|
||||
atomic_val_t mask = ATOMIC_MASK(bit);
|
||||
|
||||
(void)atomic_or(ATOMIC_ELEM(target, bit), mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Atomically set a bit to a given value.
|
||||
*
|
||||
* Atomically set bit number @a bit of @a target to value @a val.
|
||||
* The target may be a single atomic variable or an array of them.
|
||||
*
|
||||
* @param target Address of atomic variable or array.
|
||||
* @param bit Bit number (starting from 0).
|
||||
* @param val true for 1, false for 0.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
static inline void atomic_set_bit_to(atomic_t *target, int bit, bool val)
|
||||
{
|
||||
atomic_val_t mask = ATOMIC_MASK(bit);
|
||||
|
||||
if (val) {
|
||||
(void)atomic_or(ATOMIC_ELEM(target, bit), mask);
|
||||
} else {
|
||||
(void)atomic_and(ATOMIC_ELEM(target, bit), ~mask);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_SYS_ATOMIC_H_ */
|
||||
@@ -0,0 +1,303 @@
|
||||
/* atomic operations */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2015, Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_SYS_ATOMIC_BUILTIN_H_
|
||||
#define ZEPHYR_INCLUDE_SYS_ATOMIC_BUILTIN_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Included from <atomic.h> */
|
||||
|
||||
/**
|
||||
* @addtogroup atomic_apis Atomic Services APIs
|
||||
* @ingroup kernel_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Atomic compare-and-set.
|
||||
*
|
||||
* This routine performs an atomic compare-and-set on @a target. If the current
|
||||
* value of @a target equals @a old_value, @a target is set to @a new_value.
|
||||
* If the current value of @a target does not equal @a old_value, @a target
|
||||
* is left unchanged.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
* @param old_value Original value to compare against.
|
||||
* @param new_value New value to store.
|
||||
* @return true if @a new_value is written, false otherwise.
|
||||
*/
|
||||
static inline bool atomic_cas(atomic_t *target, atomic_val_t old_value,
|
||||
atomic_val_t new_value)
|
||||
{
|
||||
return __atomic_compare_exchange_n(target, &old_value, new_value,
|
||||
0, __ATOMIC_SEQ_CST,
|
||||
__ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Atomic compare-and-set with pointer values
|
||||
*
|
||||
* This routine performs an atomic compare-and-set on @a target. If the current
|
||||
* value of @a target equals @a old_value, @a target is set to @a new_value.
|
||||
* If the current value of @a target does not equal @a old_value, @a target
|
||||
* is left unchanged.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
* @param old_value Original value to compare against.
|
||||
* @param new_value New value to store.
|
||||
* @return true if @a new_value is written, false otherwise.
|
||||
*/
|
||||
static inline bool atomic_ptr_cas(atomic_ptr_t *target, atomic_ptr_val_t old_value,
|
||||
atomic_ptr_val_t new_value)
|
||||
{
|
||||
return __atomic_compare_exchange_n(target, &old_value, new_value,
|
||||
0, __ATOMIC_SEQ_CST,
|
||||
__ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic addition.
|
||||
*
|
||||
* This routine performs an atomic addition on @a target.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
* @param value Value to add.
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_val_t atomic_add(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
return __atomic_fetch_add(target, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic subtraction.
|
||||
*
|
||||
* This routine performs an atomic subtraction on @a target.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
* @param value Value to subtract.
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
return __atomic_fetch_sub(target, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic increment.
|
||||
*
|
||||
* This routine performs an atomic increment by 1 on @a target.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_val_t atomic_inc(atomic_t *target)
|
||||
{
|
||||
return atomic_add(target, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic decrement.
|
||||
*
|
||||
* This routine performs an atomic decrement by 1 on @a target.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_val_t atomic_dec(atomic_t *target)
|
||||
{
|
||||
return atomic_sub(target, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic get.
|
||||
*
|
||||
* This routine performs an atomic read on @a target.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
*
|
||||
* @return Value of @a target.
|
||||
*/
|
||||
static inline atomic_val_t atomic_get(const atomic_t *target)
|
||||
{
|
||||
return __atomic_load_n(target, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic get a pointer value
|
||||
*
|
||||
* This routine performs an atomic read on @a target.
|
||||
*
|
||||
* @param target Address of pointer variable.
|
||||
*
|
||||
* @return Value of @a target.
|
||||
*/
|
||||
static inline atomic_ptr_val_t atomic_ptr_get(const atomic_ptr_t *target)
|
||||
{
|
||||
return __atomic_load_n(target, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic get-and-set.
|
||||
*
|
||||
* This routine atomically sets @a target to @a value and returns
|
||||
* the previous value of @a target.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
* @param value Value to write to @a target.
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_val_t atomic_set(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
/* This builtin, as described by Intel, is not a traditional
|
||||
* test-and-set operation, but rather an atomic exchange operation. It
|
||||
* writes value into *ptr, and returns the previous contents of *ptr.
|
||||
*/
|
||||
return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic get-and-set for pointer values
|
||||
*
|
||||
* This routine atomically sets @a target to @a value and returns
|
||||
* the previous value of @a target.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
* @param value Value to write to @a target.
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_ptr_val_t atomic_ptr_set(atomic_ptr_t *target, atomic_ptr_val_t value)
|
||||
{
|
||||
return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic clear.
|
||||
*
|
||||
* This routine atomically sets @a target to zero and returns its previous
|
||||
* value. (Hence, it is equivalent to atomic_set(target, 0).)
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_val_t atomic_clear(atomic_t *target)
|
||||
{
|
||||
return atomic_set(target, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic clear of a pointer value
|
||||
*
|
||||
* This routine atomically sets @a target to zero and returns its previous
|
||||
* value. (Hence, it is equivalent to atomic_set(target, 0).)
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_ptr_val_t atomic_ptr_clear(atomic_ptr_t *target)
|
||||
{
|
||||
return atomic_ptr_set(target, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic bitwise inclusive OR.
|
||||
*
|
||||
* This routine atomically sets @a target to the bitwise inclusive OR of
|
||||
* @a target and @a value.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
* @param value Value to OR.
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_val_t atomic_or(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
return __atomic_fetch_or(target, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic bitwise exclusive OR (XOR).
|
||||
*
|
||||
* This routine atomically sets @a target to the bitwise exclusive OR (XOR) of
|
||||
* @a target and @a value.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
* @param value Value to XOR
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
return __atomic_fetch_xor(target, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic bitwise AND.
|
||||
*
|
||||
* This routine atomically sets @a target to the bitwise AND of @a target
|
||||
* and @a value.
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
* @param value Value to AND.
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_val_t atomic_and(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
return __atomic_fetch_and(target, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Atomic bitwise NAND.
|
||||
*
|
||||
* This routine atomically sets @a target to the bitwise NAND of @a target
|
||||
* and @a value. (This operation is equivalent to target = ~(target & value).)
|
||||
*
|
||||
* @param target Address of atomic variable.
|
||||
* @param value Value to NAND.
|
||||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value)
|
||||
{
|
||||
return __atomic_fetch_nand(target, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_SYS_ATOMIC_BUILTIN_H_ */
|
||||
@@ -0,0 +1,103 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : buf.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2022/06/30
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef BLE_DIRECTTEST_APP_INCLUDE_BUF_H
|
||||
#define BLE_DIRECTTEST_APP_INCLUDE_BUF_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
struct simple_buf {
|
||||
/** Pointer to the start of data in the buffer. */
|
||||
uint8_t *data;
|
||||
|
||||
/**
|
||||
* Length of the data behind the data pointer.
|
||||
*
|
||||
*/
|
||||
uint16_t len;
|
||||
|
||||
/** Amount of data that simple buf can store. */
|
||||
uint16_t size;
|
||||
|
||||
/** Start of the data storage. Not to be accessed directly
|
||||
* (the data pointer should be used instead).
|
||||
*/
|
||||
uint8_t *__buf;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief create a simple_buf object.
|
||||
*
|
||||
* @param buf simple_buf object
|
||||
* @param buf_pool simple_buf buffer
|
||||
* @param pool_size simple_buf size
|
||||
*/
|
||||
struct simple_buf *simple_buf_create(struct simple_buf *buf,
|
||||
uint8_t *buf_pool, uint16_t pool_size);
|
||||
|
||||
/**
|
||||
* @brief Prepare data to be added at the end of the buffer
|
||||
*
|
||||
* Increments the data length of a buffer to account for more data
|
||||
* at the end.
|
||||
*
|
||||
* @param buf Buffer to update.
|
||||
* @param len Number of bytes to increment the length with.
|
||||
*
|
||||
* @return The original tail of the buffer.
|
||||
*/
|
||||
void *simple_buf_add(struct simple_buf *buf, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Prepare data to be added to the start of the buffer
|
||||
*
|
||||
* Modifies the data pointer and buffer length to account for more data
|
||||
* in the beginning of the buffer.
|
||||
*
|
||||
* @param buf Buffer to update.
|
||||
* @param len Number of bytes to add to the beginning.
|
||||
*
|
||||
* @return The new beginning of the buffer data.
|
||||
*/
|
||||
void *simple_buf_pull(struct simple_buf *buf, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Copy given number of bytes from memory to the end of the buffer
|
||||
*
|
||||
* Increments the data length of the buffer to account for more data at the
|
||||
* end.
|
||||
*
|
||||
* @param buf Buffer to update.
|
||||
* @param mem Location of data to be added.
|
||||
* @param len Length of data to be added
|
||||
*
|
||||
* @return The original tail of the buffer.
|
||||
*/
|
||||
void *simple_buf_add_mem(struct simple_buf *buf, const void *mem,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* @brief Add (8-bit) byte at the end of the buffer
|
||||
*
|
||||
* Increments the data length of the buffer to account for more data at the
|
||||
* end.
|
||||
*
|
||||
* @param buf Buffer to update.
|
||||
* @param val byte value to be added.
|
||||
*
|
||||
* @return Pointer to the value added
|
||||
*/
|
||||
uint8_t *simple_buf_add_u8(struct simple_buf *buf, uint8_t val);
|
||||
|
||||
#endif /* BLE_DIRECTTEST_APP_INCLUDE_BUF_H */
|
||||
@@ -0,0 +1,37 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_conf.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* Description : Library configuration file.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __CH32V20x_CONF_H
|
||||
#define __CH32V20x_CONF_H
|
||||
|
||||
#include "ch32v20x_adc.h"
|
||||
#include "ch32v20x_bkp.h"
|
||||
#include "ch32v20x_can.h"
|
||||
#include "ch32v20x_crc.h"
|
||||
#include "ch32v20x_dbgmcu.h"
|
||||
#include "ch32v20x_dma.h"
|
||||
#include "ch32v20x_exti.h"
|
||||
#include "ch32v20x_flash.h"
|
||||
#include "ch32v20x_gpio.h"
|
||||
#include "ch32v20x_i2c.h"
|
||||
#include "ch32v20x_iwdg.h"
|
||||
#include "ch32v20x_pwr.h"
|
||||
#include "ch32v20x_rcc.h"
|
||||
#include "ch32v20x_rtc.h"
|
||||
#include "ch32v20x_spi.h"
|
||||
#include "ch32v20x_tim.h"
|
||||
#include "ch32v20x_usart.h"
|
||||
#include "ch32v20x_wwdg.h"
|
||||
#include "ch32v20x_it.h"
|
||||
#include "ch32v20x_misc.h"
|
||||
|
||||
#endif /* __CH32V20x_CONF_H */
|
||||
@@ -0,0 +1,18 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* Description : This file contains the headers of the interrupt handlers.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __CH32V20x_IT_H
|
||||
#define __CH32V20x_IT_H
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#endif /* __CH32V20x_IT_H */
|
||||
@@ -0,0 +1,150 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : hci_test.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2022/06/29
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef BLE_DIRECTTEST_APP_INCLUDE_HCI_TEST_H
|
||||
#define BLE_DIRECTTEST_APP_INCLUDE_HCI_TEST_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "buf.h"
|
||||
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
#define BT_HCI_LE_RX_PHY_1M 0x01
|
||||
#define BT_HCI_LE_RX_PHY_2M 0x02
|
||||
#define BT_HCI_LE_RX_PHY_CODED 0x03
|
||||
|
||||
#define BT_HCI_LE_TX_PHY_1M 0x01
|
||||
#define BT_HCI_LE_TX_PHY_2M 0x02
|
||||
#define BT_HCI_LE_TX_PHY_CODED_S8 0x03
|
||||
#define BT_HCI_LE_TX_PHY_CODED_S2 0x04
|
||||
|
||||
#define BT_HCI_TEST_PKT_PAYLOAD_PRBS9 0x00
|
||||
#define BT_HCI_TEST_PKT_PAYLOAD_11110000 0x01
|
||||
#define BT_HCI_TEST_PKT_PAYLOAD_10101010 0x02
|
||||
#define BT_HCI_TEST_PKT_PAYLOAD_PRBS15 0x03
|
||||
#define BT_HCI_TEST_PKT_PAYLOAD_11111111 0x04
|
||||
#define BT_HCI_TEST_PKT_PAYLOAD_00000000 0x05
|
||||
#define BT_HCI_TEST_PKT_PAYLOAD_00001111 0x06
|
||||
#define BT_HCI_TEST_PKT_PAYLOAD_01010101 0x07
|
||||
|
||||
struct bt_hci_pkt_type {
|
||||
uint8_t type;
|
||||
}__packed;
|
||||
|
||||
struct bt_hci_evt_hdr {
|
||||
uint8_t evt;
|
||||
uint8_t len;
|
||||
} __packed;
|
||||
|
||||
struct bt_hci_cmd_hdr {
|
||||
uint16_t opcode;
|
||||
uint8_t param_len;
|
||||
} __packed;
|
||||
|
||||
/* HCI packet type */
|
||||
#define BT_HCI_PKT_TYPE_CMD 0x01
|
||||
#define BT_HCI_PKT_TYPE_ACL 0x02
|
||||
#define BT_HCI_PKT_TYPE_SYNC 0x03
|
||||
#define BT_HCI_PKT_TYPE_EVT 0x04
|
||||
#define BT_HCI_PKT_TYPE_ISO 0x05
|
||||
|
||||
/* HCI BR/EDR link types */
|
||||
#define BT_HCI_SCO 0x00
|
||||
#define BT_HCI_ACL 0x01
|
||||
#define BT_HCI_ESCO 0x02
|
||||
|
||||
/* OpCode Group Fields */
|
||||
#define BT_OGF_LINK_CTRL 0x01
|
||||
#define BT_OGF_BASEBAND 0x03
|
||||
#define BT_OGF_INFO 0x04
|
||||
#define BT_OGF_STATUS 0x05
|
||||
#define BT_OGF_LE 0x08
|
||||
#define BT_OGF_VS 0x3f
|
||||
|
||||
/* Construct OpCode from OGF and OCF */
|
||||
#define BT_OP(ogf, ocf) ((ocf) | ((ogf) << 10))
|
||||
|
||||
/* Invalid opcode */
|
||||
#define BT_OP_NOP 0x0000
|
||||
|
||||
/* Obtain OGF from OpCode */
|
||||
#define BT_OGF(opcode) (((opcode) >> 10) & ((1<<6)- 1U))
|
||||
/* Obtain OCF from OpCode */
|
||||
#define BT_OCF(opcode) ((opcode) & ((1<<10) - 1U))
|
||||
|
||||
#define BT_HCI_OP_RESET BT_OP(BT_OGF_BASEBAND, 0x0003)
|
||||
|
||||
#define BT_HCI_OP_LE_TEST_END BT_OP(BT_OGF_LE, 0x001f)
|
||||
struct bt_hci_rp_le_test_end {
|
||||
uint8_t status;
|
||||
uint16_t rx_pkt_count;
|
||||
} __packed;
|
||||
|
||||
#define BT_HCI_OP_LE_RX_TEST BT_OP(BT_OGF_LE, 0x001d)
|
||||
struct bt_hci_cp_le_rx_test {
|
||||
uint8_t rx_ch;
|
||||
} __packed;
|
||||
|
||||
#define BT_HCI_OP_LE_RX_TEST_V2 BT_OP(BT_OGF_LE, 0x0033)
|
||||
struct bt_hci_cp_le_rx_test_v2 {
|
||||
uint8_t rx_ch;
|
||||
uint8_t phy;
|
||||
/* ATTENTION: Modulation_Index feature is not currently supported */
|
||||
uint8_t mod_index;
|
||||
} __packed;
|
||||
|
||||
#define BT_HCI_OP_LE_TX_TEST BT_OP(BT_OGF_LE, 0x001e)
|
||||
struct bt_hci_cp_le_tx_test {
|
||||
uint8_t tx_ch;
|
||||
uint8_t test_data_len;
|
||||
uint8_t pkt_payload;
|
||||
} __packed;
|
||||
|
||||
#define BT_HCI_OP_LE_TX_TEST_V2 BT_OP(BT_OGF_LE, 0x0034)
|
||||
struct bt_hci_cp_le_tx_test_v2 {
|
||||
uint8_t tx_ch;
|
||||
uint8_t test_data_len;
|
||||
uint8_t pkt_payload;
|
||||
uint8_t phy;
|
||||
} __packed;
|
||||
|
||||
#define BT_HCI_EVT_CMD_COMPLETE 0x0e
|
||||
struct bt_hci_evt_cmd_complete {
|
||||
uint8_t ncmd;
|
||||
uint16_t opcode;
|
||||
} __packed;
|
||||
|
||||
struct bt_hci_evt_cc_status {
|
||||
uint8_t status;
|
||||
} __packed;
|
||||
|
||||
/*vender cmds*/
|
||||
#define BT_HCI_SET_TXPOWER BT_OP(BT_OGF_VS, 0x0301)
|
||||
struct bt_hci_set_txpower {
|
||||
uint8_t tx_power;
|
||||
} __packed;
|
||||
|
||||
#define BT_HCI_XT32M_TUNE BT_OP(BT_OGF_VS, 0x0302)
|
||||
struct bt_hci_xt32m_tune {
|
||||
uint8_t xt32m_tune;
|
||||
} __packed;
|
||||
|
||||
#define BT_HCI_SINGLE_CARRIER BT_OP(BT_OGF_VS, 0x0303)
|
||||
struct bt_hci_single_carrier {
|
||||
uint8_t single_carrier;
|
||||
} __packed;
|
||||
|
||||
struct simple_buf *hci_cmd_handle(struct simple_buf *cmd);
|
||||
|
||||
#endif /* BLE_DIRECTTEST_APP_INCLUDE_HCI_TEST_H */
|
||||
@@ -0,0 +1,31 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Header File.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __SYSTEM_ch32v20x_H
|
||||
#define __SYSTEM_ch32v20x_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
/* System_Exported_Functions */
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__CH32V20x_SYSTEM_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : test_dtm.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2022/06/29
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef BLE_DIRECTTEST_APP_INCLUDE_TEST_DTM_H
|
||||
#define BLE_DIRECTTEST_APP_INCLUDE_TEST_DTM_H
|
||||
|
||||
#include "hci_test.h"
|
||||
|
||||
extern tmosTaskID test_taskid;
|
||||
|
||||
void test_dtm_init(void);
|
||||
|
||||
#endif /* BLE_DIRECTTEST_APP_INCLUDE_TEST_DTM_H */
|
||||
@@ -0,0 +1,34 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : uart.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2022/06/30
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef BLE_DIRECTTEST_APP_INCLUDE_UART_H
|
||||
#define BLE_DIRECTTEST_APP_INCLUDE_UART_H
|
||||
|
||||
#include "config.h"
|
||||
#include "buf.h"
|
||||
|
||||
#define UART_PROCESS_EVT 1
|
||||
|
||||
/*process events*/
|
||||
#define UART_RECEIVE_POLL_EVT (1<<0)
|
||||
|
||||
struct uart_process_msg {
|
||||
tmos_event_hdr_t hdr;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
|
||||
int uart_send(struct simple_buf *buf);
|
||||
int uart_start_receiving(void);
|
||||
void uart_task_init(void);
|
||||
|
||||
#endif /* BLE_DIRECTTEST_APP_INCLUDE_UART_H */
|
||||
@@ -0,0 +1,68 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : main.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2020/08/06
|
||||
* Description : Direct test mode
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header file contains */
|
||||
#include "CONFIG.h"
|
||||
#include "HAL.h"
|
||||
#include "test_dtm.h"
|
||||
#include "uart.h"
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL TYPEDEFS
|
||||
*/
|
||||
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
|
||||
|
||||
#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
|
||||
const uint8_t MacAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Main_Circulation
|
||||
*
|
||||
* @brief Main loop
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__((section(".highcode")))
|
||||
__attribute__((noinline))
|
||||
void Main_Circulation(void)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
TMOS_SystemProcess();
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn main
|
||||
*
|
||||
* @brief Main function
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
Delay_Init();
|
||||
#ifdef DEBUG
|
||||
USART_Printf_Init( 115200 );
|
||||
#endif
|
||||
PRINT("%s\n", VER_LIB);
|
||||
WCHBLE_Init();
|
||||
HAL_Init();
|
||||
uart_task_init();
|
||||
test_dtm_init();
|
||||
GAPRole_BroadcasterInit();
|
||||
Main_Circulation();
|
||||
}
|
||||
|
||||
/******************************** endfile @ main ******************************/
|
||||
@@ -0,0 +1,989 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Source File.
|
||||
* For HSE = 32Mhz (CH32V208x/CH32V203RBT6)
|
||||
* For HSE = 8Mhz (other CH32V203x)
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32v20x.h"
|
||||
|
||||
/*
|
||||
* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
|
||||
* reset the HSI is used as SYSCLK source).
|
||||
* If none of the define below is enabled, the HSI is used as System clock source.
|
||||
*/
|
||||
//#define SYSCLK_FREQ_HSE HSE_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSE 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSE 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSE 72000000
|
||||
#define SYSCLK_FREQ_96MHz_HSE 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSE 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSE 144000000
|
||||
//#define SYSCLK_FREQ_HSI HSI_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSI 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSI 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSI 72000000
|
||||
//#define SYSCLK_FREQ_96MHz_HSI 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSI 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSI 144000000
|
||||
|
||||
/* Clock Definitions */
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#else
|
||||
uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
#endif
|
||||
|
||||
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
|
||||
|
||||
/* system_private_function_proto_types */
|
||||
static void SetSysClock(void);
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
static void SetSysClockToHSE( void );
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
static void SetSysClockTo48_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
static void SetSysClockTo56_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
static void SetSysClockTo72_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
static void SetSysClockTo96_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
static void SetSysClockTo120_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
static void SetSysClockTo144_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
static void SetSysClockTo48_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
static void SetSysClockTo56_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
static void SetSysClockTo72_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
static void SetSysClockTo96_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
static void SetSysClockTo120_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
static void SetSysClockTo144_HSI( void );
|
||||
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemInit
|
||||
*
|
||||
* @brief Setup the microcontroller system Initialize the Embedded Flash Interface,
|
||||
* the PLL and update the SystemCoreClock variable.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
RCC->CTLR |= (uint32_t)0x00000001;
|
||||
RCC->CFGR0 &= (uint32_t)0xF8FF0000;
|
||||
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
|
||||
RCC->CTLR &= (uint32_t)0xFFFBFFFF;
|
||||
RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
|
||||
RCC->INTR = 0x009F0000;
|
||||
SetSysClock();
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemCoreClockUpdate
|
||||
*
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0;
|
||||
|
||||
tmp = RCC->CFGR0 & RCC_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04:
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08:
|
||||
pllmull = RCC->CFGR0 & RCC_PLLMULL;
|
||||
pllsource = RCC->CFGR0 & RCC_PLLSRC;
|
||||
pllmull = ( pllmull >> 18) + 2;
|
||||
|
||||
if(pllmull == 17) pllmull = 18;
|
||||
|
||||
if (pllsource == 0x00)
|
||||
{
|
||||
if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE){
|
||||
SystemCoreClock = HSI_VALUE * pllmull;
|
||||
}
|
||||
else{
|
||||
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
if((RCC->CFGR0 & (3<<22)) == (3<<22))
|
||||
{
|
||||
SystemCoreClock = ((HSE_VALUE>>1)) * pllmull;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = ((HSE_VALUE>>2) >> 1) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = (HSE_VALUE>>2) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2);
|
||||
|
||||
break;
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClock
|
||||
*
|
||||
* @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClock(void)
|
||||
{
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
SetSysClockToHSE();
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
SetSysClockTo48_HSE();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
SetSysClockTo56_HSE();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
SetSysClockTo72_HSE();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
SetSysClockTo96_HSE();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
SetSysClockTo120_HSE();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
SetSysClockTo144_HSE();
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
SetSysClockTo48_HSI();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
SetSysClockTo56_HSI();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
SetSysClockTo72_HSI();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
SetSysClockTo96_HSI();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
SetSysClockTo120_HSI();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
SetSysClockTo144_HSI();
|
||||
|
||||
#endif
|
||||
|
||||
/* If none of the define above is enabled, the HSI is used as System clock
|
||||
* source (default after reset)
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockToHSE
|
||||
*
|
||||
* @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockToHSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
|
||||
|
||||
/* Select HSE as system clock source
|
||||
* CH32V20x_D6 (HSE=8MHZ)
|
||||
* CH32V20x_D8 (HSE=32MHZ)
|
||||
* CH32V20x_D8W (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
|
||||
|
||||
/* Wait till HSE is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if(HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
RCC->CFGR0 |= (uint32_t)(3<<22);
|
||||
/* HCLK = SYSCLK/2 */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2;
|
||||
#else
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
#endif
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 15 = 120 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 7 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : test_dtm.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2022/06/29
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "test_dtm.h"
|
||||
#include "uart.h"
|
||||
|
||||
tmosTaskID test_taskid = INVALID_TASK_ID;
|
||||
|
||||
/*********************************************************************
|
||||
* @fn test_dtm_process_msg
|
||||
*
|
||||
* @brief Process an incoming task message.
|
||||
*
|
||||
* @param pMsg - message to process
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void test_dtm_process_msg(tmos_event_hdr_t *pMsg) {
|
||||
switch (pMsg->event) {
|
||||
case UART_PROCESS_EVT:{
|
||||
struct simple_buf *evt = NULL;
|
||||
struct uart_process_msg *msg = \
|
||||
(struct uart_process_msg *)pMsg;
|
||||
|
||||
evt = hci_cmd_handle((struct simple_buf*)msg->data);
|
||||
|
||||
if(evt)
|
||||
uart_send(evt);
|
||||
|
||||
uart_start_receiving();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn test_dtm_processevent
|
||||
*
|
||||
* @brief process handle
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed
|
||||
*/
|
||||
tmosEvents test_dtm_processevent(tmosTaskID task_id, tmosEvents events)
|
||||
{
|
||||
uint8_t *msgPtr;
|
||||
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{ // 处理HAL层消息,调用tmos_msg_receive读取消息,处理完成后删除消息。
|
||||
msgPtr = tmos_msg_receive(task_id);
|
||||
if(msgPtr)
|
||||
{
|
||||
test_dtm_process_msg((tmos_event_hdr_t *)msgPtr);
|
||||
|
||||
/* De-allocate */
|
||||
tmos_msg_deallocate(msgPtr);
|
||||
}
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_dtm_init(void)
|
||||
{
|
||||
test_taskid = TMOS_ProcessEventRegister(test_dtm_processevent);
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : uart.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2022/06/30
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "atomic.h"
|
||||
#include "test_dtm.h"
|
||||
|
||||
static tmosTaskID uart_taskid;
|
||||
|
||||
static uint8_t rx_buf[100];
|
||||
static struct simple_buf *uart_buf = NULL;
|
||||
static struct simple_buf uart_buffer;
|
||||
|
||||
enum uart_status {
|
||||
UART_STATUS_IDLE,
|
||||
UART_STATUS_RCVING,
|
||||
UART_STATUS_RCV_END,
|
||||
UART_STATUS_SENDING,
|
||||
|
||||
UART_STATUS_NUM,
|
||||
};
|
||||
|
||||
atomic_t uart_flag;
|
||||
|
||||
void uart_buffer_create(struct simple_buf **buf)
|
||||
{
|
||||
*buf = simple_buf_create(&uart_buffer, rx_buf, sizeof(rx_buf));
|
||||
}
|
||||
|
||||
int uart_start_receiving(void)
|
||||
{
|
||||
PRINT("uart2 reeciving\n");
|
||||
atomic_set(&uart_flag, UART_STATUS_RCVING);
|
||||
uart_buffer_create(&uart_buf);
|
||||
USART_Cmd(USART2, ENABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart2_send_data(uint8_t *data, uint16_t len)
|
||||
{
|
||||
for(int i = 0; i < len; i++) {
|
||||
USART_SendData(USART2, data[i]);
|
||||
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {
|
||||
/* waiting for sending finish */
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int uart_send(struct simple_buf *buf)
|
||||
{
|
||||
atomic_set(&uart_flag, UART_STATUS_SENDING);
|
||||
|
||||
uint8_t *send_data;
|
||||
uint16_t send_len;
|
||||
|
||||
send_len = buf->len;
|
||||
send_data = simple_buf_pull(buf, buf->len);
|
||||
uart2_send_data(send_data, send_len);
|
||||
atomic_set(&uart_flag, UART_STATUS_IDLE);
|
||||
|
||||
PRINT("uart2 send %d bytes [", send_len);
|
||||
for(int i = 0; i < send_len; i++){
|
||||
if(i) PRINT(" ");
|
||||
PRINT("%#x", send_data[i]);
|
||||
}
|
||||
PRINT("]\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn uart_processevent
|
||||
*
|
||||
* @brief process handle
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed
|
||||
*/
|
||||
tmosEvents uart_processevent(tmosTaskID task_id, tmosEvents events)
|
||||
{
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *msgPtr;
|
||||
|
||||
msgPtr = tmos_msg_receive(task_id);
|
||||
if(msgPtr)
|
||||
{
|
||||
/* De-allocate */
|
||||
tmos_msg_deallocate(msgPtr);
|
||||
}
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
if(events & UART_RECEIVE_POLL_EVT) {
|
||||
if(atomic_get(&uart_flag) == UART_STATUS_RCV_END) {
|
||||
PRINT("uart2 recevied %d bytes [", uart_buf->len);
|
||||
for(int i = 0; i < uart_buf->len; i++) {
|
||||
if(i) PRINT(" ");
|
||||
PRINT("%#x", uart_buf->data[i]);
|
||||
}
|
||||
PRINT("]\n");
|
||||
|
||||
struct uart_process_msg *uart_msg;
|
||||
|
||||
uart_msg = (struct uart_process_msg *) \
|
||||
tmos_msg_allocate(sizeof(struct uart_process_msg));
|
||||
|
||||
if(uart_msg) {
|
||||
uart_msg->hdr.event = UART_PROCESS_EVT;
|
||||
uart_msg->hdr.status = true;
|
||||
uart_msg->data = (uint8_t *)uart_buf;
|
||||
tmos_msg_send(test_taskid, (uint8_t *)uart_msg );
|
||||
}
|
||||
}
|
||||
|
||||
return (events ^ UART_RECEIVE_POLL_EVT);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uart_task_init(void)
|
||||
{
|
||||
uart_taskid = TMOS_ProcessEventRegister(uart_processevent);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure = {0};
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
|
||||
/* USART2 TX-->A.2 RX-->A.3 */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
USART_InitStructure.USART_BaudRate = 115200;
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||||
|
||||
USART_Init(USART2, &USART_InitStructure);
|
||||
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
|
||||
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
tmos_start_reload_task(uart_taskid, UART_RECEIVE_POLL_EVT,
|
||||
MS1_TO_SYSTEM_TIME(100));
|
||||
|
||||
atomic_set(&uart_flag, UART_STATUS_IDLE);
|
||||
uart_start_receiving();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USART2_IRQHandler
|
||||
*
|
||||
* @brief This function handles USART2 global interrupt request.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__((interrupt("WCH-Interrupt-fast")))
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
|
||||
{
|
||||
simple_buf_add_u8(uart_buf, USART_ReceiveData(USART2));
|
||||
}
|
||||
|
||||
if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)
|
||||
{
|
||||
atomic_set(&uart_flag, UART_STATUS_RCV_END);
|
||||
|
||||
/* clear IDLE flag */
|
||||
(void)USART_ReceiveData(USART2);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user