Changeset - f2f8cb2bebfa
[Not reviewed]
default
0 6 0
Ethan Zonca - 7 years ago 2019-09-02 13:57:33
ez@ethanzonca.com
1hz RTC interrupt and STOP mode works! Now idling at 0.8mA or so!
6 files changed with 44 insertions and 12 deletions:
0 comments (0 inline, 0 general)
drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h
Show inline comments
 
@@ -336,226 +336,227 @@
 
#define __HAL_DBGMCU_FREEZE_TIM16()          (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM16_STOP))
 
#define __HAL_DBGMCU_UNFREEZE_TIM16()        (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM16_STOP))
 
#endif /* DBGMCU_APB2_FZ_DBG_TIM16_STOP */
 
 
#if defined(DBGMCU_APB2_FZ_DBG_TIM17_STOP)
 
#define __HAL_DBGMCU_FREEZE_TIM17()          (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM17_STOP))
 
#define __HAL_DBGMCU_UNFREEZE_TIM17()        (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM17_STOP))
 
#endif /* DBGMCU_APB2_FZ_DBG_TIM17_STOP */
 
 
/**
 
  * @}
 
  */  
 
  
 
/** @defgroup Memory_Mapping_Selection Memory Mapping Selection
 
  * @{   
 
  */
 
#if defined(SYSCFG_CFGR1_MEM_MODE)
 
/** @brief  Main Flash memory mapped at 0x00000000
 
  */
 
#define __HAL_SYSCFG_REMAPMEMORY_FLASH()        (SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_MEM_MODE))
 
#endif /* SYSCFG_CFGR1_MEM_MODE */
 
 
#if defined(SYSCFG_CFGR1_MEM_MODE_0)
 
/** @brief  System Flash memory mapped at 0x00000000
 
  */
 
#define __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH()  do {SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_MEM_MODE); \
 
                                             SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE_0;  \
 
                                            }while(0)
 
#endif /* SYSCFG_CFGR1_MEM_MODE_0 */
 
 
#if defined(SYSCFG_CFGR1_MEM_MODE_0) && defined(SYSCFG_CFGR1_MEM_MODE_1)
 
/** @brief  Embedded SRAM mapped at 0x00000000
 
  */
 
#define __HAL_SYSCFG_REMAPMEMORY_SRAM()         do {SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_MEM_MODE); \
 
                                             SYSCFG->CFGR1 |= (SYSCFG_CFGR1_MEM_MODE_0 | SYSCFG_CFGR1_MEM_MODE_1); \
 
                                            }while(0) 
 
#endif /* SYSCFG_CFGR1_MEM_MODE_0 && SYSCFG_CFGR1_MEM_MODE_1 */
 
/**
 
  * @}
 
  */ 
 
 
 
#if defined(SYSCFG_CFGR1_PA11_PA12_RMP)
 
/** @defgroup HAL_Pin_remap HAL Pin remap 
 
  * @brief  Pin remapping enable/disable macros
 
  * @param __PIN_REMAP__: This parameter can be a value of @ref HAL_Pin_remapping
 
  * @{   
 
  */
 
#define __HAL_REMAP_PIN_ENABLE(__PIN_REMAP__)          do {assert_param(IS_HAL_REMAP_PIN((__PIN_REMAP__)));                 \
 
                                                           SYSCFG->CFGR1 |= (__PIN_REMAP__);                                \
 
                                                         }while(0)
 
#define __HAL_REMAP_PIN_DISABLE(__PIN_REMAP__)         do {assert_param(IS_HAL_REMAP_PIN((__PIN_REMAP__)));                 \
 
                                                           SYSCFG->CFGR1 &= ~(__PIN_REMAP__);                               \
 
                                                         }while(0)
 
/**
 
  * @}
 
  */  
 
#endif /* SYSCFG_CFGR1_PA11_PA12_RMP */
 
 
/** @brief  Fast-mode Plus driving capability enable/disable macros
 
  * @param __FASTMODEPLUS__: This parameter can be a value of @ref SYSCFG_FastModePlus_GPIO values.
 
  *                          That you can find above these macros.
 
  */
 
#define __HAL_SYSCFG_FASTMODEPLUS_ENABLE(__FASTMODEPLUS__)  do {assert_param(IS_SYSCFG_FASTMODEPLUS((__FASTMODEPLUS__)));\
 
                                                                SET_BIT(SYSCFG->CFGR1, (__FASTMODEPLUS__));\
 
                                                               }while(0)
 
 
#define __HAL_SYSCFG_FASTMODEPLUS_DISABLE(__FASTMODEPLUS__) do {assert_param(IS_SYSCFG_FASTMODEPLUS((__FASTMODEPLUS__)));\
 
                                                                CLEAR_BIT(SYSCFG->CFGR1, (__FASTMODEPLUS__));\
 
                                                               }while(0)
 
#if defined(SYSCFG_CFGR2_LOCKUP_LOCK)
 
/** @defgroup Cortex_Lockup_Enable Cortex Lockup Enable
 
  * @{   
 
  */
 
