NUCLEO_WB55RG: HAL API updates to get SLEEP, RTC and LPTICKER OK

- astyle OK
- file alignment with other families
- HSE, MSI, HSI clock support
- LPTICKER with RTC and LPTIM tested
pull/9814/head
jeromecoutant 2018-10-08 11:37:15 +02:00 committed by Laurent Meunier
parent beab69704a
commit ea86e8ef34
13 changed files with 579 additions and 470 deletions

View File

@ -39,7 +39,7 @@ typedef enum {
PA_5 = 0x05,
PA_6 = 0x06,
PA_7 = 0x07,
PA_7_ALT0 = PA_7|ALT0,
PA_7_ALT0 = PA_7 | ALT0,
PA_8 = 0x08,
PA_9 = 0x09,
PA_10 = 0x0A,
@ -59,7 +59,7 @@ typedef enum {
PB_7 = 0x17,
PB_8 = 0x18,
PB_9 = 0x19,
PB_9_ALT0 = PB_9|ALT0,
PB_9_ALT0 = PB_9 | ALT0,
PB_10 = 0x1A,
PB_11 = 0x1B,
PB_12 = 0x1C,

View File

@ -13,18 +13,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This file configures the system clock as follows:
*-----------------------------------------------------------------------------
* System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock)
* | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal)
* | 3- USE_PLL_HSI (internal 16 MHz)
* | 4- USE_PLL_MSI (internal 100kHz to 48 MHz)
*-----------------------------------------------------------------------------
* SYSCLK(MHz) | 64
* AHBCLK (MHz) | 64
* APB1CLK (MHz) | 64
* APB2CLK (MHz) | 64
* USB capable | NO // todo
*-----------------------------------------------------------------------------
**/
#include "stm32wbxx.h"
#include "mbed_assert.h"
#include "mbed_error.h"
// Clock source is selected with CLOCK_SOURCE in json config
#define USE_PLL_HSE_EXTC 0x8 // Use external clock (not available)
#define USE_PLL_HSE_XTAL 0x4 // Use external 32 MHz xtal (X1 on board + need HW patch)
#define USE_PLL_HSI 0x2 // Use HSI 16MHz internal clock
#define USE_PLL_MSI 0x1 // Use MSI 4MHz internal clock (default)
#define USE_PLL_MSI 0x1 // Use MSI internal clock
#define DEBUG_MCO (0) // Output the MCO on PA8 for debugging (0=OFF, 1=SYSCLK, 2=HSE, 3=HSI, 4=MSI)
#if (((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC))
#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) )
uint8_t SetSysClock_PLL_HSE(uint8_t bypass);
#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */
@ -45,6 +62,7 @@ void Configure_RF_Clock_Sources(void);
* @param None
* @retval None
*/
void SetSysClock(void)
{
#if ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC)
@ -59,7 +77,7 @@ void SetSysClock(void)
{
#if ((CLOCK_SOURCE) & USE_PLL_HSI)
/* 3- If fail start with HSI clock */
if (SetSysClock_PLL_HSI()==0)
if (SetSysClock_PLL_HSI() == 0)
#endif
{
#if ((CLOCK_SOURCE) & USE_PLL_MSI)
@ -67,8 +85,8 @@ void SetSysClock(void)
if (SetSysClock_PLL_MSI() == 0)
#endif
{
while(1) {
MBED_ASSERT(1);
{
error("SetSysClock failed\n");
}
}
}
@ -89,24 +107,41 @@ void SetSysClock(void)
/******************************************************************************/
uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// System is fully clocked @ 32MHz from HSE
//return 1;
// Enable HSE oscillator and activate PLL with HSE as source
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
if (bypass == 0) {
RCC_OscInitStruct.HSEState = RCC_HSE_ON; // External 32 MHz xtal on OSC_IN/OSC_OUT
} else {
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; // External 32 MHz clock on OSC_IN
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
#if MBED_CONF_TARGET_LSE_AVAILABLE
// Enable LSE Oscillator to automatically calibrate the MSI clock
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // No PLL update
RCC_OscInitStruct.LSEState = RCC_LSE_ON; // External 32.768 kHz clock on OSC_IN/OSC_OUT
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
return 0; // FAIL
}
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
RCC_OscInitStruct.PLL.PLLN = 16;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4;
/* Enable the CSS interrupt in case LSE signal is corrupted or not present */
HAL_RCCEx_DisableLSECSS();
#endif /* MBED_CONF_TARGET_LSE_AVAILABLE */
// HSE has been turned on during system init
// Enable HSE oscillator and activate PLL with HSE as source
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
if (bypass == 0) {
RCC_OscInitStruct.HSEState = RCC_HSE_ON; // External 8 MHz xtal on OSC_IN/OSC_OUT
} else {
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; // External 32 MHz clock on OSC_IN
}
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; // 32 MHz
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV8; // 4 MHz
RCC_OscInitStruct.PLL.PLLN = 32; // 128 MHz
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; // 64 MHz // RCC_SYSCLKSOURCE_PLLCLK
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV5;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
return 0; // FAIL
@ -125,12 +160,19 @@ uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
return 0; // FAIL
}
// Disable MSI Oscillator
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_OFF;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // No PLL update
HAL_RCC_OscConfig(&RCC_OscInitStruct);
// Output clock on MCO1 pin(PA8) for debugging purpose
#if DEBUG_MCO == 2
if (bypass == 0)
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_2); // xx MHz
else
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1); // xx MHz
if (bypass == 0) {
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_4); // 8 MHz
} else {
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_2); // 4 MHz
}
#endif
return 1;
@ -152,12 +194,12 @@ uint8_t SetSysClock_PLL_HSI(void)
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
RCC_OscInitStruct.PLL.PLLN = 16;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; // 16 MHz
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2; // 8 MHz
RCC_OscInitStruct.PLL.PLLN = 16; // 128 MHz
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; // 64 MHz // RCC_SYSCLKSOURCE_PLLCLK
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
return 0; // FAIL
@ -171,7 +213,7 @@ uint8_t SetSysClock_PLL_HSI(void)
RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1; // 64 MHz
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 64 MHz
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 64 MHz
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) {
return 0; // FAIL
}
@ -193,24 +235,47 @@ uint8_t SetSysClock_PLL_MSI(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
// RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; // USB todo
#if MBED_CONF_TARGET_LSE_AVAILABLE
// Enable LSE Oscillator to automatically calibrate the MSI clock
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // No PLL update
RCC_OscInitStruct.LSEState = RCC_LSE_ON; // External 32.768 kHz clock on OSC_IN/OSC_OUT
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
return 0; // FAIL
}
/* Enable the CSS interrupt in case LSE signal is corrupted or not present */
HAL_RCCEx_DisableLSECSS();
#endif /* MBED_CONF_TARGET_LSE_AVAILABLE */
// Enable MSI Oscillator and activate PLL with MSI as source
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6; // 4 MHz
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
RCC_OscInitStruct.PLL.PLLN = 32;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; // 4 MHz
RCC_OscInitStruct.PLL.PLLN = 32; // 128 MHz
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; // 64 MHz // RCC_SYSCLKSOURCE_PLLCLK
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV5;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
return 0; // FAIL
}
#if MBED_CONF_TARGET_LSE_AVAILABLE
/* Enable MSI Auto-calibration through LSE */
HAL_RCCEx_EnableMSIPLLMode();
#endif /* MBED_CONF_TARGET_LSE_AVAILABLE */
/* Select MSI output as USB clock source */
// PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
// PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI; /* 48 MHz */
// HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
// Select PLL as system clock source and configure the clocks dividers
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_HCLK2 | RCC_CLOCKTYPE_HCLK4 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 64 MHz
@ -224,13 +289,6 @@ uint8_t SetSysClock_PLL_MSI(void)
return 0; // FAIL
}
// Calibrate MSI
LL_PWR_EnableBkUpAccess();
LL_RCC_ForceBackupDomainReset();
LL_RCC_ReleaseBackupDomainReset();
LL_RCC_LSE_Enable();
while (LL_RCC_LSE_IsReady() != 1) {}
LL_RCC_MSI_EnablePLLMode();
// Output clock on MCO1 pin(PA8) for debugging purpose
#if DEBUG_MCO == 4
@ -243,11 +301,21 @@ uint8_t SetSysClock_PLL_MSI(void)
void Configure_RF_Clock_Sources(void)
{
// Reset backup domain
if ((LL_RCC_IsActiveFlag_PINRST()) && (!LL_RCC_IsActiveFlag_SFTRST())) {
// Write twice the value to flush the APB-AHB bridge
// This bit shall be written in the register before writing the next one
HAL_PWR_EnableBkUpAccess();
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE();
}
/**
* Select LSE clock
*/
LL_RCC_LSE_Enable();
while(!LL_RCC_LSE_IsReady());
while (!LL_RCC_LSE_IsReady());
/**
* Select wakeup source of BLE RF
@ -263,7 +331,7 @@ void Configure_RF_Clock_Sources(void)
* Set RNG on HSI48
*/
LL_RCC_HSI48_Enable();
while(!LL_RCC_HSI48_IsReady());
while (!LL_RCC_HSI48_IsReady());
LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_HSI48);
return;

