/*
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(C)2013 Semtech
Description: Target board general functions implementation
License: Revised BSD License, see LICENSE.TXT file include in the project
Maintainer: Miguel Luis and Gregory Cristian
*/
/*******************************************************************************
* @file stm32l0xx_hw.c
* @author MCD Application Team
* @version V1.1.2
* @date 08-September-2017
* @brief system hardware driver
******************************************************************************
* @attention
*
*
© Copyright (c) 2017 STMicroelectronics International N.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted, provided that the following conditions are met:
*
* 1. Redistribution 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 STMicroelectronics nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific written permission.
* 4. This software, including modifications and/or derivative works of this
* software, must execute solely and exclusively on microcontroller or
* microprocessor devices manufactured by or for STMicroelectronics.
* 5. Redistribution and use of this software other than as permitted under
* this license is void and will automatically terminate your rights under
* this license.
*
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
* SHALL STMICROELECTRONICS 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 "hw.h"
#include "radio.h"
#include "debug.h"
#include "vcom.h"
/*!
* \brief Unique Devices IDs register set ( STM32L0xxx )
*/
#define ID1 ( 0x1FF80050 )
#define ID2 ( 0x1FF80054 )
#define ID3 ( 0x1FF80064 )
/*!
* \brief ADC Vbat measurement constants
*/
/* Internal voltage reference, parameter VREFINT_CAL*/
#define VREFINT_CAL ((uint16_t*) ((uint32_t) 0x1FF80078))
#define LORAWAN_MAX_BAT 254
/* Internal temperature sensor: constants data used for indicative values in */
/* this example. Refer to device datasheet for min/typ/max values. */
/* Internal temperature sensor, parameter TS_CAL1: TS ADC raw data acquired at
*a temperature of 110 DegC (+-5 DegC), VDDA = 3.3 V (+-10 mV). */
#define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007A))
/* Internal temperature sensor, parameter TS_CAL2: TS ADC raw data acquired at
*a temperature of 30 DegC (+-5 DegC), VDDA = 3.3 V (+-10 mV). */
#define TEMP110_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007E))
/* Vdda value with which temperature sensor has been calibrated in production
(+-10 mV). */
#define VDDA_TEMP_CAL ((uint32_t) 3000)
/*!
* Flag to indicate if the MCU is Initialized
*/
static bool McuInitialized = false;
/**
* @brief This function initializes the hardware
* @param None
* @retval None
*/
void HW_Init( void )
{
if( McuInitialized == false )
{
#if defined( USE_BOOTLOADER )
/* Set the Vector Table base location at 0x3000 */
NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x3000 );
#endif
HW_AdcInit( );
Radio.IoInit( );
HW_SPI_Init( );
HW_RTC_Init( );
vcom_Init( );
McuInitialized = true;
}
}
/**
* @brief This function Deinitializes the hardware
* @param None
* @retval None
*/
void HW_DeInit( void )
{
HW_SPI_DeInit( );
Radio.IoDeInit( );
vcom_DeInit( );
McuInitialized = false;
}
/**
* @brief This function Initializes the hardware Ios
* @param None
* @retval None
*/
static void HW_IoInit( void )
{
HW_SPI_IoInit( );
Radio.IoInit( );
vcom_IoInit( );
}
/**
* @brief This function Deinitializes the hardware Ios
* @param None
* @retval None
*/
static void HW_IoDeInit( void )
{
HW_SPI_IoDeInit( );
Radio.IoDeInit( );
vcom_IoDeInit( );
}
void HW_GpioInit(void)
{
/* STM32L0 Gpios are all already configured in analog input at nReset*/
}
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (HSI)
* SYSCLK(Hz) = 32000000
* HCLK(Hz) = 32000000
* AHB Prescaler = 1
* APB1 Prescaler = 1
* APB2 Prescaler = 1
* HSI Frequency(Hz) = 16000000
* PLLMUL = 6
* PLLDIV = 3
* Flash Latency(WS) = 1
* @retval None
*/
void SystemClock_Config( void )
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
/* Enable HSE Oscillator and Activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Set Voltage scale1 as MCU will run at 32MHz */
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0 */
while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOS) != RESET) {};
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief This function return a random seed
* @note based on the device unique ID
* @param None
* @retval see
*/
uint32_t HW_GetRandomSeed( void )
{
return ( ( *( uint32_t* )ID1 ) ^ ( *( uint32_t* )ID2 ) ^ ( *( uint32_t* )ID3 ) );
}
/**
* @brief This function return a unique ID
* @param unique ID
* @retval none
*/
void HW_GetUniqueId( uint8_t *id )
{
id[7] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 24;
id[6] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 16;
id[5] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) ) >> 8;
id[4] = ( ( *( uint32_t* )ID1 )+ ( *( uint32_t* )ID3 ) );
id[3] = ( ( *( uint32_t* )ID2 ) ) >> 24;
id[2] = ( ( *( uint32_t* )ID2 ) ) >> 16;
id[1] = ( ( *( uint32_t* )ID2 ) ) >> 8;
id[0] = ( ( *( uint32_t* )ID2 ) );
}
/**
* @brief Enters Low Power Stop Mode
* @note ARM exists the function when waking up
* @param none
* @retval none
*/
void HW_EnterStopMode( void)
{
BACKUP_PRIMASK();
DISABLE_IRQ( );
HW_IoDeInit( );
/*clear wake up flag*/
SET_BIT(PWR->CR, PWR_CR_CWUF);
RESTORE_PRIMASK( );
/* Enter Stop Mode */
HAL_PWR_EnterSTOPMode ( PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI );
}
/**
* @brief Exists Low Power Stop Mode
* @note Enable the pll at 32MHz
* @param none
* @retval none
*/
void HW_ExitStopMode( void)
{
/* Disable IRQ while the MCU is not running on HSI */
BACKUP_PRIMASK();
DISABLE_IRQ( );
/* After wake-up from STOP reconfigure the system clock */
/* Enable HSI */
__HAL_RCC_HSI_ENABLE();
/* Wait till HSI is ready */
while( __HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET ) {}
/* Enable PLL */
__HAL_RCC_PLL_ENABLE();
/* Wait till PLL is ready */
while( __HAL_RCC_GET_FLAG( RCC_FLAG_PLLRDY ) == RESET ) {}
/* Select PLL as system clock source */
__HAL_RCC_SYSCLK_CONFIG ( RCC_SYSCLKSOURCE_PLLCLK );
/* Wait till PLL is used as system clock source */
while( __HAL_RCC_GET_SYSCLK_SOURCE( ) != RCC_SYSCLKSOURCE_STATUS_PLLCLK ) {}
/*initilizes the peripherals*/
HW_IoInit( );
RESTORE_PRIMASK( );
}
/**
* @brief Enters Low Power Sleep Mode
* @note ARM exits the function when waking up
* @param none
* @retval none
*/
void HW_EnterSleepMode( void)
{
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/