/** @brief  SYSCFG Break Lockup lock
 
  *         Enables and locks the connection of Cortex-M0 LOCKUP (Hardfault) output to TIM1/15/16/17 Break input
 
  * @note   The selected configuration is locked and can be unlocked by system reset
 
  */
 
#define __HAL_SYSCFG_BREAK_LOCKUP_LOCK()   do {SYSCFG->CFGR2 &= ~(SYSCFG_CFGR2_LOCKUP_LOCK); \
 
                                               SYSCFG->CFGR2 |= SYSCFG_CFGR2_LOCKUP_LOCK;    \
 
                                              }while(0)
 
/**
 
  * @}
 
  */  
 
#endif /* SYSCFG_CFGR2_LOCKUP_LOCK */
 
 
#if defined(SYSCFG_CFGR2_PVD_LOCK)
 
/** @defgroup PVD_Lock_Enable PVD Lock
 
  * @{  
 
  */
 
/** @brief  SYSCFG Break PVD lock
 
  *         Enables and locks the PVD connection with Timer1/8/15/16/17 Break Input, , as well as the PVDE and PLS[2:0] in the PWR_CR register
 
  * @note   The selected configuration is locked and can be unlocked by system reset
 
  */
 
#define __HAL_SYSCFG_BREAK_PVD_LOCK()      do {SYSCFG->CFGR2 &= ~(SYSCFG_CFGR2_PVD_LOCK); \
 
                                               SYSCFG->CFGR2 |= SYSCFG_CFGR2_PVD_LOCK;    \
 
                                              }while(0)
 
/**
 
  * @}
 
  */
 
#endif /* SYSCFG_CFGR2_PVD_LOCK */
 
 
#if defined(SYSCFG_CFGR2_SRAM_PARITY_LOCK)
 
/** @defgroup SRAM_Parity_Lock SRAM Parity Lock
 
  * @{
 
  */
 
/** @brief  SYSCFG Break SRAM PARITY lock
 
  *         Enables and locks the SRAM_PARITY error signal with Break Input of TIMER1/8/15/16/17
 
  * @note   The selected configuration is locked and can be unlocked by system reset
 
  */
 
#define __HAL_SYSCFG_BREAK_SRAMPARITY_LOCK() do {SYSCFG->CFGR2 &= ~(SYSCFG_CFGR2_SRAM_PARITY_LOCK); \
 
                                                 SYSCFG->CFGR2 |= SYSCFG_CFGR2_SRAM_PARITY_LOCK;    \
 
                                                }while(0)
 
/**
 
  * @}
 
  */
 
#endif /* SYSCFG_CFGR2_SRAM_PARITY_LOCK */
 
 
#if defined(SYSCFG_CFGR2_SRAM_PEF)
 
/** @defgroup HAL_SYSCFG_Parity_check_on_RAM HAL SYSCFG Parity check on RAM
 
  * @brief  Parity check on RAM disable macro
 
  * @note   Disabling the parity check on RAM locks the configuration bit.
 
  *         To re-enable the parity check on RAM perform a system reset.
 
  * @{  
 
  */
 
#define __HAL_SYSCFG_RAM_PARITYCHECK_DISABLE()   (SYSCFG->CFGR2 |= SYSCFG_CFGR2_SRAM_PEF)
 
/**
 
  * @}
 
  */
 
#endif /* SYSCFG_CFGR2_SRAM_PEF */
 
 
 
#if defined(STM32F091xC) || defined (STM32F098xx)
 
/** @defgroup HAL_ISR_wrapper_check HAL ISR wrapper check
 
  * @brief  ISR wrapper check
 
  * @note This feature is applicable on STM32F09x  
 
  * @note Allow to determine interrupt source per line.
 
  * @{  
 
  */
 
#define __HAL_GET_PENDING_IT(__SOURCE__)       (SYSCFG->IT_LINE_SR[((__SOURCE__) >> 0x18)] & ((__SOURCE__) & 0x00FFFFFF))
 
/**
 
  * @}
 
  */
 
#endif /* (STM32F091xC) || defined (STM32F098xx)*/
 
 
#if defined(STM32F091xC) || defined (STM32F098xx)
 
/** @defgroup HAL_SYSCFG_IRDA_modulation_envelope_selection HAL SYSCFG IRDA modulation envelope selection
 
  * @brief  selection of the modulation envelope signal macro, using bits [7:6] of SYS_CTRL(CFGR1) register
 
  * @note This feature is applicable on STM32F09x
 
  * @param __SOURCE__: This parameter can be a value of @ref HAL_IRDA_ENV_SEL
 
  * @{  
 
  */
 
#define __HAL_SYSCFG_IRDA_ENV_SELECTION(__SOURCE__)  do {assert_param(IS_HAL_SYSCFG_IRDA_ENV_SEL((__SOURCE__))); \
 
                                                         SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_IRDA_ENV_SEL); \
 
                                                         SYSCFG->CFGR1 |= (__SOURCE__);    \
 
                                                        }while(0)
 
 
#define __HAL_SYSCFG_GET_IRDA_ENV_SELECTION()  ((SYSCFG->CFGR1) & 0x000000C0)
 
