V2.0
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,107 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : main.c
|
||||
* Author : WCH
|
||||
* Version : V1.2
|
||||
* Date : 2022/06/22
|
||||
* 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.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header file contains */
|
||||
#include "CONFIG.h"
|
||||
#include "MESH_LIB.h"
|
||||
#include "HAL.h"
|
||||
#include "app_mesh_config.h"
|
||||
#include "app.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 bt_mesh_lib_init
|
||||
*
|
||||
* @brief mesh ¿â³õʼ»¯
|
||||
*
|
||||
* @return state
|
||||
*/
|
||||
uint8_t bt_mesh_lib_init(void)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
if(tmos_memcmp(VER_MESH_LIB, VER_MESH_FILE, strlen(VER_MESH_FILE)) == FALSE)
|
||||
{
|
||||
PRINT("mesh head file error...\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
ret = RF_RoleInit();
|
||||
|
||||
#if((CONFIG_BLE_MESH_PROXY) || \
|
||||
(CONFIG_BLE_MESH_PB_GATT) || \
|
||||
(CONFIG_BLE_MESH_OTA))
|
||||
ret = GAPRole_PeripheralInit();
|
||||
#endif /* PROXY || PB-GATT || OTA */
|
||||
|
||||
#if(CONFIG_BLE_MESH_PROXY_CLI)
|
||||
ret = GAPRole_CentralInit();
|
||||
#endif /* CONFIG_BLE_MESH_PROXY_CLI */
|
||||
|
||||
MeshTimer_Init();
|
||||
MeshDeamon_Init();
|
||||
ble_sm_alg_ecc_init();
|
||||
|
||||
#if(CONFIG_BLE_MESH_IV_UPDATE_TEST)
|
||||
bt_mesh_iv_update_test(TRUE);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @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)
|
||||
{
|
||||
SystemCoreClockUpdate();
|
||||
Delay_Init();
|
||||
#ifdef DEBUG
|
||||
USART_Printf_Init( 115200 );
|
||||
#endif
|
||||
PRINT("%s\n", VER_LIB);
|
||||
WCHBLE_Init();
|
||||
HAL_Init();
|
||||
bt_mesh_lib_init();
|
||||
App_Init();
|
||||
Main_Circulation();
|
||||
}
|
||||
|
||||
/******************************** endfile @ main ******************************/
|
||||
@@ -0,0 +1,182 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : app_mesh_config.c
|
||||
* Author : WCH
|
||||
* Version : V1.2
|
||||
* Date : 2022/06/22
|
||||
* 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.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header file contains */
|
||||
#include "CONFIG.h"
|
||||
#include "app_mesh_config.h"
|
||||
#include "MESH_LIB.h"
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL TYPEDEFS
|
||||
*/
|
||||
const ble_mesh_cfg_t app_mesh_cfg = {
|
||||
.common_cfg.adv_buf_count = CONFIG_MESH_ADV_BUF_COUNT_DEF,
|
||||
.common_cfg.rpl_count = CONFIG_MESH_RPL_COUNT_DEF,
|
||||
.common_cfg.allow_rpl_cycle = CONFIG_MESH_ALLOW_RPL_CYCLE,
|
||||
.common_cfg.allow_same_addr = CONFIG_MESH_ALLOW_SAME_ADDR,
|
||||
.common_cfg.ivu_divider = CONFIG_MESH_IVU_DIVIDER_DEF,
|
||||
.common_cfg.mod_key_count = CONFIG_MESH_MOD_KEY_COUNT_DEF,
|
||||
.common_cfg.mod_group_count = CONFIG_MESH_MOD_GROUP_COUNT_DEF,
|
||||
|
||||
.proxy_cfg.pxyfilter_count = CONFIG_MESH_PROXY_FILTER_DEF,
|
||||
|
||||
.net_cfg.msgcache_count = CONFIG_MESH_MSG_CACHE_DEF,
|
||||
.net_cfg.subnet_count = CONFIG_MESH_SUBNET_COUNT_DEF,
|
||||
.net_cfg.appkey_count = CONFIG_MESH_APPKEY_COUNT_DEF,
|
||||
.net_cfg.unseg_length = CONFIG_MESH_UNSEG_LENGTH_DEF,
|
||||
.net_cfg.txseg_max = CONFIG_MESH_TX_SEG_DEF,
|
||||
.net_cfg.txseg_count = CONFIG_MESH_TX_SEG_COUNT_DEF,
|
||||
.net_cfg.rxseg_count = CONFIG_MESH_RX_SEG_COUNT_DEF,
|
||||
.net_cfg.rxsdu_max = CONFIG_MESH_RX_SDU_DEF,
|
||||
.net_cfg.label_count = CONFIG_MESH_LABEL_COUNT_DEF,
|
||||
|
||||
.store_cfg.seq_store_rate = CONFIG_MESH_SEQ_STORE_RATE_DEF,
|
||||
.store_cfg.rpl_store_rate = CONFIG_MESH_RPL_STORE_RATE_DEF,
|
||||
.store_cfg.store_rate = CONFIG_MESH_STORE_RATE_DEF,
|
||||
|
||||
.friend_cfg.frndseg_rx = CONFIG_MESH_FRIEND_SEG_RX_COUNT_DEF,
|
||||
.friend_cfg.frndsub_size = CONFIG_MESH_FRIEND_SUB_SIZE_DEF,
|
||||
.friend_cfg.frndlpn_count = CONFIG_MESH_FRIEND_LPN_COUNT_DEF,
|
||||
.friend_cfg.frndqueue_size = CONFIG_MESH_QUEUE_SIZE_DEF,
|
||||
.friend_cfg.frndrecv_win = CONFIG_MESH_FRIEND_RECV_WIN_DEF,
|
||||
|
||||
.lpn_cfg.lpnmin_size = CONFIG_MESH_LPN_REQ_QUEUE_SIZE_DEF,
|
||||
.lpn_cfg.lpnrssi_factor = 0,
|
||||
.lpn_cfg.lpnrecv_factor = 0,
|
||||
.lpn_cfg.lpnpoll_interval = CONFIG_MESH_LPN_POLLINTERVAL_DEF,
|
||||
.lpn_cfg.lpnpoll_timeout = CONFIG_MESH_LPN_POLLTIMEOUT_DEF,
|
||||
.lpn_cfg.lpnrecv_delay = CONFIG_MESH_LPN_RECV_DELAY_DEF,
|
||||
.lpn_cfg.lpnretry_timeout = CONFIG_MESH_RETRY_TIMEOUT_DEF,
|
||||
|
||||
.prov_cfg.node_count = CONFIG_MESH_PROV_NODE_COUNT_DEF,
|
||||
.rf_cfg.rf_accessAddress = CONFIG_MESH_RF_ACCESSADDRESS,
|
||||
.rf_cfg.rf_channel_37 = CONFIG_MESH_RF_CHANNEL_37,
|
||||
.rf_cfg.rf_channel_38 = CONFIG_MESH_RF_CHANNEL_38,
|
||||
.rf_cfg.rf_channel_39 = CONFIG_MESH_RF_CHANNEL_39,
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* @fn read_flash
|
||||
*
|
||||
* @brief read flash
|
||||
*
|
||||
* @param offset - 地址偏移
|
||||
* @param data - 数据指针
|
||||
* @param len - 长度
|
||||
*
|
||||
* @return always success
|
||||
*/
|
||||
int read_flash(int offset, void *data, unsigned int len)
|
||||
{
|
||||
tmos_memcpy(data, (uint8_t*)offset, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn write_flash
|
||||
*
|
||||
* @brief write flash
|
||||
*
|
||||
* @param offset - 地址偏移
|
||||
* @param data - 数据指针
|
||||
* @param len - 长度
|
||||
*
|
||||
* @return state
|
||||
*/
|
||||
int write_flash(int offset, const void *data, unsigned int len)
|
||||
{
|
||||
FLASH_Status status = FLASH_COMPLETE;
|
||||
__attribute__((aligned(4))) uint8_t vec[64]={0};
|
||||
uint8_t i;
|
||||
|
||||
if(len > sizeof(vec))
|
||||
{
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
memcpy(vec, data, len);
|
||||
|
||||
FLASH_Unlock();
|
||||
for( i=0; i<(len+1)/2; i++)
|
||||
{
|
||||
status = FLASH_ProgramHalfWord(offset+i*2,vec[i*2]|(vec[i*2+1]<<8));
|
||||
if( status != FLASH_COMPLETE )
|
||||
{
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
FLASH_Lock();
|
||||
|
||||
return NOERR;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn erase_flash
|
||||
*
|
||||
* @brief erase flash
|
||||
*
|
||||
* @param offset - 地址偏移
|
||||
* @param len - 长度
|
||||
*
|
||||
* @return state
|
||||
*/
|
||||
int erase_flash(int offset, unsigned int len)
|
||||
{
|
||||
FLASH_Status status = FLASH_COMPLETE;
|
||||
if(len != 4096)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
FLASH_Unlock();
|
||||
status = FLASH_ErasePage(offset);
|
||||
FLASH_Lock();
|
||||
if(status == FLASH_COMPLETE)
|
||||
{
|
||||
return NOERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn flash_write_protection
|
||||
*
|
||||
* @brief no used
|
||||
*
|
||||
* @param enable - no uesd
|
||||
*
|
||||
* @return always success
|
||||
*/
|
||||
int flash_write_protection(BOOL enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct device app_dev = {
|
||||
.api = {
|
||||
.read = read_flash,
|
||||
.write = write_flash,
|
||||
.erase = erase_flash,
|
||||
.write_protection = flash_write_protection,
|
||||
},
|
||||
.info = {
|
||||
.nvs_sector_cnt = CONFIG_MESH_SECTOR_COUNT_DEF,
|
||||
.nvs_write_size = sizeof(int),
|
||||
.nvs_sector_size = CONFIG_MESH_SECTOR_SIZE_DEF,
|
||||
.nvs_store_baddr = CONFIG_MESH_NVS_ADDR_DEF,
|
||||
},
|
||||
};
|
||||
|
||||
/******************************** endfile @ main ******************************/
|
||||
@@ -0,0 +1,696 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : app_vendor_model_cli.c
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2022/01/18
|
||||
* 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 "app_mesh_config.h"
|
||||
#include "MESH_LIB.h"
|
||||
#include "app_vendor_model_cli.h"
|
||||
#include "app_vendor_model_srv.h"
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL TYPEDEFS
|
||||
*/
|
||||
|
||||
// 应用层最大发送长度,不分包最大为CONFIG_MESH_UNSEG_LENGTH_DEF,分包最大为CONFIG_MESH_TX_SEG_DEF*BLE_MESH_APP_SEG_SDU_MAX-8(依据RAM使用情况决定)
|
||||
#define APP_MAX_TX_SIZE MAX(CONFIG_MESH_UNSEG_LENGTH_DEF, CONFIG_MESH_TX_SEG_DEF *BLE_MESH_APP_SEG_SDU_MAX - 8)
|
||||
|
||||
static uint8_t vendor_model_cli_TaskID = 0; // Task ID for internal task/event processing
|
||||
static uint8_t cli_send_tid = 0;
|
||||
static int32_t cli_msg_timeout = K_SECONDS(2); //有应答的数据传输超时时间,默认2秒
|
||||
|
||||
static struct net_buf cli_trans_buf;
|
||||
static struct bt_mesh_trans cli_trans = {
|
||||
.buf = &cli_trans_buf,
|
||||
};
|
||||
|
||||
static struct net_buf cli_write_buf;
|
||||
static struct bt_mesh_write cli_write = {
|
||||
.buf = &cli_write_buf,
|
||||
};
|
||||
|
||||
static struct bt_mesh_vendor_model_cli *vendor_model_cli;
|
||||
|
||||
static uint16_t vendor_model_cli_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static void write_reset(struct bt_mesh_write *write, int err);
|
||||
static void adv_cli_trans_send(void);
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_cli_tid_get
|
||||
*
|
||||
* @brief TID selection method
|
||||
*
|
||||
* @return TID
|
||||
*/
|
||||
uint8_t vendor_cli_tid_get(void)
|
||||
{
|
||||
cli_send_tid++;
|
||||
if(cli_send_tid > 127)
|
||||
cli_send_tid = 0;
|
||||
return cli_send_tid;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_model_cli_reset
|
||||
*
|
||||
* @brief 复位厂商模型服务,取消所有正在发送的流程
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void vendor_model_cli_reset(void)
|
||||
{
|
||||
vendor_model_cli->op_pending = 0U;
|
||||
vendor_model_cli->op_req = 0U;
|
||||
|
||||
if(cli_write.buf->__buf)
|
||||
{
|
||||
write_reset(&cli_write, -ECANCELED);
|
||||
}
|
||||
if(cli_trans.buf->__buf)
|
||||
{
|
||||
vendor_message_cli_trans_reset();
|
||||
}
|
||||
|
||||
tmos_stop_task(vendor_model_cli_TaskID, VENDOR_MODEL_CLI_RSP_TIMEOUT_EVT);
|
||||
tmos_stop_task(vendor_model_cli_TaskID, VENDOR_MODEL_CLI_WRITE_EVT);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_model_cli_rsp_recv
|
||||
*
|
||||
* @brief 调用应用层传入的回调
|
||||
*
|
||||
* @param val - 回调参数,包括消息类型、数据内容、长度、来源地址
|
||||
* @param statu - 状态
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void vendor_model_cli_rsp_recv(vendor_model_cli_status_t *val, uint8_t status)
|
||||
{
|
||||
if(vendor_model_cli == NULL || (!vendor_model_cli->op_req))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
val->vendor_model_cli_Hdr.opcode = vendor_model_cli->op_req;
|
||||
val->vendor_model_cli_Hdr.status = status;
|
||||
|
||||
vendor_model_cli_reset();
|
||||
|
||||
if(vendor_model_cli->handler)
|
||||
{
|
||||
vendor_model_cli->handler(val);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_model_cli_wait
|
||||
*
|
||||
* @brief 默认两秒超时后通知应用层
|
||||
*
|
||||
* @return 参考BLE_LIB err code
|
||||
*/
|
||||
static int vendor_model_cli_wait(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = tmos_start_task(vendor_model_cli_TaskID,
|
||||
VENDOR_MODEL_CLI_RSP_TIMEOUT_EVT, cli_msg_timeout);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_model_cli_prepare
|
||||
*
|
||||
* @brief 预发送,记录当前消息类型
|
||||
*
|
||||
* @param op_req - 发出去的消息类型
|
||||
* @param op - 期待收到的消息类型
|
||||
*
|
||||
* @return 错误码
|
||||
*/
|
||||
static int vendor_model_cli_prepare(uint32_t op_req, uint32_t op)
|
||||
{
|
||||
if(!vendor_model_cli)
|
||||
{
|
||||
APP_DBG("No available Configuration Client context!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(vendor_model_cli->op_pending)
|
||||
{
|
||||
APP_DBG("Another synchronous operation pending");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
vendor_model_cli->op_req = op_req;
|
||||
vendor_model_cli->op_pending = op;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_cli_sync_handler
|
||||
*
|
||||
* @brief 通知应用层当前op_code超时了
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void vendor_cli_sync_handler(void)
|
||||
{
|
||||
vendor_model_cli_status_t vendor_model_cli_status;
|
||||
|
||||
tmos_memset(&vendor_model_cli_status, 0, sizeof(vendor_model_cli_status_t));
|
||||
|
||||
write_reset(&cli_write, -ETIMEDOUT);
|
||||
|
||||
vendor_model_cli_rsp_recv(&vendor_model_cli_status, 0xFF);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_message_cli_ack
|
||||
*
|
||||
* @brief 发送vendor_message_cli_ack - 该消息用于Vendor Model Client回复给Vendor Model Server,
|
||||
* 用于表示已收到Vendor Model Server发出的Indication
|
||||
*
|
||||
* @param model - 模型参数.
|
||||
* @param ctx - 数据参数.
|
||||
* @param buf - 数据内容.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void vendor_message_cli_ack(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, APP_MAX_TX_SIZE + 8);
|
||||
uint8_t recv_tid;
|
||||
int err;
|
||||
|
||||
recv_tid = net_buf_simple_pull_u8(buf);
|
||||
|
||||
APP_DBG("tid 0x%02x ", recv_tid);
|
||||
|
||||
/* Init indication opcode */
|
||||
bt_mesh_model_msg_init(&msg, OP_VENDOR_MESSAGE_TRANSPARENT_ACK);
|
||||
|
||||
/* Add tid field */
|
||||
net_buf_simple_add_u8(&msg, recv_tid);
|
||||
|
||||
err = bt_mesh_model_send(model, ctx, &msg, NULL, NULL);
|
||||
if(err)
|
||||
{
|
||||
APP_DBG("#mesh-onoff STATUS: send status failed: %d", err);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_message_cli_trans
|
||||
*
|
||||
* @brief 收到透传数据
|
||||
*
|
||||
* @param model - 模型参数.
|
||||
* @param ctx - 数据参数.
|
||||
* @param buf - 数据内容.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void vendor_message_cli_trans(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
|
||||
{
|
||||
vendor_model_cli_status_t vendor_model_cli_status;
|
||||
uint8_t *pData = buf->data;
|
||||
uint16_t len = buf->len;
|
||||
|
||||
if((pData[0] != vendor_model_cli->cli_tid.trans_tid) ||
|
||||
(ctx->addr != vendor_model_cli->cli_tid.trans_addr))
|
||||
{
|
||||
vendor_model_cli->cli_tid.trans_tid = pData[0];
|
||||
vendor_model_cli->cli_tid.trans_addr = ctx->addr;
|
||||
// 开头为tid
|
||||
pData++;
|
||||
len--;
|
||||
vendor_model_cli_status.vendor_model_cli_Hdr.opcode =
|
||||
OP_VENDOR_MESSAGE_TRANSPARENT_MSG;
|
||||
vendor_model_cli_status.vendor_model_cli_Hdr.status = 0;
|
||||
vendor_model_cli_status.vendor_model_cli_Event.trans.pdata = pData;
|
||||
vendor_model_cli_status.vendor_model_cli_Event.trans.len = len;
|
||||
vendor_model_cli_status.vendor_model_cli_Event.trans.addr = ctx->addr;
|
||||
|
||||
if(vendor_model_cli->handler)
|
||||
{
|
||||
vendor_model_cli->handler(&vendor_model_cli_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_message_cli_ind
|
||||
*
|
||||
* @brief 收到Indication 数据,随后应答vendor_message_cli_ack
|
||||
*
|
||||
* @param model - 模型参数.
|
||||
* @param ctx - 数据参数.
|
||||
* @param buf - 数据内容.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void vendor_message_cli_ind(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
vendor_model_cli_status_t vendor_model_cli_status;
|
||||
uint8_t *pData = buf->data;
|
||||
uint16_t len = buf->len;
|
||||
APP_DBG("src: 0x%04x dst: 0x%04x rssi: %d app_idx: 0x%x", ctx->addr, ctx->recv_dst, ctx->recv_rssi, ctx->app_idx);
|
||||
|
||||
if((pData[0] != vendor_model_cli->cli_tid.ind_tid) ||
|
||||
(ctx->addr != vendor_model_cli->cli_tid.trans_addr))
|
||||
{
|
||||
vendor_model_cli->cli_tid.ind_tid = pData[0];
|
||||
vendor_model_cli->cli_tid.trans_addr = ctx->addr;
|
||||
// 开头为tid
|
||||
pData++;
|
||||
len--;
|
||||
vendor_model_cli_status.vendor_model_cli_Hdr.opcode =
|
||||
OP_VENDOR_MESSAGE_TRANSPARENT_IND;
|
||||
vendor_model_cli_status.vendor_model_cli_Hdr.status = 0;
|
||||
vendor_model_cli_status.vendor_model_cli_Event.ind.pdata = pData;
|
||||
vendor_model_cli_status.vendor_model_cli_Event.ind.len = len;
|
||||
vendor_model_cli_status.vendor_model_cli_Event.ind.addr = ctx->addr;
|
||||
|
||||
if(vendor_model_cli->handler)
|
||||
{
|
||||
vendor_model_cli->handler(&vendor_model_cli_status);
|
||||
}
|
||||
}
|
||||
vendor_message_cli_ack(model, ctx, buf);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_message_cli_cfm
|
||||
*
|
||||
* @brief 收到vendor_message_cli_cfm - 该消息用于Vendor Model Server回复给Vendor Model Client,
|
||||
* 用于表示已收到Vendor Model Client发出的 Write
|
||||
*
|
||||
* @param model - 模型参数.
|
||||
* @param ctx - 数据参数.
|
||||
* @param buf - 数据内容.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void vendor_message_cli_cfm(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
|
||||
{
|
||||
uint8_t recv_tid;
|
||||
vendor_model_cli_status_t vendor_model_cli_status;
|
||||
|
||||
recv_tid = net_buf_simple_pull_u8(buf);
|
||||
|
||||
APP_DBG("src: 0x%04x dst: 0x%04x tid 0x%02x rssi: %d", ctx->addr,
|
||||
ctx->recv_dst, recv_tid, ctx->recv_rssi);
|
||||
|
||||
if(cli_write.param.tid == recv_tid)
|
||||
{
|
||||
write_reset(&cli_write, 0);
|
||||
vendor_model_cli_rsp_recv(&vendor_model_cli_status, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// opcode 对应的处理函数
|
||||
const struct bt_mesh_model_op vnd_model_cli_op[] = {
|
||||
{OP_VENDOR_MESSAGE_TRANSPARENT_MSG, 0, vendor_message_cli_trans},
|
||||
{OP_VENDOR_MESSAGE_TRANSPARENT_IND, 0, vendor_message_cli_ind},
|
||||
{OP_VENDOR_MESSAGE_TRANSPARENT_CFM, 0, vendor_message_cli_cfm},
|
||||
BLE_MESH_MODEL_OP_END,
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_message_cli_send_trans
|
||||
*
|
||||
* @brief send_trans ,透传数据通道
|
||||
*
|
||||
* @param param - 发送参数.
|
||||
* @param pData - 数据指针.
|
||||
* @param len - 数据长度,最大为(APP_MAX_TX_SIZE).
|
||||
*
|
||||
* @return 参考Global_Error_Code
|
||||
*/
|
||||
int vendor_message_cli_send_trans(struct send_param *param, uint8_t *pData,
|
||||
uint16_t len)
|
||||
{
|
||||
if(!param->addr)
|
||||
return -EINVAL;
|
||||
if(cli_trans.buf->__buf)
|
||||
return -EBUSY;
|
||||
if(len > (APP_MAX_TX_SIZE))
|
||||
return -EINVAL;
|
||||
|
||||
cli_trans.buf->__buf = tmos_msg_allocate(len + 8);
|
||||
if(!(cli_trans.buf->__buf))
|
||||
{
|
||||
APP_DBG("No enough space!");
|
||||
return -ENOMEM;
|
||||
}
|
||||
cli_trans.buf->size = len + 4;
|
||||
/* Init indication opcode */
|
||||
bt_mesh_model_msg_init(&(cli_trans.buf->b), OP_VENDOR_MESSAGE_TRANSPARENT_MSG);
|
||||
|
||||
/* Add tid field */
|
||||
net_buf_simple_add_u8(&(cli_trans.buf->b), param->tid);
|
||||
|
||||
net_buf_simple_add_mem(&(cli_trans.buf->b), pData, len);
|
||||
|
||||
memcpy(&cli_trans.param, param, sizeof(struct send_param));
|
||||
|
||||
if(param->rand)
|
||||
{
|
||||
// 延迟发送
|
||||
tmos_start_task(vendor_model_cli_TaskID, VENDOR_MODEL_CLI_TRANS_EVT, param->rand);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 直接发送
|
||||
adv_cli_trans_send();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_message_cli_write
|
||||
*
|
||||
* @brief write ,有应答传输数据通道
|
||||
*
|
||||
* @param param - 发送参数.
|
||||
* @param pData - 数据指针.
|
||||
* @param len - 数据长度,最大为(APP_MAX_TX_SIZE).
|
||||
*
|
||||
* @return 参考Global_Error_Code
|
||||
*/
|
||||
int vendor_message_cli_write(struct send_param *param, uint8_t *pData, uint16_t len)
|
||||
{
|
||||
if(!param->addr)
|
||||
return -EINVAL;
|
||||
if(cli_write.buf->__buf)
|
||||
return -EBUSY;
|
||||
if(len > (APP_MAX_TX_SIZE))
|
||||
return -EINVAL;
|
||||
|
||||
cli_write.buf->__buf = tmos_msg_allocate(len + 8);
|
||||
if(!(cli_write.buf->__buf))
|
||||
{
|
||||
APP_DBG("No enough space!");
|
||||
return -ENOMEM;
|
||||
}
|
||||
cli_write.buf->size = len + 4;
|
||||
/* Init indication opcode */
|
||||
bt_mesh_model_msg_init(&(cli_write.buf->b),
|
||||
OP_VENDOR_MESSAGE_TRANSPARENT_WRT);
|
||||
|
||||
/* Add tid field */
|
||||
net_buf_simple_add_u8(&(cli_write.buf->b), param->tid);
|
||||
|
||||
net_buf_simple_add_mem(&(cli_write.buf->b), pData, len);
|
||||
|
||||
memcpy(&cli_write.param, param, sizeof(struct send_param));
|
||||
|
||||
vendor_model_cli_prepare(OP_VENDOR_MESSAGE_TRANSPARENT_WRT,
|
||||
OP_VENDOR_MESSAGE_TRANSPARENT_CFM);
|
||||
|
||||
tmos_start_task(vendor_model_cli_TaskID, VENDOR_MODEL_CLI_WRITE_EVT,
|
||||
param->rand);
|
||||
|
||||
vendor_model_cli_wait();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn adv_cli_trans_send
|
||||
*
|
||||
* @brief 发送 透传 cli_trans
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void adv_cli_trans_send(void)
|
||||
{
|
||||
int err;
|
||||
NET_BUF_SIMPLE_DEFINE(msg, APP_MAX_TX_SIZE + 8);
|
||||
|
||||
struct bt_mesh_msg_ctx ctx = {
|
||||
.net_idx = cli_trans.param.net_idx ? cli_trans.param.net_idx : BLE_MESH_KEY_ANY,
|
||||
.app_idx = cli_trans.param.app_idx ? cli_trans.param.app_idx : vendor_model_cli->model->keys[0],
|
||||
.addr = cli_trans.param.addr,
|
||||
};
|
||||
|
||||
if(cli_trans.buf->__buf == NULL)
|
||||
{
|
||||
APP_DBG("NULL buf");
|
||||
return;
|
||||
}
|
||||
|
||||
if(cli_trans.param.trans_cnt == 0)
|
||||
{
|
||||
// APP_DBG("cli_trans.buf.trans_cnt over");
|
||||
tmos_msg_deallocate(cli_trans.buf->__buf);
|
||||
cli_trans.buf->__buf = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
cli_trans.param.trans_cnt--;
|
||||
|
||||
ctx.send_ttl = cli_trans.param.send_ttl;
|
||||
|
||||
/** TODO */
|
||||
net_buf_simple_add_mem(&msg, cli_trans.buf->data, cli_trans.buf->len);
|
||||
|
||||
err = bt_mesh_model_send(vendor_model_cli->model, &ctx, &msg, NULL, NULL);
|
||||
if(err)
|
||||
{
|
||||
APP_DBG("Unable send model message (err:%d)", err);
|
||||
tmos_msg_deallocate(cli_trans.buf->__buf);
|
||||
cli_trans.buf->__buf = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(cli_trans.param.trans_cnt == 0)
|
||||
{
|
||||
// APP_DBG("cli_trans.buf.trans_cnt over");
|
||||
tmos_msg_deallocate(cli_trans.buf->__buf);
|
||||
cli_trans.buf->__buf = NULL;
|
||||
return;
|
||||
}
|
||||
// 重传
|
||||
tmos_start_task(vendor_model_cli_TaskID, VENDOR_MODEL_CLI_TRANS_EVT,
|
||||
cli_trans.param.period);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_message_cli_trans_reset
|
||||
*
|
||||
* @brief 取消发送trans数据的任务,释放缓存
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void vendor_message_cli_trans_reset(void)
|
||||
{
|
||||
tmos_msg_deallocate(cli_trans.buf->__buf);
|
||||
cli_trans.buf->__buf = NULL;
|
||||
tmos_stop_task(vendor_model_cli_TaskID, VENDOR_MODEL_CLI_TRANS_EVT);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn write_reset
|
||||
*
|
||||
* @brief 调用write发送完成回调,释放缓存
|
||||
*
|
||||
* @param write - 需要释放的write.
|
||||
* @param err - 错误状态.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void write_reset(struct bt_mesh_write *write, int err)
|
||||
{
|
||||
if(write->param.cb && write->param.cb->end)
|
||||
{
|
||||
write->param.cb->end(err, write->param.cb_data);
|
||||
}
|
||||
|
||||
tmos_msg_deallocate(write->buf->__buf);
|
||||
write->buf->__buf = NULL;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn write_start
|
||||
*
|
||||
* @brief 发送 write 开始回调
|
||||
*
|
||||
* @param duration - 此次发送持续的时长(ms).
|
||||
* @param err - 错误状态.
|
||||
* @param cb_data - 错误状态发送时填写的回调参数.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void write_start(uint16_t duration, int err, void *cb_data)
|
||||
{
|
||||
struct bt_mesh_write *write = cb_data;
|
||||
|
||||
if(write->buf->__buf == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(err)
|
||||
{
|
||||
APP_DBG("Unable send indicate (err:%d)", err);
|
||||
tmos_start_task(vendor_model_cli_TaskID, VENDOR_MODEL_CLI_WRITE_EVT,
|
||||
K_MSEC(100));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn write_end
|
||||
*
|
||||
* @brief 发送 write 结束回调
|
||||
*
|
||||
* @param err - 错误状态.
|
||||
* @param cb_data - 错误状态发送时填写的回调参数.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void write_end(int err, void *cb_data)
|
||||
{
|
||||
struct bt_mesh_write *write = cb_data;
|
||||
APP_DBG("write_end (err:%d)", err);
|
||||
|
||||
if(write->buf->__buf == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
tmos_start_task(vendor_model_cli_TaskID, VENDOR_MODEL_CLI_WRITE_EVT,
|
||||
write->param.period);
|
||||
}
|
||||
|
||||
// 发送 indicate 回调结构体
|
||||
const struct bt_mesh_send_cb write_cb = {
|
||||
.start = write_start,
|
||||
.end = write_end,
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* @fn adv_cli_write_send
|
||||
*
|
||||
* @brief 发送 cli_write
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void adv_cli_write_send(void)
|
||||
{
|
||||
int err;
|
||||
NET_BUF_SIMPLE_DEFINE(msg, APP_MAX_TX_SIZE + 8);
|
||||
|
||||
struct bt_mesh_msg_ctx ctx = {
|
||||
.net_idx = cli_write.param.net_idx ? cli_write.param.net_idx : BLE_MESH_KEY_ANY,
|
||||
.app_idx = cli_write.param.app_idx ? cli_write.param.app_idx : vendor_model_cli->model->keys[0],
|
||||
.addr = cli_write.param.addr,
|
||||
};
|
||||
|
||||
if(cli_write.buf->__buf == NULL)
|
||||
{
|
||||
APP_DBG("NULL buf");
|
||||
return;
|
||||
}
|
||||
|
||||
if(cli_write.param.trans_cnt == 0)
|
||||
{
|
||||
// APP_DBG("cli_write.buf.trans_cnt over");
|
||||
write_reset(&cli_write, -ETIMEDOUT);
|
||||
return;
|
||||
}
|
||||
|
||||
cli_write.param.trans_cnt--;
|
||||
|
||||
ctx.send_ttl = cli_write.param.send_ttl;
|
||||
|
||||
/** TODO */
|
||||
net_buf_simple_add_mem(&msg, cli_write.buf->data, cli_write.buf->len);
|
||||
|
||||
err = bt_mesh_model_send(vendor_model_cli->model, &ctx, &msg, &write_cb,
|
||||
&cli_write);
|
||||
if(err)
|
||||
{
|
||||
APP_DBG("Unable send model message (err:%d)", err);
|
||||
|
||||
write_reset(&cli_write, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_model_cli_init
|
||||
*
|
||||
* @brief 厂商模型初始化
|
||||
*
|
||||
* @param model - 指向厂商模型结构体
|
||||
*
|
||||
* @return always SUCCESS
|
||||
*/
|
||||
int vendor_model_cli_init(struct bt_mesh_model *model)
|
||||
{
|
||||
vendor_model_cli = model->user_data;
|
||||
vendor_model_cli->model = model;
|
||||
|
||||
vendor_model_cli_TaskID = TMOS_ProcessEventRegister(vendor_model_cli_ProcessEvent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn vendor_model_cli_ProcessEvent
|
||||
*
|
||||
* @brief 厂商模型事件处理函数
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
static uint16_t vendor_model_cli_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & VENDOR_MODEL_CLI_TRANS_EVT)
|
||||
{
|
||||
adv_cli_trans_send();
|
||||
return (events ^ VENDOR_MODEL_CLI_TRANS_EVT);
|
||||
}
|
||||
if(events & VENDOR_MODEL_CLI_RSP_TIMEOUT_EVT)
|
||||
{
|
||||
vendor_cli_sync_handler();
|
||||
return (events ^ VENDOR_MODEL_CLI_RSP_TIMEOUT_EVT);
|
||||
}
|
||||
if(events & VENDOR_MODEL_CLI_WRITE_EVT)
|
||||
{
|
||||
adv_cli_write_send();
|
||||
return (events ^ VENDOR_MODEL_CLI_WRITE_EVT);
|
||||
}
|
||||
// Discard unknown events
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************** endfile @ main ******************************/
|
||||
@@ -0,0 +1,61 @@
|
||||
/********************************** (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")));
|
||||
|
||||
/*********************************************************************
|
||||
* @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();
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : app.h
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2021/11/18
|
||||
* 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 app_H
|
||||
#define app_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#define APP_NODE_EVT (1 << 0)
|
||||
#define APP_NODE_TEST_EVT (1 << 1)
|
||||
#define APP_DELETE_NODE_TIMEOUT_EVT (1 << 2)
|
||||
|
||||
#define CMD_DELETE_NODE 0xA2
|
||||
#define CMD_DELETE_NODE_ACK 0x82
|
||||
|
||||
#define PERIPHERAL_CMD_LEN 1
|
||||
#define ADDRESS_LEN 2
|
||||
|
||||
// 删除节点命令,包含 1字节命令码+2字节需要删除的节点地址
|
||||
#define DELETE_NODE_DATA_LEN (PERIPHERAL_CMD_LEN + ADDRESS_LEN)
|
||||
// 删除节点命令应答,包含 1字节命令码
|
||||
#define DELETE_NODE_ACK_DATA_LEN (PERIPHERAL_CMD_LEN)
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief 远端节点配置流程状态
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NODE_INIT = 0,
|
||||
NODE_APPKEY_ADD = 1,
|
||||
NODE_MOD_BIND_SET = 2,
|
||||
NODE_MOD_SUB_SET = 3,
|
||||
|
||||
NODE_CONFIGURATIONED = 4,
|
||||
} node_stage_t;
|
||||
|
||||
/**
|
||||
* @brief 本地节点配置流程状态
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LOCAL_INIT = 0,
|
||||
LOCAL_APPKEY_ADD = 1,
|
||||
LOCAL_MOD_BIND_SET = 2,
|
||||
|
||||
LOCAL_CONFIGURATIONED = 4,
|
||||
} local_stage_t;
|
||||
|
||||
/**
|
||||
* @brief 节点配置流程组合体
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
node_stage_t node;
|
||||
local_stage_t local;
|
||||
} stage_t;
|
||||
|
||||
typedef void (*cfg_rsp_handler_t)(void *node, const void *rsp);
|
||||
typedef BOOL (*stage_handler_t)(void *node);
|
||||
|
||||
/**
|
||||
* @brief 节点配置流程回调
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
cfg_rsp_handler_t rsp;
|
||||
stage_handler_t stage;
|
||||
} cfg_cb_t;
|
||||
|
||||
/**
|
||||
* @brief 配置节点的结构体
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t node_addr;
|
||||
uint16_t elem_count;
|
||||
uint16_t net_idx;
|
||||
uint16_t retry_cnt : 12,
|
||||
fixed : 1,
|
||||
blocked : 1;
|
||||
|
||||
stage_t stage;
|
||||
const cfg_cb_t *cb;
|
||||
} node_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t cmd; /* 命令码 CMD_DELETE_NODE */
|
||||
uint8_t addr[ADDRESS_LEN]; /* 擦除地址 */
|
||||
} delete_node; /* 删除节点命令 */
|
||||
struct
|
||||
{
|
||||
uint8_t cmd; /* 命令码 CMD_DELETE_NODE_ACK */
|
||||
} delete_node_ack; /* 删除节点命令应答 */
|
||||
struct
|
||||
{
|
||||
uint8_t buf[20]; /* 接收数据包*/
|
||||
} data;
|
||||
}app_mesh_manage_t;
|
||||
|
||||
extern node_t app_nodes[1 + CONFIG_MESH_PROV_NODE_COUNT_DEF];
|
||||
extern const uint16_t self_prov_net_idx;
|
||||
extern const uint16_t self_prov_app_idx;
|
||||
extern const uint32_t self_prov_iv_index;
|
||||
extern const uint16_t self_prov_addr;
|
||||
|
||||
/**
|
||||
* @brief 应用层初始化
|
||||
*/
|
||||
void App_Init(void);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,219 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : app_mesh_config.h
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2021/11/18
|
||||
* 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 APP_MESH_CONFIG_H
|
||||
#define APP_MESH_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/**************************功能配置,建议直接参考不同例程*****************************/
|
||||
|
||||
// relay功能
|
||||
#define CONFIG_BLE_MESH_RELAY 1
|
||||
// 代理功能
|
||||
#define CONFIG_BLE_MESH_PROXY 0
|
||||
// GATT层配网功能
|
||||
#define CONFIG_BLE_MESH_PB_GATT 0
|
||||
// FLASH存储功能
|
||||
#define CONFIG_BLE_MESH_SETTINGS 1
|
||||
// 朋友节点功能
|
||||
#define CONFIG_BLE_MESH_FRIEND 0
|
||||
// 低功耗节点功能
|
||||
#define CONFIG_BLE_MESH_LOW_POWER 0
|
||||
// config模型客户端功能
|
||||
#define CONFIG_BLE_MESH_CFG_CLI 1
|
||||
// health模型客户端功能
|
||||
#define CONFIG_BLE_MESH_HLTH_CLI 1
|
||||
|
||||
/************************************参数配置******************************************/
|
||||
|
||||
// Net数据缓存个数
|
||||
#define CONFIG_MESH_ADV_BUF_COUNT_MIN (6)
|
||||
#define CONFIG_MESH_ADV_BUF_COUNT_DEF (10)
|
||||
#define CONFIG_MESH_ADV_BUF_COUNT_MAX (256)
|
||||
|
||||
// RPL数据缓存个数,需不小于配网发起者支持的配网设备节点个数
|
||||
#define CONFIG_MESH_RPL_COUNT_MIN (6)
|
||||
#define CONFIG_MESH_RPL_COUNT_DEF (40)
|
||||
#define CONFIG_MESH_RPL_COUNT_MAX (128)
|
||||
|
||||
// RPL缓存循环使用,开启后网络中节点数量不受RPL限制,但NVS将不存储RPL数据
|
||||
#define CONFIG_MESH_ALLOW_RPL_CYCLE (FALSE)
|
||||
|
||||
// IV Update State Timer 基于96H的分频系数
|
||||
#define CONFIG_MESH_IVU_DIVIDER_MIN (1)
|
||||
#define CONFIG_MESH_IVU_DIVIDER_DEF (96)
|
||||
#define CONFIG_MESH_IVU_DIVIDER_MAX (96)
|
||||
|
||||
// 代理黑白名单功能存储个数
|
||||
#define CONFIG_MESH_PROXY_FILTER_MIN (2)
|
||||
#define CONFIG_MESH_PROXY_FILTER_DEF (5)
|
||||
#define CONFIG_MESH_PROXY_FILTER_MAX (20)
|
||||
|
||||
// 消息贮存个数
|
||||
#define CONFIG_MESH_MSG_CACHE_MIN (3)
|
||||
#define CONFIG_MESH_MSG_CACHE_DEF (20)
|
||||
#define CONFIG_MESH_MSG_CACHE_MAX (20)
|
||||
|
||||
// 子网络个数
|
||||
#define CONFIG_MESH_SUBNET_COUNT_MIN (1)
|
||||
#define CONFIG_MESH_SUBNET_COUNT_DEF (1)
|
||||
#define CONFIG_MESH_SUBNET_COUNT_MAX (4)
|
||||
|
||||
// APP key个数
|
||||
#define CONFIG_MESH_APPKEY_COUNT_MIN (1)
|
||||
#define CONFIG_MESH_APPKEY_COUNT_DEF (3)
|
||||
#define CONFIG_MESH_APPKEY_COUNT_MAX (5)
|
||||
|
||||
// 可存储的模型密钥数量
|
||||
#define CONFIG_MESH_MOD_KEY_COUNT_MIN (1)
|
||||
#define CONFIG_MESH_MOD_KEY_COUNT_DEF (1)
|
||||
#define CONFIG_MESH_MOD_KEY_COUNT_MAX (3)
|
||||
|
||||
// 可存储的订阅地址数量
|
||||
#define CONFIG_MESH_MOD_GROUP_COUNT_MIN (1)
|
||||
#define CONFIG_MESH_MOD_GROUP_COUNT_DEF (6)
|
||||
#define CONFIG_MESH_MOD_GROUP_COUNT_MAX (64)
|
||||
|
||||
// 是否允许一个网络中存在同地址的节点(使能后分包功能不可用)
|
||||
#define CONFIG_MESH_ALLOW_SAME_ADDR (FALSE)
|
||||
|
||||
// 不分包消息支持的长度(超过此长度则需要分包,默认值为7,注意同网络里所有设备配置需统一)
|
||||
#define CONFIG_MESH_UNSEG_LENGTH_MIN (7)
|
||||
#define CONFIG_MESH_UNSEG_LENGTH_DEF (221)
|
||||
#define CONFIG_MESH_UNSEG_LENGTH_MAX (221)
|
||||
|
||||
// 每个消息的最大分包数
|
||||
#define CONFIG_MESH_TX_SEG_MIN (2)
|
||||
#define CONFIG_MESH_TX_SEG_DEF (8)
|
||||
#define CONFIG_MESH_TX_SEG_MAX (32)
|
||||
|
||||
// 允许同时存在的分包消息的最大发送个数
|
||||
#define CONFIG_MESH_TX_SEG_COUNT_MIN (1)
|
||||
#define CONFIG_MESH_TX_SEG_COUNT_DEF (2)
|
||||
#define CONFIG_MESH_TX_SEG_COUNT_MAX (4)
|
||||
|
||||
// 允许同时存在的分包消息的最大接收个数
|
||||
#define CONFIG_MESH_RX_SEG_COUNT_MIN (1)
|
||||
#define CONFIG_MESH_RX_SEG_COUNT_DEF (2)
|
||||
#define CONFIG_MESH_RX_SEG_COUNT_MAX (4)
|
||||
|
||||
// 每个接收的分包消息的最大字节数
|
||||
#define CONFIG_MESH_RX_SDU_MIN (12)
|
||||
#define CONFIG_MESH_RX_SDU_DEF (192)
|
||||
#define CONFIG_MESH_RX_SDU_MAX (384)
|
||||
|
||||
// 虚拟地址个数
|
||||
#define CONFIG_MESH_LABEL_COUNT_MIN (1)
|
||||
#define CONFIG_MESH_LABEL_COUNT_DEF (2)
|
||||
#define CONFIG_MESH_LABEL_COUNT_MAX (4)
|
||||
|
||||
// NVS存储使用扇区个数
|
||||
#define CONFIG_MESH_SECTOR_COUNT_MIN (2)
|
||||
#define CONFIG_MESH_SECTOR_COUNT_DEF (3)
|
||||
|
||||
// NVS存储扇区大小
|
||||
#define CONFIG_MESH_SECTOR_SIZE_DEF (4096)
|
||||
|
||||
// NVS存储首地址
|
||||
#define CONFIG_MESH_NVS_ADDR_DEF (448*1024+0x08000000)
|
||||
|
||||
// RPL更新超过多少次后存储
|
||||
#define CONFIG_MESH_RPL_STORE_RATE_MIN (5)
|
||||
#define CONFIG_MESH_RPL_STORE_RATE_DEF (60)
|
||||
#define CONFIG_MESH_RPL_STORE_RATE_MAX (3600)
|
||||
|
||||
// SEQ更新超过多少次后存储
|
||||
#define CONFIG_MESH_SEQ_STORE_RATE_MIN (5)
|
||||
#define CONFIG_MESH_SEQ_STORE_RATE_DEF (60)
|
||||
#define CONFIG_MESH_SEQ_STORE_RATE_MAX (3600)
|
||||
|
||||
// 其他信息更新后存储的超时时长(s)
|
||||
#define CONFIG_MESH_STORE_RATE_MIN (2)
|
||||
#define CONFIG_MESH_STORE_RATE_DEF (2)
|
||||
#define CONFIG_MESH_STORE_RATE_MAX (5)
|
||||
|
||||
// 朋友节点支持的每个消息的分包个数
|
||||
#define CONFIG_MESH_FRIEND_SEG_RX_COUNT_MIN (1)
|
||||
#define CONFIG_MESH_FRIEND_SEG_RX_COUNT_DEF (2)
|
||||
#define CONFIG_MESH_FRIEND_SEG_RX_COUNT_MAX (4)
|
||||
|
||||
// 朋友节点支持的订阅个数
|
||||
#define CONFIG_MESH_FRIEND_SUB_SIZE_MIN (1)
|
||||
#define CONFIG_MESH_FRIEND_SUB_SIZE_DEF (4)
|
||||
#define CONFIG_MESH_FRIEND_SUB_SIZE_MAX (8)
|
||||
|
||||
// 朋友节点支持的低功耗节点个数
|
||||
#define CONFIG_MESH_FRIEND_LPN_COUNT_MIN (1)
|
||||
#define CONFIG_MESH_FRIEND_LPN_COUNT_DEF (1)
|
||||
#define CONFIG_MESH_FRIEND_LPN_COUNT_MAX (4)
|
||||
|
||||
// 朋友节点存储的消息队列大小
|
||||
#define CONFIG_MESH_QUEUE_SIZE_MIN (2)
|
||||
#define CONFIG_MESH_QUEUE_SIZE_DEF (4)
|
||||
#define CONFIG_MESH_QUEUE_SIZE_MAX (30)
|
||||
|
||||
// 朋友节点接收窗口大小(ms)
|
||||
#define CONFIG_MESH_FRIEND_RECV_WIN_MIN (1)
|
||||
#define CONFIG_MESH_FRIEND_RECV_WIN_DEF (30)
|
||||
#define CONFIG_MESH_FRIEND_RECV_WIN_MAX (255)
|
||||
|
||||
// 低功耗节点的请求消息队列大小(log2(N)),例配置为4,则大小为2^4=16
|
||||
#define CONFIG_MESH_LPN_REQ_QUEUE_SIZE_MIN (2)
|
||||
#define CONFIG_MESH_LPN_REQ_QUEUE_SIZE_DEF (2)
|
||||
#define CONFIG_MESH_LPN_REQ_QUEUE_SIZE_MAX (4)
|
||||
|
||||
// 低功耗节点的请求消息间隔(100ms)
|
||||
#define CONFIG_MESH_LPN_POLLINTERVAL_MIN (1)
|
||||
#define CONFIG_MESH_LPN_POLLINTERVAL_DEF (80)
|
||||
#define CONFIG_MESH_LPN_POLLINTERVAL_MAX (3455999)
|
||||
|
||||
// 低功耗节点的请求消息超时时长(100ms)
|
||||
#define CONFIG_MESH_LPN_POLLTIMEOUT_MIN (10)
|
||||
#define CONFIG_MESH_LPN_POLLTIMEOUT_DEF (300)
|
||||
#define CONFIG_MESH_LPN_POLLTIMEOUT_MAX (3455999)
|
||||
|
||||
// 低功耗节点支持的接收延迟(ms)
|
||||
#define CONFIG_MESH_LPN_RECV_DELAY_MIN (10)
|
||||
#define CONFIG_MESH_LPN_RECV_DELAY_DEF (100)
|
||||
#define CONFIG_MESH_LPN_RECV_DELAY_MAX (255)
|
||||
|
||||
// 朋友关系重建等待时长(s)
|
||||
#define CONFIG_MESH_RETRY_TIMEOUT_MIN (3)
|
||||
#define CONFIG_MESH_RETRY_TIMEOUT_DEF (10)
|
||||
#define CONFIG_MESH_RETRY_TIMEOUT_MAX (60)
|
||||
|
||||
// 配网发起者支持的配网设备节点个数
|
||||
#define CONFIG_MESH_PROV_NODE_COUNT_DEF (40)
|
||||
|
||||
// ADV_RF配置
|
||||
#define CONFIG_MESH_RF_ACCESSADDRESS (0x8E89BED6)
|
||||
#define CONFIG_MESH_RF_CHANNEL_37 (37)
|
||||
#define CONFIG_MESH_RF_CHANNEL_38 (38)
|
||||
#define CONFIG_MESH_RF_CHANNEL_39 (39)
|
||||
|
||||
#define APP_DBG(X...) \
|
||||
if(1) \
|
||||
{ \
|
||||
PRINT("APP_DBG %s> ", __FUNCTION__); \
|
||||
PRINT(X); \
|
||||
PRINT("\n"); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,161 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : app_generic_onoff_model_cli.h
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2021/11/18
|
||||
* 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 app_generic_onoff_model_cli_H
|
||||
#define app_generic_onoff_model_cli_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_vendor_model_srv.h"
|
||||
|
||||
#define CID_WCH 0x07D7
|
||||
|
||||
#define OP_VENDOR_MESSAGE_TRANSPARENT_CFM BLE_MESH_MODEL_OP_3(0xCB, CID_WCH)
|
||||
#define OP_VENDOR_MESSAGE_TRANSPARENT_WRT BLE_MESH_MODEL_OP_3(0xCC, CID_WCH)
|
||||
#define OP_VENDOR_MESSAGE_TRANSPARENT_ACK BLE_MESH_MODEL_OP_3(0xCD, CID_WCH)
|
||||
#define OP_VENDOR_MESSAGE_TRANSPARENT_IND BLE_MESH_MODEL_OP_3(0xCE, CID_WCH)
|
||||
#define OP_VENDOR_MESSAGE_TRANSPARENT_MSG BLE_MESH_MODEL_OP_3(0xCF, CID_WCH)
|
||||
|
||||
#define BLE_MESH_MODEL_ID_WCH_SRV 0x0000
|
||||
#define BLE_MESH_MODEL_ID_WCH_CLI 0x0001
|
||||
|
||||
#define VENDOR_MODEL_CLI_TRANS_EVT (1 << 0)
|
||||
#define VENDOR_MODEL_CLI_RSP_TIMEOUT_EVT (1 << 1)
|
||||
#define VENDOR_MODEL_CLI_WRITE_EVT (1 << 2)
|
||||
|
||||
/**
|
||||
* @brief indicate 回调结构体
|
||||
*/
|
||||
struct bt_mesh_vendor_model_ind
|
||||
{
|
||||
uint8_t *pdata;
|
||||
uint16_t len;
|
||||
uint16_t addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief trans 回调结构体
|
||||
*/
|
||||
struct bt_mesh_vendor_model_cli_trans
|
||||
{
|
||||
uint8_t *pdata;
|
||||
uint16_t len;
|
||||
uint16_t addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Client event header
|
||||
*/
|
||||
struct vendor_model_cli_EventHdr
|
||||
{
|
||||
uint8_t status;
|
||||
uint32_t opcode;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Client event union
|
||||
*/
|
||||
union vendor_model_cli_Event_t
|
||||
{
|
||||
struct bt_mesh_vendor_model_cli_trans trans;
|
||||
struct bt_mesh_vendor_model_ind ind;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Client event struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct vendor_model_cli_EventHdr vendor_model_cli_Hdr;
|
||||
union vendor_model_cli_Event_t vendor_model_cli_Event;
|
||||
} vendor_model_cli_status_t;
|
||||
|
||||
typedef void (*vendor_model_cli_rsp_handler_t)(const vendor_model_cli_status_t *val);
|
||||
|
||||
/**
|
||||
* @brief 记录当前发送数据包的tid
|
||||
*/
|
||||
struct vendor_model_cli_tid
|
||||
{
|
||||
uint8_t trans_tid;
|
||||
uint16_t trans_addr;
|
||||
uint8_t ind_tid;
|
||||
uint16_t ind_addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Mesh vendor_model_cli Model Context
|
||||
*/
|
||||
struct bt_mesh_vendor_model_cli
|
||||
{
|
||||
struct bt_mesh_model *model;
|
||||
uint32_t op_req;
|
||||
uint32_t op_pending;
|
||||
struct vendor_model_cli_tid cli_tid;
|
||||
|
||||
vendor_model_cli_rsp_handler_t handler;
|
||||
};
|
||||
|
||||
extern const struct bt_mesh_model_op vnd_model_cli_op[];
|
||||
extern const struct bt_mesh_model_cb bt_mesh_vendor_model_cli_cb;
|
||||
|
||||
/**
|
||||
* @brief send_trans,透传数据通道
|
||||
*
|
||||
* @param param - 发送参数.
|
||||
* @param pData - 数据指针.
|
||||
* @param len - 数据长度,最大为(APP_MAX_TX_SIZE).
|
||||
*
|
||||
* @return 参考Global_Error_Code
|
||||
*/
|
||||
int vendor_message_cli_send_trans(struct send_param *param, uint8_t *pData, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief write,有应答传输数据通道
|
||||
*
|
||||
* @param param - 发送参数.
|
||||
* @param pData - 数据指针.
|
||||
* @param len - 数据长度,最大为(APP_MAX_TX_SIZE).
|
||||
*
|
||||
* @return 参考Global_Error_Code
|
||||
*/
|
||||
int vendor_message_cli_write(struct send_param *param, uint8_t *pData, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief TID selection method
|
||||
*
|
||||
* @return TID
|
||||
*/
|
||||
uint8_t vendor_cli_tid_get(void);
|
||||
|
||||
/**
|
||||
* @brief 复位厂商模型服务,取消所有正在发送的流程
|
||||
*/
|
||||
void vendor_message_cli_trans_reset(void);
|
||||
|
||||
/**
|
||||
* @brief 厂商模型初始化
|
||||
*
|
||||
* @param model - 指向厂商模型结构体
|
||||
*
|
||||
* @return always SUCCESS
|
||||
*/
|
||||
int vendor_model_cli_init(struct bt_mesh_model *model);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,232 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : app_vendor_model_srv.h
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2021/11/18
|
||||
* 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 app_vendor_model_srv_H
|
||||
#define app_vendor_model_srv_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "MESH_LIB.h"
|
||||
|
||||
#define MSG_PIN GPIO_Pin_14
|
||||
#define MSG_PCENR RCC_APB2Periph_GPIOB
|
||||
#define MSG_GPIO GPIOB
|
||||
|
||||
#define CID_WCH 0x07D7
|
||||
|
||||
#define OP_VENDOR_MESSAGE_TRANSPARENT_CFM BLE_MESH_MODEL_OP_3(0xCB, CID_WCH)
|
||||
#define OP_VENDOR_MESSAGE_TRANSPARENT_WRT BLE_MESH_MODEL_OP_3(0xCC, CID_WCH)
|
||||
#define OP_VENDOR_MESSAGE_TRANSPARENT_ACK BLE_MESH_MODEL_OP_3(0xCD, CID_WCH)
|
||||
#define OP_VENDOR_MESSAGE_TRANSPARENT_IND BLE_MESH_MODEL_OP_3(0xCE, CID_WCH)
|
||||
#define OP_VENDOR_MESSAGE_TRANSPARENT_MSG BLE_MESH_MODEL_OP_3(0xCF, CID_WCH)
|
||||
|
||||
#define BLE_MESH_MODEL_ID_WCH_SRV 0x0000
|
||||
#define BLE_MESH_MODEL_ID_WCH_CLI 0x0001
|
||||
|
||||
#define VENDOR_MODEL_SRV_TRANS_EVT (1 << 0)
|
||||
#define VENDOR_MODEL_SRV_RSP_TIMEOUT_EVT (1 << 1)
|
||||
#define VENDOR_MODEL_SRV_INDICATE_EVT (1 << 2)
|
||||
|
||||
/**
|
||||
* @brief 发送数据的开始和结束回调函数定义
|
||||
*/
|
||||
struct bt_adv_trans_cb
|
||||
{
|
||||
void (*start)(int err, void *cb_data);
|
||||
void (*end)(int err, void *cb_data);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 发送参数结构体
|
||||
*/
|
||||
struct send_param
|
||||
{
|
||||
uint16_t net_idx;
|
||||
uint16_t app_idx;
|
||||
uint16_t addr;
|
||||
uint8_t tid;
|
||||
uint8_t trans_cnt;
|
||||
int32_t period;
|
||||
int32_t rand;
|
||||
uint8_t send_ttl;
|
||||
|
||||
void *cb_data;
|
||||
const struct bt_adv_trans_cb *cb;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief indicate 发送缓存
|
||||
*/
|
||||
struct bt_mesh_indicate
|
||||
{
|
||||
struct send_param param;
|
||||
struct net_buf *buf;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief trans 发送缓存
|
||||
*/
|
||||
struct bt_mesh_trans
|
||||
{
|
||||
struct send_param param;
|
||||
struct net_buf *buf;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief write 发送缓存
|
||||
*/
|
||||
struct bt_mesh_write
|
||||
{
|
||||
struct send_param param;
|
||||
struct net_buf *buf;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief write 回调结构体
|
||||
*/
|
||||
struct bt_mesh_vendor_model_write
|
||||
{
|
||||
uint8_t *pdata;
|
||||
uint16_t len;
|
||||
uint16_t addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief srv_trans 回调结构体
|
||||
*/
|
||||
struct bt_mesh_vendor_model_srv_trans
|
||||
{
|
||||
uint8_t *pdata;
|
||||
uint16_t len;
|
||||
uint16_t addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Event header
|
||||
*/
|
||||
struct vendor_model_srv_EventHdr
|
||||
{
|
||||
uint8_t status;
|
||||
uint32_t opcode;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Server event union
|
||||
*/
|
||||
union vendor_model_srv_Event_t
|
||||
{
|
||||
struct bt_mesh_vendor_model_srv_trans trans;
|
||||
struct bt_mesh_vendor_model_write write;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Server event struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct vendor_model_srv_EventHdr vendor_model_srv_Hdr;
|
||||
union vendor_model_srv_Event_t vendor_model_srv_Event;
|
||||
} vendor_model_srv_status_t;
|
||||
|
||||
typedef void (*vendor_model_srv_rsp_handler_t)(const vendor_model_srv_status_t *val);
|
||||
|
||||
/**
|
||||
* @brief 记录当前发送数据包的tid
|
||||
*/
|
||||
struct vendor_model_srv_tid
|
||||
{
|
||||
uint8_t trans_tid;
|
||||
uint16_t trans_addr;
|
||||
uint8_t write_tid;
|
||||
uint16_t write_addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Mesh vendor_model_srv Model Context
|
||||
*/
|
||||
struct bt_mesh_vendor_model_srv
|
||||
{
|
||||
struct bt_mesh_model *model;
|
||||
uint32_t op_req;
|
||||
uint32_t op_pending;
|
||||
struct vendor_model_srv_tid srv_tid;
|
||||
vendor_model_srv_rsp_handler_t handler;
|
||||
};
|
||||
|
||||
extern const struct bt_mesh_model_cb bt_mesh_vendor_model_srv_cb;
|
||||
extern const struct bt_mesh_model_op vnd_model_srv_op[];
|
||||
|
||||
/**
|
||||
* @brief 读取led状态
|
||||
*
|
||||
* @param led_pin - 引脚
|
||||
*
|
||||
* @return led状态
|
||||
*/
|
||||
BOOL read_led_state(uint32_t led_pin);
|
||||
|
||||
/**
|
||||
* @brief 设置led状态
|
||||
*
|
||||
* @param led_pin - 引脚
|
||||
* @param on - 状态
|
||||
*/
|
||||
void set_led_state(uint32_t led_pin, BOOL on);
|
||||
|
||||
/**
|
||||
* @brief 翻转led状态
|
||||
*
|
||||
* @param led_pin - 引脚
|
||||
*/
|
||||
void toggle_led_state(uint32_t led_pin);
|
||||
|
||||
/**
|
||||
* @brief indicate,有应答传输数据通道
|
||||
*
|
||||
* @param param - 发送参数.
|
||||
* @param pData - 数据指针.
|
||||
* @param len - 数据长度,最大为(APP_MAX_TX_SIZE).
|
||||
*
|
||||
* @return 参考Global_Error_Code
|
||||
*/
|
||||
int vendor_message_srv_indicate(struct send_param *param, uint8_t *pData, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief send_trans,透传数据通道
|
||||
*
|
||||
* @param param - 发送参数.
|
||||
* @param pData - 数据指针.
|
||||
* @param len - 数据长度,最大为(APP_MAX_TX_SIZE).
|
||||
*
|
||||
* @return 参考Global_Error_Code
|
||||
*/
|
||||
int vendor_message_srv_send_trans(struct send_param *param, uint8_t *pData, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief TID selection method
|
||||
*
|
||||
* @return TID
|
||||
*/
|
||||
uint8_t vendor_srv_tid_get(void);
|
||||
|
||||
/**
|
||||
* @brief 复位厂商模型服务,取消所有正在发送的流程
|
||||
*/
|
||||
void vendor_message_srv_trans_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -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,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,990 @@
|
||||
/********************************** (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)0xF0FF0000;
|
||||
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
|
||||
RCC->CTLR &= (uint32_t)0xFFFBFFFF;
|
||||
RCC->CFGR0 &= (uint32_t)0xFF00FFFF;
|
||||
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)
|
||||
{
|
||||
//GPIO_IPD_Unused();
|
||||
#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
|
||||
Reference in New Issue
Block a user