Files
TencentOS-tiny/board/RHF76_STM32L072CBxx_Lora/Src/board.c
supowang edb2879617 first commit for opensource
first commit for opensource
2019-09-16 13:19:50 +08:00

487 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*!
* \file board.c
*
* \brief Target board general functions implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*/
#include "stm32l0xx.h"
#include "utilities.h"
#include "gpio.h"
#include "adc.h"
#include "spi.h"
#include "i2c.h"
#include "uart.h"
#include "timer.h"
#include "board-config.h"
#include "lpm-board.h"
#include "rtc-board.h"
#include "sx1276-board.h"
#include "board.h"
#include "tos.h"
/*!
* Unique Devices IDs register set ( STM32L0xxx )
*/
#define ID1 ( 0x1FF80050 )
#define ID2 ( 0x1FF80054 )
#define ID3 ( 0x1FF80064 )
/*!
* LED GPIO pins objects
*/
Gpio_t Led1;
Gpio_t Led2;
Gpio_t Led3;
Gpio_t Led4;
/*
* MCU objects
*/
Uart_t Uart1;
/*!
* Initializes the unused GPIO to a know status
*/
static void BoardUnusedIoInit( void );
/*!
* System Clock Configuration
*/
static void SystemClockConfig( void );
/*!
* Used to measure and calibrate the system wake-up time from STOP mode
*/
static void CalibrateSystemWakeupTime( void );
/*!
* System Clock Re-Configuration when waking up from STOP mode
*/
static void SystemClockReConfig( void );
/*!
* Timer used at first boot to calibrate the SystemWakeupTime
*/
static TimerEvent_t CalibrateSystemWakeupTimeTimer;
/*!
* Flag to indicate if the MCU is Initialized
*/
static bool McuInitialized = false;
/*!
* Flag used to indicate if board is powered from the USB
*/
static bool UsbIsConnected = false;
/*!
* UART2 FIFO buffers size
*/
#define UART1_FIFO_TX_SIZE 1024
#define UART1_FIFO_RX_SIZE 1024
uint8_t Uart1TxBuffer[UART1_FIFO_TX_SIZE];
uint8_t Uart1RxBuffer[UART1_FIFO_RX_SIZE];
/*!
* Flag to indicate if the SystemWakeupTime is Calibrated
*/
static volatile bool SystemWakeupTimeCalibrated = false;
/*!
* Callback indicating the end of the system wake-up time calibration
*/
static void OnCalibrateSystemWakeupTimeTimerEvent( void* context )
{
RtcSetMcuWakeUpTime( );
SystemWakeupTimeCalibrated = true;
}
void BoardCriticalSectionBegin( uint32_t *mask )
{
*mask = __get_PRIMASK( );
__disable_irq( );
}
void BoardCriticalSectionEnd( uint32_t *mask )
{
__set_PRIMASK( *mask );
}
void BoardInitPeriph( void )
{
}
void BoardInitMcu( void )
{
if( McuInitialized == false )
{
HAL_Init( );
// LEDs
GpioInit( &Led1, LED_1, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
GpioInit( &Led2, LED_2, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
GpioInit( &Led3, LED_3, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
GpioInit( &Led4, LED_4, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
SystemClockConfig( );
UsbIsConnected = true;
FifoInit( &Uart1.FifoTx, Uart1TxBuffer, UART1_FIFO_TX_SIZE );
FifoInit( &Uart1.FifoRx, Uart1RxBuffer, UART1_FIFO_RX_SIZE );
// Configure your terminal for 8 Bits data (7 data bit + 1 parity bit), no parity and no flow ctrl
UartInit( &Uart1, UART_1, UART_TX, UART_RX );
UartConfig( &Uart1, RX_TX, 115200, UART_8_BIT, UART_1_STOP_BIT, NO_PARITY, NO_FLOW_CTRL );
RtcInit( );
GpioWrite( &Led1, 0 );
GpioWrite( &Led2, 0 );
GpioWrite( &Led3, 0 );
GpioWrite( &Led4, 0 );
BoardUnusedIoInit( );
if( GetBoardPowerSource( ) == BATTERY_POWER )
{
// Disables OFF mode - Enables lowest power mode (STOP)
LpmSetOffMode( LPM_APPLI_ID, LPM_DISABLE );
}
}
else
{
SystemClockReConfig( );
}
SpiInit( &SX1276.Spi, SPI_1, RADIO_MOSI, RADIO_MISO, RADIO_SCLK, NC );
SX1276IoInit( );
if( McuInitialized == false )
{
McuInitialized = true;
if( GetBoardPowerSource( ) == BATTERY_POWER )
{
CalibrateSystemWakeupTime( );
}
}
}
void BoardResetMcu( void )
{
CRITICAL_SECTION_BEGIN( );
//Restart system
NVIC_SystemReset( );
}
void BoardDeInitMcu( void )
{
SpiDeInit( &SX1276.Spi );
SX1276IoDeInit( );
}
uint32_t BoardGetRandomSeed( void )
{
return ( ( *( uint32_t* )ID1 ) ^ ( *( uint32_t* )ID2 ) ^ ( *( uint32_t* )ID3 ) );
}
void BoardGetUniqueId( 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 ) );
}
uint16_t BoardBatteryMeasureVolage( void )
{
return 0;
}
uint32_t BoardGetBatteryVoltage( void )
{
return 0;
}
uint8_t BoardGetBatteryLevel( void )
{
return 0;
}
static void BoardUnusedIoInit( void )
{
HAL_DBGMCU_EnableDBGSleepMode( );
HAL_DBGMCU_EnableDBGStopMode( );
HAL_DBGMCU_EnableDBGStandbyMode( );
}
void SystemClockConfig( void )
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
__HAL_RCC_PWR_CLK_ENABLE( );
__HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_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 )
{
assert_param( FAIL );
}
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 )
{
assert_param( FAIL );
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
if( HAL_RCCEx_PeriphCLKConfig( &PeriphClkInit ) != HAL_OK )
{
assert_param( FAIL );
}
HAL_SYSTICK_Config( HAL_RCC_GetHCLKFreq( ) / 1000 );
HAL_SYSTICK_CLKSourceConfig( SYSTICK_CLKSOURCE_HCLK );
// SysTick_IRQn interrupt configuration
HAL_NVIC_SetPriority( SysTick_IRQn, 0, 0 );
}
void CalibrateSystemWakeupTime( void )
{
if( SystemWakeupTimeCalibrated == false )
{
TimerInit( &CalibrateSystemWakeupTimeTimer, OnCalibrateSystemWakeupTimeTimerEvent );
TimerSetValue( &CalibrateSystemWakeupTimeTimer, 1000 );
TimerStart( &CalibrateSystemWakeupTimeTimer );
while( SystemWakeupTimeCalibrated == false )
{
}
}
}
void SystemClockReConfig( void )
{
__HAL_RCC_PWR_CLK_ENABLE( );
__HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );
// Enable HSI
__HAL_RCC_HSI_CONFIG( RCC_HSI_ON );
// 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 )
{
}
}
void SysTick_Handler( void )
{
HAL_IncTick( );
if(tos_knl_is_running()) //OS<4F><53>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>,<2C><>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ȴ<EFBFBD><C8B4><EFBFBD>
{
tos_knl_irq_enter(); //<2F><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
tos_tick_handler(); //<2F><><EFBFBD><EFBFBD>ucos<6F><73>ʱ<EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tos_knl_irq_leave(); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD>ж<EFBFBD>
}
//HAL_SYSTICK_IRQHandler( );
}
uint8_t GetBoardPowerSource( void )
{
if( UsbIsConnected == false )
{
return BATTERY_POWER;
}
else
{
return USB_POWER;
}
}
/**
* \brief Enters Low Power Stop Mode
*
* \note ARM exists the function when waking up
*/
void LpmEnterStopMode( void)
{
CRITICAL_SECTION_BEGIN( );
BoardDeInitMcu( );
// Disable the Power Voltage Detector
HAL_PWR_DisablePVD( );
// Clear wake up flag
SET_BIT( PWR->CR, PWR_CR_CWUF );
// Enable Ultra low power mode
HAL_PWREx_EnableUltraLowPower( );
// Enable the fast wake up from Ultra low power mode
HAL_PWREx_EnableFastWakeUp( );
CRITICAL_SECTION_END( );
// Enter Stop Mode
HAL_PWR_EnterSTOPMode( PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI );
}
/*!
* \brief Exists Low Power Stop Mode
*/
void LpmExitStopMode( void )
{
// Disable IRQ while the MCU is not running on HSI
CRITICAL_SECTION_BEGIN( );
// Initilizes the peripherals
BoardInitMcu( );
CRITICAL_SECTION_END( );
}
/*!
* \brief Enters Low Power Sleep Mode
*
* \note ARM exits the function when waking up
*/
void LpmEnterSleepMode( void)
{
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
void BoardLowPowerHandler( void )
{
__disable_irq( );
/*!
* If an interrupt has occurred after __disable_irq( ), it is kept pending
* and cortex will not enter low power anyway
*/
LpmEnterLowPower( );
__enable_irq( );
}
#if !defined ( __CC_ARM )
/*
* Function to be used by stdout for printf etc
*/
int _write( int fd, const void *buf, size_t count )
{
while( UartPutBuffer( &Uart1, ( uint8_t* )buf, ( uint16_t )count ) != 0 ){ };
return count;
}
/*
* Function to be used by stdin for scanf etc
*/
int _read( int fd, const void *buf, size_t count )
{
size_t bytesRead = 0;
while( UartGetBuffer( &Uart1, ( uint8_t* )buf, count, ( uint16_t* )&bytesRead ) != 0 ){ };
// Echo back the character
while( UartPutBuffer( &Uart1, ( uint8_t* )buf, ( uint16_t )bytesRead ) != 0 ){ };
return bytesRead;
}
#else
// Keil compiler
int fputc( int c, FILE *stream )
{
while( UartPutChar( &Uart1, ( uint8_t )c ) != 0 );
return c;
}
int fgetc( FILE *stream )
{
uint8_t c = 0;
while( UartGetChar( &Uart1, &c ) != 0 );
// Echo back the character
while( UartPutChar( &Uart1, c ) != 0 );
return ( int )c;
}
#endif
#ifdef USE_FULL_ASSERT
/*
* Function Name : assert_failed
* Description : Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* Input : - file: pointer to the source file name
* - line: assert_param error line source number
* Output : None
* Return : None
*/
void assert_failed( uint8_t* file, uint32_t line )
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %lu\r\n", file, line) */
printf( "Wrong parameters value: file %s on line %lu\r\n", ( const char* )file, line );
/* Infinite loop */
while( 1 )
{
}
}
#endif