/**
 
  * @}
 
  */
 
#endif /* (STM32F091xC) || defined (STM32F098xx)*/
 
 
/**
 
  * @}
 
  */  
 
  
 
/* Exported functions --------------------------------------------------------*/
 
 
/** @addtogroup HAL_Exported_Functions
 
  * @{
 
  */
 
 
/** @addtogroup HAL_Exported_Functions_Group1
 
  * @{
 
  */    
 
/* Initialization and de-initialization functions  ******************************/
 
HAL_StatusTypeDef HAL_Init(void);
 
HAL_StatusTypeDef HAL_DeInit(void);
 
void              HAL_MspInit(void);
 
void              HAL_MspDeInit(void);
 
HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority);
 
/**
 
  * @}
 
  */  
 
 
/** @addtogroup HAL_Exported_Functions_Group2
 
  * @{
 
  */    
 
 
/* Peripheral Control functions  ************************************************/
 
void              HAL_IncTick(void);
 
void 			  HAL_IncTickBy(uint32_t increment); // emz
 
void              HAL_Delay(__IO uint32_t Delay);
 
uint32_t          HAL_GetTick(void);
 
void              HAL_SuspendTick(void);
 
void              HAL_ResumeTick(void);
 
uint32_t          HAL_GetHalVersion(void);
 
uint32_t          HAL_GetREVID(void);
 
uint32_t          HAL_GetDEVID(void);
 
void              HAL_DBGMCU_EnableDBGStopMode(void);
 
void              HAL_DBGMCU_DisableDBGStopMode(void);
 
void              HAL_DBGMCU_EnableDBGStandbyMode(void);
 
void              HAL_DBGMCU_DisableDBGStandbyMode(void);
 
/**
 
  * @}
 
  */ 
 
 
/**
 
  * @}
 
  */
 
 
/**
 
  * @}
 
  */ 
 
 
/**
 
  * @}
 
  */
 
 
#ifdef __cplusplus
 
}
 
#endif
 
 
#endif /* __STM32F0xx_HAL_H */
 
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c
Show inline comments
 
