Initial commit: CCU621_M firmware project with BLE debug link support.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-08 17:28:36 +08:00
commit 9ceb218f80
1597 changed files with 724159 additions and 0 deletions
@@ -0,0 +1,286 @@
/*!
\file gd32h7xx_hwsem.c
\brief HWSEM driver
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
*/
/*
Copyright (c) 2025, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#include "gd32h7xx_hwsem.h"
/*!
\brief try to lock the specific semaphore by writing process ID
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[in] process: the process to lock the semaphore
only one parameter can be selected which is shown as below:
\arg 0 - 0xFF
\param[out] none
\retval ErrStatus: SUCCESS or ERROR
*/
ErrStatus hwsem_lock_set(hwsem_semaphore_enum semaphore, uint8_t process)
{
uint32_t temp_mid = 0U, temp_pid = 0U;
ErrStatus ret = ERROR;
/* try to lock the semaphore */
HWSEM_CTL(semaphore) = (uint32_t)(HWSEM_LOCK | CTL_MID(HWSEM_MASTER_ID) | CTL_PID(process));
/* read the control register to confirm the semaphore is locked by target process or not */
temp_mid = hwsem_master_id_get(semaphore);
temp_pid = hwsem_process_id_get(semaphore);
if((HWSEM_MASTER_ID == temp_mid) && (process == temp_pid)) {
ret = SUCCESS;
}
return ret;
}
/*!
\brief try to release the lock of the semaphore by writing process ID
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[in] process: the process to unlock the semaphore
only one parameter can be selected which is shown as below:
\arg 0 - 0xFF
\param[out] none
\retval ErrStatus: SUCCESS or ERROR
*/
ErrStatus hwsem_lock_release(hwsem_semaphore_enum semaphore, uint8_t process)
{
uint32_t lock_state = 0U;
ErrStatus ret = ERROR;
HWSEM_CTL(semaphore) = (uint32_t)(CTL_MID(HWSEM_MASTER_ID) | CTL_PID(process));
lock_state = HWSEM_CTL(semaphore) & HWSEM_CTL_LK;
if(0U == lock_state) {
ret = SUCCESS;
}
return ret;
}
/*!
\brief try to lock the semaphore by reading
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[out] none
\retval ErrStatus: SUCCESS or ERROR
*/
ErrStatus hwsem_lock_by_reading(hwsem_semaphore_enum semaphore)
{
ErrStatus ret = ERROR;
if((uint32_t)(HWSEM_LOCK | CTL_MID(HWSEM_MASTER_ID)) == HWSEM_RLK(semaphore)) {
ret = SUCCESS;
}
return ret;
}
/*!
\brief unlock all semaphores of the master ID
\param[in] key: key value
\arg 0 - 0xFFFF
\param[out] none
\retval none
*/
ErrStatus hwsem_unlock_all(uint16_t key)
{
ErrStatus ret = ERROR;
HWSEM_UNLK = UNLK_KEY(key) | UNLK_MID(HWSEM_MASTER_ID);
if(key == hwsem_key_get()) {
ret = SUCCESS;
}
return ret;
}
/*!
\brief get process ID of the specific semaphore
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[out] none
\retval uint32_t: process ID of semaphore
*/
uint32_t hwsem_process_id_get(hwsem_semaphore_enum semaphore)
{
return (uint32_t)(GET_CTL_PID(HWSEM_CTL(semaphore)));
}
/*!
\brief get master ID of the specific semaphore
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[out] none
\retval uint32_t: master ID of semaphore
*/
uint32_t hwsem_master_id_get(hwsem_semaphore_enum semaphore)
{
return (uint32_t)(GET_CTL_MID(HWSEM_CTL(semaphore)));
}
/*!
\brief get the lock status of the semaphore
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[out] none
\retval FlagStatus: SET or RESET
*/
FlagStatus hwsem_lock_status_get(hwsem_semaphore_enum semaphore)
{
FlagStatus ret = RESET;
if(0U != (HWSEM_CTL(semaphore) & HWSEM_LOCK)) {
ret = SET;
}
return ret;
}
/*!
\brief set the key
\param[in] key: key value
\arg 0 - 0xFFFF
\param[out] none
\retval none
*/
void hwsem_key_set(uint16_t key)
{
HWSEM_KEY = KEY_KEY(key);
}
/*!
\brief get the key
\param[in] none
\param[out] none
\retval uint16_t: key to unlock all semaphores
*/
uint16_t hwsem_key_get(void)
{
return ((uint16_t)GET_KEY_KEY(HWSEM_KEY));
}
/*!
\brief get the HWSEM flag status
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[out] none
\retval FlagStatus: SET or RESET
*/
FlagStatus hwsem_flag_get(hwsem_semaphore_enum semaphore)
{
FlagStatus ret = RESET;
if(RESET != ((HWSEM_STAT >> semaphore) & 0x1U)) {
return SET;
}
return ret;
}
/*!
\brief clear HWSEM flag status
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[out] none
\retval none
*/
void hwsem_flag_clear(hwsem_semaphore_enum semaphore)
{
HWSEM_INTC = (1U << semaphore);
}
/*!
\brief get HWSEM interrupt flag status
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[out] none
\retval FlagStatus: SET or RESET
*/
FlagStatus hwsem_interrupt_flag_get(hwsem_semaphore_enum semaphore)
{
FlagStatus ret = RESET;
if(RESET != ((HWSEM_INTF >> semaphore) & 0x1U)) {
ret = SET;
}
return ret;
}
/*!
\brief clear HWSEM interrupt flag
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[out] none
\retval none
*/
void hwsem_interrupt_flag_clear(hwsem_semaphore_enum semaphore)
{
HWSEM_INTC = (1U << semaphore);
}
/*!
\brief enable HWSEM interrupt
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[out] none
\retval none
*/
void hwsem_interrupt_enable(hwsem_semaphore_enum semaphore)
{
HWSEM_INTEN |= (1U << semaphore);
}
/*!
\brief disable HWSEM interrupt
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
only one parameter can be selected which is shown as below:
\arg SEMx (x=0..31): semaphore x
\param[out] none
\retval none
*/
void hwsem_interrupt_disable(hwsem_semaphore_enum semaphore)
{
HWSEM_INTEN &= (uint32_t)(~((uint32_t)1U << semaphore));
}