View File

@ -1,347 +0,0 @@
/**
******************************************************************************
* @file system_stm32wbxx.c
* @author MCD Application Team
* @brief CMSIS Cortex Device Peripheral Access Layer System Source File
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32wbxx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* After each device reset the MSI (4 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32wbxx.s" file, to
* configure the system clock before to branch to main program.
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2018 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32WBxx_system
* @{
*/
/** @addtogroup stm32WBxx_System_Private_Includes
* @{
*/
#include "stm32wbxx.h"
#include "nvic_addr.h" // MBED patch
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)32000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (MSI_VALUE)
#define MSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
#if !defined (LSI_VALUE)
#define LSI_VALUE ((uint32_t)32000) /*!< Value of LSI in Hz*/
#endif /* LSI_VALUE */
#if !defined (LSE_VALUE)
#define LSE_VALUE ((uint32_t)32768) /*!< Value of LSE in Hz*/
#endif /* LSE_VALUE */
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Defines
* @{
*/
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
#ifdef CORE_CM0PLUS
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x0U /*!< Vector Table base offset field.
This value must be a multiple of 0x100. */
#define VECT_TAB_BASE_ADDRESS RAM2A_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x100. */
#else
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x0U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#define VECT_TAB_BASE_ADDRESS RAM1_BASE /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#endif
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Variables
* @{
*/
/* The SystemCoreClock variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = 4000000; /*CPU1: M4 on MSI clock after startup (4MHz)*/
const uint32_t AHBPrescTable[16] = {1, 3, 5, 1, 1, 6, 10, 32, 2, 4, 8, 16, 64, 128, 256, 512}; /* eqv. division factor used for Dory*/
/* index=[0,...15]*/
const uint32_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
const uint32_t MSIRangeTable[12] = {100000, 200000, 400000, 800000, 1000000, 2000000, \
4000000, 8000000, 16000000, 24000000, 32000000, 48000000};
const uint32_t SmpsPrescalerTable[4][6]={{1,3,2,2,1,2}, \
{2,6,4,3,2,4}, \
{4,12,8,6,4,8}, \
{4,12,8,6,4,8}};
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system.
* @param None
* @retval None
*/
void SystemInit(void)
{
/* Configure the Vector Table location add offset address ------------------*/
#ifdef CORE_CM0PLUS
#if defined(VECT_TAB_SRAM) && defined(VECT_TAB_BASE_ADDRESS)
/* program in SRAMx */
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAMx for CPU2 */
#else
/* program in FLASH */
SCB->VTOR = VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif /* Program memory type */
#else
#if defined(VECT_TAB_SRAM) && defined(VECT_TAB_BASE_ADDRESS)
/* program in SRAMx */
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAMx for CPU1 */
#else /* program in FLASH */
SCB->VTOR = NVIC_FLASH_VECTOR_ADDRESS; /* Vector Table Relocation in Internal FLASH - MBED patch */
#endif
#endif
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set MSION bit */
RCC->CR |= RCC_CR_MSION;
/* Reset CFGR register */
RCC->CFGR = 0x00070000U;
/* Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits */
RCC->CR &= (uint32_t)0xFAF6FEFBU;
/*!< Reset LSI1 and LSI2 bits */
RCC->CSR &= (uint32_t)0xFFFFFFFAU;
/*!< Reset HSI48ON bit */
RCC->CRRCR &= (uint32_t)0xFFFFFFFEU;
/* Reset PLLCFGR register */
RCC->PLLCFGR = 0x22041000U;
/* Reset PLLSAI1CFGR register */
RCC->PLLSAI1CFGR = 0x22041000U;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Disable all interrupts */
RCC->CIER = 0x00000000;
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
* or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (*) MSI_VALUE is a constant defined in stm32wbxx_hal.h file (default value
* 4 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
* 16 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (***) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
* 32 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may
* have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void)
{
uint32_t tmp = 0, msirange = 0, pllvco = 0, pllr = 2, pllsource = 0, pllm = 2;
/* Get MSI Range frequency--------------------------------------------------*/
/*MSI frequency range in Hz*/
msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos];
/*SystemCoreClock=HAL_RCC_GetSysClockFreq();*/
/* Get SYSCLK source -------------------------------------------------------*/
switch (RCC->CFGR & RCC_CFGR_SWS)
{
case 0x00: /* MSI used as system clock source */
SystemCoreClock = msirange;
break;
case 0x04: /* HSI used as system clock source */
/* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x08: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x0C: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
SYSCLK = PLL_VCO / PLLR
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1 ;
switch (pllsource)
{
case 0x02: /* HSI used as PLL clock source */
pllvco = (HSI_VALUE / pllm);
break;
case 0x03: /* HSE used as PLL clock source */
pllvco = (HSE_VALUE / pllm);
break;
default: /* MSI used as PLL clock source */
pllvco = (msirange / pllm);
break;
}
pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1);
SystemCoreClock = pllvco/pllr;
break;
default:
SystemCoreClock = msirange;
break;
}
/* Compute HCLK clock frequency --------------------------------------------*/
#ifdef CORE_CM0PLUS
/* Get HCLK2 prescaler */
tmp = AHBPrescTable[((RCC->EXTCFGR & RCC_EXTCFGR_C2HPRE) >> RCC_EXTCFGR_C2HPRE_Pos)];
#else
/* Get HCLK1 prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
#endif
/* HCLK clock frequency */
SystemCoreClock = SystemCoreClock / tmp;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -17,13 +17,13 @@
#define __US_TICKER_DATA_H
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
#include "stm32wbxx.h"
#include "stm32wbxx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM16
#define TIM_MST_IRQ TIM1_UP_TIM16_IRQn
#define TIM_MST_RCC __HAL_RCC_TIM16_CLK_ENABLE()

View File

@ -129,7 +129,7 @@ struct analogin_s {
}
#endif
/* STM32WB HAL doesn't provide this API called in sleep.c */
/* STM32WB HAL doesn't provide some macro */
#define __HAL_RCC_PWR_CLK_DISABLE()
#define __HAL_RCC_PWR_CLK_ENABLE()
#define __HAL_RCC_PWR_IS_CLK_ENABLED() 1

View File

@ -28,7 +28,7 @@
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx.h"
#include "Legacy/stm32_hal_legacy.h" /* Aliases file for old names compatibility */
#include "stm32_hal_legacy.h" /* Aliases file for old names compatibility */
#include <stddef.h>
/* Exported types ------------------------------------------------------------*/

View File

@ -0,0 +1,381 @@
/**
******************************************************************************
* @file system_stm32wbxx.c
* @author MCD Application Team
* @brief CMSIS Cortex Device Peripheral Access Layer System Source File
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32wbxx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* After each device reset the MSI (4 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32wbxx.s" file, to
* configure the system clock before to branch to main program.
*
* This file configures the system clock as follows:
*=============================================================================
*-----------------------------------------------------------------------------
* System Clock source | MSI
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 4000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 4000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 1
*-----------------------------------------------------------------------------
* APB2 Prescaler | 1
*-----------------------------------------------------------------------------
* PLL_M | 1
*-----------------------------------------------------------------------------
* PLL_N | 8
*-----------------------------------------------------------------------------
* PLL_P | 7
*-----------------------------------------------------------------------------
* PLL_Q | 2
*-----------------------------------------------------------------------------
* PLL_R | 2
*-----------------------------------------------------------------------------
* PLLSAI1_P | NA
*-----------------------------------------------------------------------------
* PLLSAI1_Q | NA
*-----------------------------------------------------------------------------
* PLLSAI1_R | NA
*-----------------------------------------------------------------------------
* Require 48MHz for USB OTG FS, | Disabled
* SDIO and RNG clock |
*-----------------------------------------------------------------------------
*=============================================================================
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2018 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32WBxx_system
* @{
*/
/** @addtogroup stm32WBxx_System_Private_Includes
* @{
*/
#include "app_common.h"
#include "otp.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)32000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (MSI_VALUE)
#define MSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
#if !defined (LSI_VALUE)
#define LSI_VALUE ((uint32_t)32000) /*!< Value of LSI in Hz*/
#endif /* LSI_VALUE */
#if !defined (LSE_VALUE)
#define LSE_VALUE ((uint32_t)32768) /*!< Value of LSE in Hz*/
#endif /* LSE_VALUE */
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Defines
* @{
*/
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
/* #define VECT_TAB_SRAM */
/*!< Vector Table base offset field. This value must be a multiple of 0x200. */
/* #define VECT_TAB_OFFSET 0x0U*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Variables
* @{
*/
/* The SystemCoreClock variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = 4000000; /*CPU1: M4 on MSI clock after startup (4MHz)*/
const uint32_t AHBPrescTable[16] = {1, 3, 5, 1, 1, 6, 10, 32, 2, 4, 8, 16, 64, 128, 256, 512}; /* eqv. division factor used for Dory*/
/* index=[0,...15]*/
const uint32_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
const uint32_t MSIRangeTable[16UL] = {100000UL, 200000UL, 400000UL, 800000UL, 1000000UL, 2000000UL, \
4000000UL, 8000000UL, 16000000UL, 24000000UL, 32000000UL, 48000000UL, 0UL, 0UL, 0UL, 0UL}; /* 0UL values are incorrect cases */
const uint32_t SmpsPrescalerTable[4][6]={{1,3,2,2,1,2}, \
{2,6,4,3,2,4}, \
{4,12,8,6,4,8}, \
{4,12,8,6,4,8}};
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system.
* @param None
* @retval None
*/
void SystemInit(void)
{
OTP_ID0_t * p_otp;
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
/**
* Read HSE_Tuning from OTP
*/
p_otp = (OTP_ID0_t *) OTP_Read(0);
if (p_otp)
{
LL_RCC_HSE_SetCapacitorTuning(p_otp->hse_tuning);
}
LL_RCC_HSE_Enable();
/**
* Set FLASH latency to 1WS
*/
LL_FLASH_SetLatency( LL_FLASH_LATENCY_1 );
while( LL_FLASH_GetLatency() != LL_FLASH_LATENCY_1 );
/**
* Switch to HSE
*
*/
while(!LL_RCC_HSE_IsReady());
LL_RCC_SetSysClkSource( LL_RCC_SYS_CLKSOURCE_HSE );
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE);
/**
* Switch OFF MSI
*/
LL_RCC_MSI_Disable();
/* Configure the Vector Table location add offset address ------------------*/
#ifdef CORE_CM0PLUS
/* program in SRAM2A */
#if defined(VECT_TAB_SRAM)
SCB->VTOR = RAM2A_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM2A for CPU2 */
#elif defined(VECT_TAB_SRAM2B)
/* program in SRAM2B */
SCB->VTOR = RAM2B_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM2B for CPU2 */
#else
/* program in FLASH */
SCB->VTOR = VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif /* Program memory type */
#else
#if defined(VECT_TAB_SRAM)
/* program in SRAM1 */
SCB->VTOR = RAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM1 for CPU1 */
#elif defined(VECT_TAB_OFFSET)
SCB->VTOR = VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
#endif
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
* or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (*) MSI_VALUE is a constant defined in stm32wbxx_hal.h file (default value
* 4 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
* 16 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (***) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
* 32 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may
* have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void)
{
uint32_t tmp = 0, msirange = 0, pllvco = 0, pllr = 2, pllsource = 0, pllm = 2;
/* Get MSI Range frequency--------------------------------------------------*/
/*MSI frequency range in Hz*/
msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos];
/*SystemCoreClock=HAL_RCC_GetSysClockFreq();*/
/* Get SYSCLK source -------------------------------------------------------*/
switch (RCC->CFGR & RCC_CFGR_SWS)
{
case 0x00: /* MSI used as system clock source */
SystemCoreClock = msirange;
break;
case 0x04: /* HSI used as system clock source */
/* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x08: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x0C: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
SYSCLK = PLL_VCO / PLLR
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1 ;
switch (pllsource)
{
case 0x02: /* HSI used as PLL clock source */
pllvco = (HSI_VALUE / pllm);
break;
case 0x03: /* HSE used as PLL clock source */
pllvco = (HSE_VALUE / pllm);
break;
default: /* MSI used as PLL clock source */
pllvco = (msirange / pllm);
break;
}
pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1);
SystemCoreClock = pllvco/pllr;
break;
default:
SystemCoreClock = msirange;
break;
}
/* Compute HCLK clock frequency --------------------------------------------*/
#ifdef CORE_CM0PLUS
/* Get HCLK2 prescaler */
tmp = AHBPrescTable[((RCC->EXTCFGR & RCC_EXTCFGR_C2HPRE) >> RCC_EXTCFGR_C2HPRE_Pos)];
#else
/* Get HCLK1 prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
#endif
/* HCLK clock frequency */
SystemCoreClock = SystemCoreClock / tmp;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -29,7 +29,7 @@
*/
static uint32_t GetPage(uint32_t Addr)
{
return (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;
return (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;
}
/** Initialize the flash peripheral and the flash_t object
@ -137,7 +137,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
if ((uint32_t) data % 4 != 0) { // Data is not aligned, copy data in a temp buffer before programming it
volatile uint64_t data64;
while ((address < (StartAddress + size)) && (status == 0)) {
for (uint8_t i =0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
*(((uint8_t *) &data64) + i) = *(data + i);
}
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data64) == HAL_OK) {
@ -149,7 +149,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
}
} else { // Data is aligned, so let's avoid any copy
while ((address < (StartAddress + size)) && (status == 0)) {
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, *((uint64_t*) data)) == HAL_OK) {
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, *((uint64_t *) data)) == HAL_OK) {
address = address + 8;
data = data + 8;
} else {
@ -171,7 +171,8 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
* @param address The sector starting address
* @return The size of a sector
*/
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) {
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
{
/* considering 1 sector = 1 page */
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
return MBED_FLASH_INVALID_SIZE;
@ -185,7 +186,8 @@ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) {
* @param obj The flash object
* @return Minimum programmable page size in bytes
*/
uint32_t flash_get_page_size(const flash_t *obj) {
uint32_t flash_get_page_size(const flash_t *obj)
{
return 8;
}
@ -194,7 +196,8 @@ uint32_t flash_get_page_size(const flash_t *obj) {
* @param obj The flash object
* @return The start address for the flash region
*/
uint32_t flash_get_start_address(const flash_t *obj) {
uint32_t flash_get_start_address(const flash_t *obj)
{
return FLASH_BASE;
}
@ -203,7 +206,8 @@ uint32_t flash_get_start_address(const flash_t *obj) {
* @param obj The flash object
* @return The flash region size
*/
uint32_t flash_get_size(const flash_t *obj) {
uint32_t flash_get_size(const flash_t *obj)
{
return FLASH_SIZE;
}

View File

@ -57,14 +57,15 @@ static inline void stm_pin_PullConfig(GPIO_TypeDef *gpio, uint32_t ll_pin, uint3
}
}
static inline void stm_pin_SetAFPin( GPIO_TypeDef *gpio, PinName pin, uint32_t afnum)
static inline void stm_pin_SetAFPin(GPIO_TypeDef *gpio, PinName pin, uint32_t afnum)
{
uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)];
if (STM_PIN(pin) > 7)
if (STM_PIN(pin) > 7) {
LL_GPIO_SetAFPin_8_15(gpio, ll_pin, afnum);
else
} else {
LL_GPIO_SetAFPin_0_7(gpio, ll_pin, afnum);
}
}
#endif

View File

@ -34,8 +34,7 @@
#ifdef DEVICE_PWMOUT
const pwm_apb_map_t pwm_apb_map_table[] =
{
const pwm_apb_map_t pwm_apb_map_table[] = {
#if defined(TIM1_BASE)
{PWM_1, PWMOUT_ON_APB1},
#endif

View File

@ -51,7 +51,7 @@ static void uart_irq(UARTName uart_name)
int8_t id = get_uart_index(uart_name);
if (id >= 0) {
UART_HandleTypeDef * huart = &uart_handlers[id];
UART_HandleTypeDef *huart = &uart_handlers[id];
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TXE) != RESET) {
if (__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET) {
@ -90,7 +90,7 @@ static void lpuart1_irq(void)
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
{
struct serial_s *obj_s = SERIAL_S(obj);
irq_handler = handler;
serial_irq_ids[obj_s->index] = id;
}
@ -203,7 +203,7 @@ void serial_break_set(serial_t *obj)
* LOCAL HELPER FUNCTIONS
******************************************************************************/
/**
/**
* Configure the TX buffer for an asynchronous write serial transaction
*
* @param obj The serial object.
@ -223,7 +223,7 @@ static void serial_tx_buffer_set(serial_t *obj, void *tx, int tx_length, uint8_t
obj->tx_buff.length = tx_length;
obj->tx_buff.pos = 0;
}
/**
* Configure the RX buffer for an asynchronous write serial transaction
*
@ -245,7 +245,7 @@ static void serial_rx_buffer_set(serial_t *obj, void *rx, int rx_length, uint8_t
obj->rx_buff.pos = 0;
}
/**
/**
* Configure events
*
* @param obj The serial object
@ -253,9 +253,9 @@ static void serial_rx_buffer_set(serial_t *obj, void *rx, int rx_length, uint8_t
* @param enable Set to non-zero to enable events, or zero to disable them
*/
static void serial_enable_event(serial_t *obj, int event, uint8_t enable)
{
{
struct serial_s *obj_s = SERIAL_S(obj);
// Shouldn't have to enable interrupt here, just need to keep track of the requested events.
if (enable) {
obj_s->events |= event;
@ -297,7 +297,7 @@ static IRQn_Type serial_get_irq_n(UARTName uart_name)
* MBED API FUNCTIONS
******************************************************************************/
/**
/**
* Begin asynchronous TX transfer. The used buffer is specified in the serial
* object, tx_buff
*
@ -311,28 +311,28 @@ static IRQn_Type serial_get_irq_n(UARTName uart_name)
* @return Returns number of data transfered, or 0 otherwise
*/
int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
{
{
// TODO: DMA usage is currently ignored
(void) hint;
// Check buffer is ok
MBED_ASSERT(tx != (void*)0);
MBED_ASSERT(tx != (void *)0);
MBED_ASSERT(tx_width == 8); // support only 8b width
struct serial_s *obj_s = SERIAL_S(obj);
UART_HandleTypeDef * huart = &uart_handlers[obj_s->index];
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
if (tx_length == 0) {
return 0;
}
// Set up buffer
serial_tx_buffer_set(obj, (void *)tx, tx_length, tx_width);
// Set up events
serial_enable_event(obj, SERIAL_EVENT_TX_ALL, 0); // Clear all events
serial_enable_event(obj, event, 1); // Set only the wanted events
// Enable interrupt
IRQn_Type irq_n = serial_get_irq_n(obj_s->uart);
NVIC_ClearPendingIRQ(irq_n);
@ -342,14 +342,14 @@ int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx
NVIC_EnableIRQ(irq_n);
// the following function will enable UART_IT_TXE and error interrupts
if (HAL_UART_Transmit_IT(huart, (uint8_t*)tx, tx_length) != HAL_OK) {
if (HAL_UART_Transmit_IT(huart, (uint8_t *)tx, tx_length) != HAL_OK) {
return 0;
}
return tx_length;
}
/**
/**
* Begin asynchronous RX transfer (enable interrupt for data collecting)
* The used buffer is specified in the serial object, rx_buff
*
@ -370,18 +370,18 @@ void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_widt
/* Sanity check arguments */
MBED_ASSERT(obj);
MBED_ASSERT(rx != (void*)0);
MBED_ASSERT(rx != (void *)0);
MBED_ASSERT(rx_width == 8); // support only 8b width
struct serial_s *obj_s = SERIAL_S(obj);
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
serial_enable_event(obj, SERIAL_EVENT_RX_ALL, 0);
serial_enable_event(obj, event, 1);
// set CharMatch
obj->char_match = char_match;
serial_rx_buffer_set(obj, rx, rx_length, rx_width);
IRQn_Type irq_n = serial_get_irq_n(obj_s->uart);
@ -391,8 +391,8 @@ void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_widt
NVIC_SetVector(irq_n, (uint32_t)handler);
NVIC_EnableIRQ(irq_n);
// following HAL function will enable the RXNE interrupt + error interrupts
HAL_UART_Receive_IT(huart, (uint8_t*)rx, rx_length);
// following HAL function will enable the RXNE interrupt + error interrupts
HAL_UART_Receive_IT(huart, (uint8_t *)rx, rx_length);
}
/**
@ -404,10 +404,10 @@ void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_widt
uint8_t serial_tx_active(serial_t *obj)
{
MBED_ASSERT(obj);
struct serial_s *obj_s = SERIAL_S(obj);
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
return (((HAL_UART_GetState(huart) & HAL_UART_STATE_BUSY_TX) == HAL_UART_STATE_BUSY_TX) ? 1 : 0);
}
@ -420,20 +420,22 @@ uint8_t serial_tx_active(serial_t *obj)
uint8_t serial_rx_active(serial_t *obj)
{
MBED_ASSERT(obj);
struct serial_s *obj_s = SERIAL_S(obj);
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
return (((HAL_UART_GetState(huart) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) ? 1 : 0);
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
}
}
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE) != RESET) {
volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear PE flag
} else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) {
@ -455,49 +457,49 @@ int serial_irq_handler_asynch(serial_t *obj)
{
struct serial_s *obj_s = SERIAL_S(obj);
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
volatile int return_event = 0;
uint8_t *buf = (uint8_t*)(obj->rx_buff.buffer);
uint8_t *buf = (uint8_t *)(obj->rx_buff.buffer);
uint8_t i = 0;
// TX PART:
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) {
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) {
// Return event SERIAL_EVENT_TX_COMPLETE if requested
if ((obj_s->events & SERIAL_EVENT_TX_COMPLETE ) != 0) {
if ((obj_s->events & SERIAL_EVENT_TX_COMPLETE) != 0) {
return_event |= (SERIAL_EVENT_TX_COMPLETE & obj_s->events);
}
}
}
// Handle error events
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE) != RESET) {
if (__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET) {
return_event |= (SERIAL_EVENT_RX_PARITY_ERROR & obj_s->events);
}
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) {
if (__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET) {
return_event |= (SERIAL_EVENT_RX_FRAMING_ERROR & obj_s->events);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
if (__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) {
return_event |= (SERIAL_EVENT_RX_OVERRUN_ERROR & obj_s->events);
}
}
HAL_UART_IRQHandler(huart);
// Abort if an error occurs
if ((return_event & SERIAL_EVENT_RX_PARITY_ERROR) ||
(return_event & SERIAL_EVENT_RX_FRAMING_ERROR) ||
(return_event & SERIAL_EVENT_RX_OVERRUN_ERROR)) {
(return_event & SERIAL_EVENT_RX_FRAMING_ERROR) ||
(return_event & SERIAL_EVENT_RX_OVERRUN_ERROR)) {
return return_event;
}
//RX PART
if (huart->RxXferSize != 0) {
obj->rx_buff.pos = huart->RxXferSize - huart->RxXferCount;
@ -505,7 +507,7 @@ int serial_irq_handler_asynch(serial_t *obj)
if ((huart->RxXferCount == 0) && (obj->rx_buff.pos >= (obj->rx_buff.length - 1))) {
return_event |= (SERIAL_EVENT_RX_COMPLETE & obj_s->events);
}
// Check if char_match is present
if (obj_s->events & SERIAL_EVENT_RX_CHARACTER_MATCH) {
if (buf != NULL) {
@ -519,11 +521,11 @@ int serial_irq_handler_asynch(serial_t *obj)
}
}
}
return return_event;
}
/**
/**
* Abort the ongoing TX transaction. It disables the enabled interupt for TX and
* flush TX hardware buffer if TX FIFO is used
*
@ -533,17 +535,17 @@ void serial_tx_abort_asynch(serial_t *obj)
{
struct serial_s *obj_s = SERIAL_S(obj);
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
__HAL_UART_DISABLE_IT(huart, UART_IT_TC);
__HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
// clear flags
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
// reset states
huart->TxXferCount = 0;
// update handle state
if(huart->gState == HAL_UART_STATE_BUSY_TX_RX) {
if (huart->gState == HAL_UART_STATE_BUSY_TX_RX) {
huart->gState = HAL_UART_STATE_BUSY_RX;
} else {
huart->gState = HAL_UART_STATE_READY;
@ -560,20 +562,20 @@ void serial_rx_abort_asynch(serial_t *obj)
{
struct serial_s *obj_s = SERIAL_S(obj);
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
// disable interrupts
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
// clear flags
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_RXNE);
volatile uint32_t tmpval __attribute__((unused)) = huart->Instance->RDR; // Clear errors flag
// reset states
huart->RxXferCount = 0;
// update handle state
if(huart->RxState == HAL_UART_STATE_BUSY_TX_RX) {
if (huart->RxState == HAL_UART_STATE_BUSY_TX_RX) {
huart->RxState = HAL_UART_STATE_BUSY_TX;
} else {
huart->RxState = HAL_UART_STATE_READY;
@ -603,9 +605,9 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
return;
}
if(type == FlowControlNone) {
if (type == FlowControlNone) {
// Disable hardware flow control
obj_s->hw_flow_ctl = UART_HWCONTROL_NONE;
obj_s->hw_flow_ctl = UART_HWCONTROL_NONE;
}
if (type == FlowControlRTS) {
// Enable RTS
@ -635,7 +637,7 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
// Enable the pin for RTS function
pinmap_pinout(rxflow, PinMap_UART_RTS);
}
init_uart(obj);
}

View File

@ -39,16 +39,17 @@
#include "PeripheralPins.h"
#if DEVICE_SPI_ASYNCH
#define SPI_S(obj) (( struct spi_s *)(&(obj->spi)))
#define SPI_S(obj) (( struct spi_s *)(&(obj->spi)))
#else
#define SPI_S(obj) (( struct spi_s *)(obj))
#define SPI_S(obj) (( struct spi_s *)(obj))
#endif
/*
* Only the frequency is managed in the family specific part
* the rest of SPI management is common to all STM32 families
*/
int spi_get_clock_freq(spi_t *obj) {
int spi_get_clock_freq(spi_t *obj)
{
struct spi_s *spiobj = SPI_S(obj);
int spi_hz = 0;