@@ -99,337 +99,343 @@
 
  * @{
 
  */
 
static __IO uint32_t uwTick;
 
/**
 
  * @}
 
  */
 
/* Private function prototypes -----------------------------------------------*/
 
/* Exported functions ---------------------------------------------------------*/
 
 
/** @defgroup HAL_Exported_Functions HAL Exported Functions
 
  * @{
 
  */
 
 
/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions 
 
  * @brief    Initialization and de-initialization functions
 
  *
 
@verbatim
 
 ===============================================================================
 
              ##### Initialization and de-initialization functions #####
 
 ===============================================================================
 
   [..]  This section provides functions allowing to:
 
      (+) Initializes the Flash interface, the NVIC allocation and initial clock 
 
          configuration. It initializes the source of time base also when timeout 
 
          is needed and the backup domain when enabled.
 
      (+) de-Initializes common part of the HAL.
 
      (+) Configure The time base source to have 1ms time base with a dedicated 
 
          Tick interrupt priority. 
 
        (++) Systick timer is used by default as source of time base, but user 
 
             can eventually implement his proper time base source (a general purpose 
 
             timer for example or other time source), keeping in mind that Time base 
 
             duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
 
             handled in milliseconds basis.
 
        (++) Time base configuration function (HAL_InitTick ()) is called automatically 
 
             at the beginning of the program after reset by HAL_Init() or at any time 
 
             when clock is configured, by HAL_RCC_ClockConfig(). 
 
        (++) Source of time base is configured  to generate interrupts at regular 
 
             time intervals. Care must be taken if HAL_Delay() is called from a 
 
             peripheral ISR process, the Tick interrupt line must have higher priority 
 
            (numerically lower) than the peripheral interrupt. Otherwise the caller 
 
            ISR process will be blocked. 
 
       (++) functions affecting time base configurations are declared as __Weak  
 
             to make  override possible  in case of other  implementations in user file.
 
 
 
@endverbatim
 
  * @{
 
  */
 
 
/**
 
  * @brief  This function configures the Flash prefetch,
 
  *        Configures time base source, NVIC and Low level hardware
 
  * @note This function is called at the beginning of program after reset and before 
 
  *       the clock configuration
 
  * @note The time base configuration is based on HSI clock when exiting from Reset.
 
  *       Once done, time base tick start incrementing.
 
  *       In the default implementation,Systick is used as source of time base.
 
  *       The tick variable is incremented each 1ms in its ISR.
 
  * @retval HAL status
 
  */
 
HAL_StatusTypeDef HAL_Init(void)
 
{
 
  /* Configure Flash prefetch */ 
 
#if (PREFETCH_ENABLE != 0)
 
  __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
 
#endif /* PREFETCH_ENABLE */
 
 
  /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
 
 
  HAL_InitTick(TICK_INT_PRIORITY);
 
 
  /* Init the low level hardware */
 
  HAL_MspInit();
 
 
  /* Return function status */
 
  return HAL_OK;
 
}
 
 
/**
 
  * @brief This function de-Initializes common part of the HAL and stops the source
 
  *        of time base.
 
  * @note This function is optional.
 
  * @retval HAL status
 
  */
 
HAL_StatusTypeDef HAL_DeInit(void)
 
{
 
  /* Reset of all peripherals */
 
  __HAL_RCC_APB1_FORCE_RESET();
 
  __HAL_RCC_APB1_RELEASE_RESET();
 
 
  __HAL_RCC_APB2_FORCE_RESET();
 
  __HAL_RCC_APB2_RELEASE_RESET();
 
 
  __HAL_RCC_AHB_FORCE_RESET();
 
  __HAL_RCC_AHB_RELEASE_RESET();
 
 
  /* De-Init the low level hardware */
 
  HAL_MspDeInit();
 
    
 
  /* Return function status */
 
  return HAL_OK;
 
}
 
 
/**
 
  * @brief  Initializes the MSP.
 
  * @retval None
 
  */
 
__weak void HAL_MspInit(void)
 
{
 
  /* NOTE : This function Should not be modified, when the callback is needed,
 
            the HAL_MspInit could be implemented in the user file
 
   */
 
}
 
 
/**
 
  * @brief  DeInitializes the MSP.
 
  * @retval None
 
  */
 
__weak void HAL_MspDeInit(void)
 
{
 
  /* NOTE : This function Should not be modified, when the callback is needed,
 
            the HAL_MspDeInit could be implemented in the user file
 
   */
 
}
 
 
/**
 
  * @brief This function configures the source of the time base. 
 
  *        The time source is configured  to have 1ms time base with a dedicated 
 
  *        Tick interrupt priority.
 
  * @note This function is called  automatically at the beginning of program after
 
  *       reset by HAL_Init() or at any time when clock is reconfigured  by HAL_RCC_ClockConfig(). 
 
  * @note In the default implementation, SysTick timer is the source of time base. 
 
  *       It is used to generate interrupts at regular time intervals. 
 
  *       Care must be taken if HAL_Delay() is called from a peripheral ISR process, 
 
  *       The the SysTick interrupt must have higher priority (numerically lower) 
 
  *       than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
 
  *       The function is declared as __Weak  to be overwritten  in case of other
 
  *       implementation  in user file.
 
  * @param TickPriority: Tick interrupt priority.
 
  * @retval HAL status
 
  */
 
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
 
{
 
  /*Configure the SysTick to have interrupt in 1ms time basis*/
 
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 
 
  /*Configure the SysTick IRQ priority */
 
  HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0);
 
 
   /* Return function status */
 
  return HAL_OK;
 
}
 
 
/**
 
  * @}
 
  */
 
 
/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions 
 
  * @brief    HAL Control functions
 
  *
 
@verbatim
 
 ===============================================================================
 
                      ##### HAL Control functions #####
 
 ===============================================================================
 
    [..]  This section provides functions allowing to:
 
      (+) Provide a tick value in millisecond
 
      (+) Provide a blocking delay in millisecond
 
      (+) Suspend the time base source interrupt
 
      (+) Resume the time base source interrupt
 
      (+) Get the HAL API driver version
 
      (+) Get the device identifier
 
      (+) Get the device revision identifier
 
      (+) Enable/Disable Debug module during Sleep mode
 
      (+) Enable/Disable Debug module during STOP mode
 
      (+) Enable/Disable Debug module during STANDBY mode
 
      
 
@endverbatim
 
  * @{
 
  */
 
 
/**
 
  * @brief This function is called to increment  a global variable "uwTick"
 
  *        used as application time base.
 
  * @note In the default implementation, this variable is incremented each 1ms
 
  *       in Systick ISR.
 
  * @note This function is declared as __weak to be overwritten in case of other 
 
  *       implementations in user file.
 
  * @retval None
 
  */
 
__weak void HAL_IncTick(void)
 
{
 
  uwTick++;
 
}
 
 
// emz
 
__weak void HAL_IncTickBy(uint32_t increment)
 
{
 
	uwTick += increment;
 
}
 
 
/**
 
  * @brief  Provides a tick value in millisecond.
 
  * @note   This function is declared as __weak  to be overwritten  in case of other 
 
  *       implementations in user file.
 
  * @retval tick value
 
  */
 
__weak uint32_t HAL_GetTick(void)
 
{
 
  return uwTick;
 
}
 
 
/**
 
  * @brief This function provides accurate delay (in milliseconds) based 
 
  *        on variable incremented.
 
  * @note In the default implementation , SysTick timer is the source of time base.
 
  *       It is used to generate interrupts at regular time intervals where uwTick
 
  *       is incremented.
 
  * @note ThiS function is declared as __weak to be overwritten in case of other
 
  *       implementations in user file.
 
  * @param Delay: specifies the delay time length, in milliseconds.
 
  * @retval None
 
  */
 
__weak void HAL_Delay(__IO uint32_t Delay)
 
{
 
  uint32_t tickstart = 0;
 
  tickstart = HAL_GetTick();
 
  while((HAL_GetTick() - tickstart) < Delay)
 
  {
 
  }
 
}
 
 
/**
 
  * @brief Suspend Tick increment.
 
  * @note In the default implementation , SysTick timer is the source of time base. It is
 
  *       used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
 
  *       is called, the the SysTick interrupt will be disabled and so Tick increment 
 
  *       is suspended.
 
  * @note This function is declared as __weak to be overwritten in case of other
 
  *       implementations in user file.
 
  * @retval None
 
  */
 
__weak void HAL_SuspendTick(void)
 
 
{
 
  /* Disable SysTick Interrupt */
 
  CLEAR_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk);
 
}
 
 
/**
 
  * @brief Resume Tick increment.
 
  * @note In the default implementation , SysTick timer is the source of time base. It is
 
  *       used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
 
  *       is called, the the SysTick interrupt will be enabled and so Tick increment 
 
  *       is resumed.
 
  * @note This function is declared as __weak  to be overwritten  in case of other
 
  *       implementations in user file.
 
  * @retval None
 
  */
 
__weak void HAL_ResumeTick(void)
 
{
 
  /* Enable SysTick Interrupt */
 
  SET_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk);
 
}
 
 
/**
 
  * @brief  This method returns the HAL revision
 
  * @retval version : 0xXYZR (8bits for each decimal, R for RC)
 
  */
 
uint32_t HAL_GetHalVersion(void)
 
{
 
 return __STM32F0xx_HAL_VERSION;
 
}
 
 
/**
 
  * @brief  Returns the device revision identifier.
 
  * @retval Device revision identifier
 
  */
 
uint32_t HAL_GetREVID(void)
 
{
 
   return((DBGMCU->IDCODE) >> 16);
 
}
 
 
/**
 
  * @brief  Returns the device identifier.
 
  * @retval Device identifier
 
  */
 
uint32_t HAL_GetDEVID(void)
 
{
 
   return((DBGMCU->IDCODE) & IDCODE_DEVID_MASK);
 
}
 
 
/**
 
  * @brief  Enable the Debug Module during STOP mode       
 
  * @retval None
 
  */
 
void HAL_DBGMCU_EnableDBGStopMode(void)
 
{
 
  SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
 
}
 
 
/**
 
  * @brief  Disable the Debug Module during STOP mode       
 
  * @retval None
 
  */
 
void HAL_DBGMCU_DisableDBGStopMode(void)
 
{
 
  CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
 
}
 
 
/**
 
  * @brief  Enable the Debug Module during STANDBY mode       
 
  * @retval None
 
  */
 
void HAL_DBGMCU_EnableDBGStandbyMode(void)
 
{
 
  SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
 
}
 
 
/**
 
  * @brief  Disable the Debug Module during STANDBY mode       
 
  * @retval None
 
  */
 
void HAL_DBGMCU_DisableDBGStandbyMode(void)
 
{
 
  CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
 
}
 
 
/**
 
  * @}
 
  */
 
 
/**
 
  * @}
 
  */
 
 
#endif /* HAL_MODULE_ENABLED */
 
/**
 
  * @}
 
  */
 
 
/**
 
  * @}
 
  */
 
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
inc/gpio.h
Show inline comments
 
#ifndef __gpio_H
 
#define __gpio_H
 
 
#include "stm32f0xx_hal.h"
 
 
 
enum _blinkrate
 
{
 
    BLINK_FAST = 50,
 
    BLINK_MED = 250, 
 
    BLINK_SLOW = 2000
 
    BLINK_SLOW = 2000,
 
	BLINK_DISABLE = 9999,
 
};
 
 
 
#define OSC_EN_Pin GPIO_PIN_1
 
#define OSC_EN_GPIO_Port GPIOF
 
#define OSC_NOTEN OSC_EN_GPIO_Port , OSC_EN_Pin
 
 
#define GPS_NEN_Pin GPIO_PIN_0
 
#define GPS_NEN_GPIO_Port GPIOF
 
#define GPS_NOTEN GPS_NEN_GPIO_Port , GPS_NEN_Pin
 
 
#define VBATT_SENSE_Pin GPIO_PIN_6
 
#define VBATT_SENSE_GPIO_Port GPIOA
 
 
#define LED_BLUE_Pin GPIO_PIN_0
 
#define LED_BLUE_GPIO_Port GPIOB
 
#define LED_BLUE LED_BLUE_GPIO_Port , LED_BLUE_Pin
 
 
#define TCXO_EN_Pin GPIO_PIN_8
 
#define TCXO_EN_GPIO_Port GPIOA
 
#define TCXO_EN TCXO_EN_GPIO_Port  , TCXO_EN_Pin
 
 
 
void gpio_init(void);
 
void led_blink(uint8_t n);
 
 
#endif 
 
inc/rtc.h
Show inline comments
 
#ifndef __rtc_H
 
#define __rtc_H
 
 
#include "stm32f0xx_hal.h"
 
 
 
void rtc_init(void);
 
RTC_TimeTypeDef* rtc_time(void);
 
RTC_HandleTypeDef* rtc_gethandle(void);
 
 
 
#endif /*__ rtc_H */
src/main.c
Show inline comments
 
//
 
// WSPRHAB: Minimal high-altitude balloon tracker with WSPR telemetry
 
//
 
 
#include "stm32f0xx_hal.h"
 
#include "adc.h"
 
#include "system.h"
 
#include "i2c.h"
 
#include "uart.h"
 
#include "gpio.h"
 
#include "wspr.h"
 
#include "rtc.h"
 
#include "gps.h"
 
#include "config.h"
 
 
 
// We have access to the 1PPS pin of the gps... could have trim routine for internal oscillator based on this when we have a fix
 
// Probable wake up 1 minute early -- 0.45min possible +/- on wakeup time with 15min sync intervals
 
 
 
// TODO: Add JT9 message with more grid locator digits + altitude + vbatt + temp
 
// MSG13charmax:
 
// 	X: gridloc
 
//  Y: altitude
 
//  Z: temperature
 
//  KD8TDF XXYYZZ // could use alt callsign thing
 
 
enum _state
 
{
 
    SYSTEM_IDLE = 0, // awaiting RTC interrupt for wakeup TODO wake up before scheduled time to get fix?
 
    SYSTEM_GPSACQ, // RTC interrupted
 
    SYSTEM_WSPRTX, // Wait for timeslot and actually transmit the message
 
};
 
 
static void __calc_gridloc(char *dst, double lat, double lon);
 
static void ledpulse(void);
 
 
uint32_t statled_ontime = 0;
 
 
 
int main(void)
 
{
 
    HAL_Init();
 
    HAL_Delay(1000); // startup delay before infinisleep
 
 
    sysclk_init();
 
    gpio_init();
 
    rtc_init();
 
    adc_init();
 
    wspr_init();
 
 
    uint32_t led_timer = HAL_GetTick();
 
 
    led_blink(4);
 
 
    uint16_t blink_rate = BLINK_FAST;
 
//    uint8_t state = SYSTEM_GPSACQ;
 
    uint8_t state = SYSTEM_GPSACQ;
 
//DEBUG:
 
    uint8_t state = SYSTEM_IDLE;
 
//    uint8_t state = SYSTEM_IDLE;
 
 
    uint32_t gps_polltimer = 0;
 
    uint32_t fix_acq_starttime = 0;
 
    uint32_t nextwspr_time = 0;
 
    uint8_t nextwspr_time_valid = 0;
 
    uint32_t last_wspr_tx_time = 0;
 
 
    uint8_t packet_type = 0;
 
 
    // Transmit pilot tone to test TX on bootup
 
    HAL_Delay(1000);
 
    wspr_pilot_tone();
 
    adc_stop();
 
    HAL_Delay(1000);
 
 
    __DBGMCU_CLK_ENABLE() ; // (RCC->APB2ENR |= (RCC_APB2ENR_DBGMCUEN))
 
    HAL_EnableDBGStopMode();  //  SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
 
//    __DBGMCU_CLK_ENABLE() ; // (RCC->APB2ENR |= (RCC_APB2ENR_DBGMCUEN))
 
//    HAL_EnableDBGStopMode();  //  SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
 
 
    uint32_t idle_blink_last = 0;
 
 
    while (1)
 
    {
 
    	// TODO: Disable GPIO port clocking when not needed!
 
 
    	// Every 10 minutes, wake up and try to wspr
 
    	if(state == SYSTEM_IDLE && (HAL_GetTick() - last_wspr_tx_time > 60000 * 10))
 
    	{
 
    		state = SYSTEM_GPSACQ;
 
    	}
 
 
        // Update fix status every 2 seconds, only if the GPS is powered on
 
        if(HAL_GetTick() - gps_polltimer > 2000)
 
        {
 
            if(gps_ison())
 
            {
 
            	gps_update_data();
 
 
            	// If odd minute
 
            	if(gps_getdata()->minute % 2)
 
            	{
 
            		// Wait until even minute plus one second, coming soon
 
            		nextwspr_time = HAL_GetTick() + (60000 - (gps_getdata()->second * 1000));
 
                    nextwspr_time_valid = 1;
 
 
            	}
 
            	// If even minute
 
            	else
 
            	{
 
            		// Wait until odd minute, one minute and some change away
 
            		nextwspr_time = HAL_GetTick() + 60000 + (60000 - (gps_getdata()->second * 1000));
 
                    nextwspr_time_valid = 1;
 
            	}
 
            }
 
            gps_polltimer = HAL_GetTick();
 
        }
 
 
 
 
        switch(state)
 
        {
 
 
            // Idling: sleep and wait for RTC timeslot trigger
 
            case SYSTEM_IDLE:
 
            {
 
                blink_rate = BLINK_SLOW;
 
            	// Don't blink normally
 
                blink_rate = 9999; //BLINK_SLOW;
 
 
                // Actually sleep for real: disable systick and sleep until RTC interrupt
 
//                HAL_SuspendTick();
 
                // If we haven't blinked for a while, blink now
 
                if(HAL_GetTick() - idle_blink_last > 10 * 1000)
 
                {
 
                	HAL_GPIO_WritePin(LED_BLUE, 1);
 
                	HAL_Delay(20);
 
                	HAL_GPIO_WritePin(LED_BLUE, 0);
 
                	idle_blink_last = HAL_GetTick();
 
                }
 
 
                // Enter sleep mode: wait for interrupt
 
                //HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);
 
                __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
 
                HAL_SuspendTick();
 
 
        		HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
 
 
        		// We probably stopped for a second
 
        		HAL_IncTickBy(1000); // maybe check the RTC before and after this, increment tick by the delta?
 
                HAL_ResumeTick();
 
 
                // We have woken up! Clear wakeup flag
 
        		__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
 
 
                // This is hopefully the only timer that needs to stay alive in idle mode
 
 //               last_wspr_tx_time += 0; // move this timer forward based on sleep length
 
 
 //               HAL_ResumeTick();
 
 
                // TODO: Eventually use GPS time to calibrate the RTC maybe
 
 
            } break;
 
 
 
            // Attempt to acquire GPS fix
 
            case SYSTEM_GPSACQ:
 
            {
 
                blink_rate = BLINK_FAST;
 
                HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);
 
                HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);
 
                HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);
 
                HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);
 
 
 
                if(!gps_ison())
 
                {
 
                	fix_acq_starttime = HAL_GetTick();
 
                    gps_poweron(); // power on and initialize GPS module
 
                }
 
 
                // TODO: Move GPS processing into here from above!
 
 
 
                // If 3d fix with a decent enough precision
 
                if( ((gps_getdata()->fixtype == 2) || (gps_getdata()->fixtype == 3)) && gps_getdata()->pdop < 10 && nextwspr_time_valid == 1)
 
                {
 
                    // Disable GPS module
 
                    gps_poweroff();
 
 
                    // TODO: Set RTC from GPS time
 
 
                    // TODO: Set RTC for countdown to next transmission timeslot!
 
 
                    // TODO: Set wspr countdown timer for this transmission!
 
                    fix_acq_starttime = 0;
 
                    state = SYSTEM_WSPRTX;
 
                    adc_start();
 
                }
 
                // If no decent fix in 3 minutes
 
                else if(HAL_GetTick() - fix_acq_starttime > 60000 * 3)
 
                {
 
                	// Flash error code and go to idle, try again next time
 
                	led_blink(4);
 
                    gps_poweroff();
 
                    fix_acq_starttime = 0;
 
                    last_wspr_tx_time = HAL_GetTick(); // repeat acq/tx cycle after big time delay
 
                	state = SYSTEM_IDLE;
 
                }
 
            } break;
 
 
            
 
 
            // Wait for wspr timeslot and start transmitting
 
            case SYSTEM_WSPRTX:
 
            {
 
            	blink_rate = BLINK_MED;
 
                // Wait for wspr countdown timer to expire and go to tx
 
//                if(timeout_expired)
 
//                {
 
 
            	// If we're after the minute but not more than 2s after the minute, start tx
 
            	if(HAL_GetTick() >= nextwspr_time)
 
            	{
 
            		if(HAL_GetTick() < nextwspr_time + 2000)
 
            		{
 
            			volatile double latitude_flt = (double)gps_getdata()->latitude / 10000000.0;
 
            			volatile double longitude_flt = (double)gps_getdata()->longitude / 10000000.0;
 
            			volatile uint8_t grid_locator[7];
 
 
            			__calc_gridloc(grid_locator, latitude_flt, longitude_flt);
 
 
                        // TODO: Switch between alternate and standard packet
 
						wspr_transmit(grid_locator, packet_type);
 
                        packet_type = !packet_type; // alternate packet type
 
						last_wspr_tx_time = HAL_GetTick();
 
						state = SYSTEM_IDLE;
 
                        adc_stop();
 
            		}
 
            		else
 
            		{
 
            			// Window was missed, go back to idle, and try again after time delay
 
						last_wspr_tx_time = HAL_GetTick();
 
            			state = SYSTEM_IDLE;
 
                        adc_stop();
 
            		}
 
                    nextwspr_time_valid = 0; // invalidate wspr time
 
                }
 
            	else
 
            	{
 
                    HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);
 
                    HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);
 
                    HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);
 
                    HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);
 
            	}
 
 
                // Schedule next wakeup (maybe 2mins prior to timeslot if no osc trim)
 
                // Next wakeup should enter SYSTEM_GPSACQ state...
 
 
            } break;
 
 
        }
 
 
		#ifndef LED_DISABLE
 
			if(HAL_GetTick() - led_timer > blink_rate)
 
			if((blink_rate != BLINK_DISABLE) && (HAL_GetTick() - led_timer > blink_rate))
 
			{
 
				ledpulse();
 
				led_timer = HAL_GetTick();
 
			}
 
 
			if(statled_ontime && HAL_GetTick() - statled_ontime > 10)
 
			if((blink_rate != BLINK_DISABLE) && (statled_ontime && HAL_GetTick() - statled_ontime > 10))
 
			{
 
				HAL_GPIO_WritePin(LED_BLUE, 0);
 
				statled_ontime = 0;
 
			}
 
		#endif
 
 
    }
 
}
 
 
static void ledpulse(void)
 
{
 
    HAL_GPIO_WritePin(LED_BLUE, 1);
 
	statled_ontime = HAL_GetTick();
 
}
 
 
static void __calc_gridloc(char *dst, double lat, double lon)
 
{
 
	int o1, o2, o3;
 
	int a1, a2, a3;
 
	double remainder;
 
	// longitude
 
	remainder = lon + 180.0;
 
	o1 = (int)(remainder / 20.0);
 
	remainder = remainder - (double)o1 * 20.0;
 
	o2 = (int)(remainder / 2.0);
 
	remainder = remainder - 2.0 * (double)o2;
 
	o3 = (int)(12.0 * remainder);
 
 
	// latitude
 
	remainder = lat + 90.0;
 
	a1 = (int)(remainder / 10.0);
 
	remainder = remainder - (double)a1 * 10.0;
 
	a2 = (int)(remainder);
 
	remainder = remainder - (double)a2;
 
	a3 = (int)(24.0 * remainder);
 
	dst[0] = (char)o1 + 'A';
 
	dst[1] = (char)a1 + 'A';
 
	dst[2] = (char)o2 + '0';
 
	dst[3] = (char)a2 + '0';
 
	dst[4] = (char)o3 + 'A';
 
	dst[5] = (char)a3 + 'A';
 
	dst[6] = (char)0;
 
}
 
src/rtc.c
Show inline comments
 
//
 
// RTC: configure real-time clock
 
//
 
 
#include "stm32f0xx_hal.h"
 
#include "rtc.h"
 
#include "gpio.h"
 
 
 
RTC_HandleTypeDef hrtc;
 
 
static void Error_Handler(void)
 
{
 
	volatile uint8_t crap = 1;
 
 
	for(uint16_t i=0; i<300; i++)
 
	{
 
		HAL_GPIO_TogglePin(LED_BLUE);
 
		HAL_Delay(100);
 
	}
 
}
 
 
// Initialize RTC
 
void rtc_init(void)
 
{
 
	__HAL_RCC_RTC_ENABLE();
 
 
    
 
	RTC_TimeTypeDef sTime;
 
	RTC_DateTypeDef sDate;
 
	RTC_AlarmTypeDef sAlarm;
 
 
	HAL_PWR_EnableBkUpAccess();
 
 
	hrtc.Instance = RTC;
 
	hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
 
	hrtc.Init.AsynchPrediv = 124;
 
	hrtc.Init.SynchPrediv = 322; // if this has enough bits should be 1.0018Hz based on 40kHz LSI
 
	hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
 
 	hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
 
	hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
 
 
	if (HAL_RTC_Init(&hrtc) != HAL_OK)
 
	{
 
		Error_Handler();
 
	}
 
 
	sTime.Hours = 0x0;
 
	sTime.Minutes = 0x0;
 
	sTime.Seconds = 0x0;
 
	sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
 
	sTime.StoreOperation = RTC_STOREOPERATION_RESET;
 
	if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
 
	{
 
		Error_Handler();
 
	}
 
 
	sDate.WeekDay = RTC_WEEKDAY_MONDAY;
 
	sDate.Month = RTC_MONTH_JANUARY;
 
	sDate.Date = 0x01;
 
	sDate.Year = 0x19;
 
 
	if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
 
	{
 
		Error_Handler();
 
	}
 
 
 
	/**Enable the Alarm A
 
	*/
 
	sAlarm.AlarmTime.Hours = 0x0;
 
	sAlarm.AlarmTime.Minutes = 0x0;
 
	sAlarm.AlarmTime.Seconds = 0x0;
 
	sAlarm.AlarmTime.SubSeconds = 0x0;
 
	sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
 
	sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
 
 
	// Alarm will trigger on the Xth second of every minute
 
	sAlarm.AlarmMask = RTC_ALARMMASK_ALL; // Trigger every second for now
 
	sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
 
	sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_SS14; //RTC_ALARMSUBSECONDMASK_ALL;
 
	sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
 
	sAlarm.AlarmDateWeekDay = RTC_WEEKDAY_MONDAY;
 
	sAlarm.Alarm = RTC_ALARM_A;
 
	if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
 
	{
 
		Error_Handler();
 
	}
 
 
	HAL_NVIC_SetPriority(RTC_IRQn, 0, 0);
 
	HAL_NVIC_EnableIRQ(RTC_IRQn);
 
 
	HAL_RTC_WaitForSynchro(&hrtc);
 
 
 
}
 
 
RTC_TimeTypeDef time_last = {0};
 
 
RTC_TimeTypeDef* rtc_time(void)
 
{
 
	HAL_RTC_GetTime(&hrtc, &time_last, RTC_FORMAT_BCD);
 
	return &time_last;
 
}
 
 
 
void rtc_cal(void)
 
{
 
	// Do something with hrtc.Instance->CALR; // this has a plus and minus component, see refman
 
}
 
 
RTC_HandleTypeDef* rtc_gethandle(void)
 
{
 
	return &hrtc;
 
}
 
 
0 comments (0 inline, 0 general)