From 0bc2a81c0aab3c89b534415d6f07d07e392260ce Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sat, 3 Jun 2017 20:47:37 +0200 Subject: o Adding support for reading IR codes. --- bsp/radio-controller-1/Inc/main.h | 4 + bsp/radio-controller-1/Inc/stm32f1xx_hal_conf.h | 2 +- bsp/radio-controller-1/Inc/stm32f1xx_it.h | 1 + bsp/radio-controller-1/Src/main.c | 73 ++++++- bsp/radio-controller-1/Src/stm32f1xx_hal_msp.c | 51 ++++- bsp/radio-controller-1/Src/stm32f1xx_it.c | 15 ++ bsp/radio-controller-1/Src/usbd_conf.c | 4 +- bsp/radio-controller-1/radio-controller-1.gpdsc | 4 +- bsp/radio-controller-1/radio-controller-1.ioc | 67 ++++-- doc/tsop48.pdf | Bin 0 -> 135854 bytes include/misc.h | 61 ++++++ src/radio-controller.cpp | 257 ++++++++++++++---------- 12 files changed, 405 insertions(+), 134 deletions(-) create mode 100644 doc/tsop48.pdf create mode 100644 include/misc.h diff --git a/bsp/radio-controller-1/Inc/main.h b/bsp/radio-controller-1/Inc/main.h index 89bca50..49efff9 100644 --- a/bsp/radio-controller-1/Inc/main.h +++ b/bsp/radio-controller-1/Inc/main.h @@ -51,8 +51,12 @@ /* Private define ------------------------------------------------------------*/ #define RADIO_RX_TIMER_PRESCALER (72000000/200000 - 1) +#define IR_RX_Pin GPIO_PIN_0 +#define IR_RX_GPIO_Port GPIOA #define RADIO_RX_Pin GPIO_PIN_8 #define RADIO_RX_GPIO_Port GPIOA +#define DEBUG_PIN_Pin GPIO_PIN_10 +#define DEBUG_PIN_GPIO_Port GPIOA /* USER CODE BEGIN Private defines */ #ifdef __cplusplus diff --git a/bsp/radio-controller-1/Inc/stm32f1xx_hal_conf.h b/bsp/radio-controller-1/Inc/stm32f1xx_hal_conf.h index eb2b5ca..917c203 100644 --- a/bsp/radio-controller-1/Inc/stm32f1xx_hal_conf.h +++ b/bsp/radio-controller-1/Inc/stm32f1xx_hal_conf.h @@ -133,7 +133,7 @@ * @brief This is the HAL system configuration section */ #define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */ -#define TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority (lowest by default) */ +#define TICK_INT_PRIORITY ((uint32_t)1) /*!< tick interrupt priority (lowest by default) */ #define USE_RTOS 0 #define PREFETCH_ENABLE 1 diff --git a/bsp/radio-controller-1/Inc/stm32f1xx_it.h b/bsp/radio-controller-1/Inc/stm32f1xx_it.h index f56b635..1d63a91 100644 --- a/bsp/radio-controller-1/Inc/stm32f1xx_it.h +++ b/bsp/radio-controller-1/Inc/stm32f1xx_it.h @@ -58,6 +58,7 @@ void USB_HP_CAN1_TX_IRQHandler(void); void USB_LP_CAN1_RX0_IRQHandler(void); void TIM1_TRG_COM_IRQHandler(void); void TIM1_CC_IRQHandler(void); +void TIM2_IRQHandler(void); #ifdef __cplusplus } diff --git a/bsp/radio-controller-1/Src/main.c b/bsp/radio-controller-1/Src/main.c index d7e4c04..dbcf975 100644 --- a/bsp/radio-controller-1/Src/main.c +++ b/bsp/radio-controller-1/Src/main.c @@ -54,6 +54,7 @@ IWDG_HandleTypeDef hiwdg; TIM_HandleTypeDef htim1; +TIM_HandleTypeDef htim2; UART_HandleTypeDef huart2; @@ -68,6 +69,7 @@ void Error_Handler(void); static void MX_GPIO_Init(void); static void MX_IWDG_Init(void); static void MX_TIM1_Init(void); +static void MX_TIM2_Init(void); static void MX_USART2_UART_Init(void); /* USER CODE BEGIN PFP */ @@ -98,6 +100,7 @@ int main(void) MX_GPIO_Init(); MX_IWDG_Init(); MX_TIM1_Init(); + MX_TIM2_Init(); MX_USART2_UART_Init(); MX_USB_DEVICE_Init(); @@ -172,7 +175,7 @@ void SystemClock_Config(void) HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /* SysTick_IRQn interrupt configuration */ - HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); + HAL_NVIC_SetPriority(SysTick_IRQn, 1, 0); } /* IWDG init function */ @@ -240,6 +243,63 @@ static void MX_TIM1_Init(void) } +/* TIM2 init function */ +static void MX_TIM2_Init(void) +{ + + TIM_SlaveConfigTypeDef sSlaveConfig; + TIM_MasterConfigTypeDef sMasterConfig; + TIM_IC_InitTypeDef sConfigIC; + + htim2.Instance = TIM2; + htim2.Init.Prescaler = RADIO_RX_TIMER_PRESCALER; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + htim2.Init.Period = 0xffff; + htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + if (HAL_TIM_Base_Init(&htim2) != HAL_OK) + { + Error_Handler(); + } + + if (HAL_TIM_IC_Init(&htim2) != HAL_OK) + { + Error_Handler(); + } + + sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; + sSlaveConfig.InputTrigger = TIM_TS_TI1FP1; + sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; + sSlaveConfig.TriggerFilter = 0; + if (HAL_TIM_SlaveConfigSynchronization(&htim2, &sSlaveConfig) != HAL_OK) + { + Error_Handler(); + } + + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; + sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; + sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; + sConfigIC.ICFilter = 0; + if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; + sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; + if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK) + { + Error_Handler(); + } + +} + /* USART2 init function */ static void MX_USART2_UART_Init(void) { @@ -269,11 +329,22 @@ static void MX_USART2_UART_Init(void) static void MX_GPIO_Init(void) { + GPIO_InitTypeDef GPIO_InitStruct; + /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(DEBUG_PIN_GPIO_Port, DEBUG_PIN_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin : DEBUG_PIN_Pin */ + GPIO_InitStruct.Pin = DEBUG_PIN_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(DEBUG_PIN_GPIO_Port, &GPIO_InitStruct); + } /* USER CODE BEGIN 4 */ diff --git a/bsp/radio-controller-1/Src/stm32f1xx_hal_msp.c b/bsp/radio-controller-1/Src/stm32f1xx_hal_msp.c index 5ee7f9a..49e9623 100644 --- a/bsp/radio-controller-1/Src/stm32f1xx_hal_msp.c +++ b/bsp/radio-controller-1/Src/stm32f1xx_hal_msp.c @@ -75,7 +75,7 @@ void HAL_MspInit(void) /* PendSV_IRQn interrupt configuration */ HAL_NVIC_SetPriority(PendSV_IRQn, 0, 0); /* SysTick_IRQn interrupt configuration */ - HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); + HAL_NVIC_SetPriority(SysTick_IRQn, 1, 0); /**NOJTAG: JTAG-DP Disabled and SW-DP Enabled */ @@ -107,14 +107,37 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) HAL_GPIO_Init(RADIO_RX_GPIO_Port, &GPIO_InitStruct); /* Peripheral interrupt init */ - HAL_NVIC_SetPriority(TIM1_TRG_COM_IRQn, 1, 0); + HAL_NVIC_SetPriority(TIM1_TRG_COM_IRQn, 10, 0); HAL_NVIC_EnableIRQ(TIM1_TRG_COM_IRQn); - HAL_NVIC_SetPriority(TIM1_CC_IRQn, 1, 0); + HAL_NVIC_SetPriority(TIM1_CC_IRQn, 10, 0); HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); /* USER CODE BEGIN TIM1_MspInit 1 */ /* USER CODE END TIM1_MspInit 1 */ } + else if(htim_base->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspInit 0 */ + + /* USER CODE END TIM2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM2_CLK_ENABLE(); + + /**TIM2 GPIO Configuration + PA0-WKUP ------> TIM2_CH1 + */ + GPIO_InitStruct.Pin = IR_RX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(IR_RX_GPIO_Port, &GPIO_InitStruct); + + /* Peripheral interrupt init */ + HAL_NVIC_SetPriority(TIM2_IRQn, 10, 0); + HAL_NVIC_EnableIRQ(TIM2_IRQn); + /* USER CODE BEGIN TIM2_MspInit 1 */ + + /* USER CODE END TIM2_MspInit 1 */ + } } @@ -139,10 +162,30 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) HAL_NVIC_DisableIRQ(TIM1_CC_IRQn); - } /* USER CODE BEGIN TIM1_MspDeInit 1 */ /* USER CODE END TIM1_MspDeInit 1 */ + } + else if(htim_base->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspDeInit 0 */ + + /* USER CODE END TIM2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM2_CLK_DISABLE(); + + /**TIM2 GPIO Configuration + PA0-WKUP ------> TIM2_CH1 + */ + HAL_GPIO_DeInit(IR_RX_GPIO_Port, IR_RX_Pin); + + /* Peripheral interrupt DeInit*/ + HAL_NVIC_DisableIRQ(TIM2_IRQn); + + /* USER CODE BEGIN TIM2_MspDeInit 1 */ + + /* USER CODE END TIM2_MspDeInit 1 */ + } } diff --git a/bsp/radio-controller-1/Src/stm32f1xx_it.c b/bsp/radio-controller-1/Src/stm32f1xx_it.c index 67cbc69..2edc0a7 100644 --- a/bsp/radio-controller-1/Src/stm32f1xx_it.c +++ b/bsp/radio-controller-1/Src/stm32f1xx_it.c @@ -42,6 +42,7 @@ /* External variables --------------------------------------------------------*/ extern PCD_HandleTypeDef hpcd_USB_FS; extern TIM_HandleTypeDef htim1; +extern TIM_HandleTypeDef htim2; /******************************************************************************/ /* Cortex-M3 Processor Interruption and Exception Handlers */ @@ -241,6 +242,20 @@ void TIM1_CC_IRQHandler(void) /* USER CODE END TIM1_CC_IRQn 1 */ } +/** +* @brief This function handles TIM2 global interrupt. +*/ +void TIM2_IRQHandler(void) +{ + /* USER CODE BEGIN TIM2_IRQn 0 */ + + /* USER CODE END TIM2_IRQn 0 */ + HAL_TIM_IRQHandler(&htim2); + /* USER CODE BEGIN TIM2_IRQn 1 */ + + /* USER CODE END TIM2_IRQn 1 */ +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/bsp/radio-controller-1/Src/usbd_conf.c b/bsp/radio-controller-1/Src/usbd_conf.c index 858fb0c..ea64758 100644 --- a/bsp/radio-controller-1/Src/usbd_conf.c +++ b/bsp/radio-controller-1/Src/usbd_conf.c @@ -79,9 +79,9 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) __HAL_RCC_USB_CLK_ENABLE(); /* Peripheral interrupt init */ - HAL_NVIC_SetPriority(USB_HP_CAN1_TX_IRQn, 0, 0); + HAL_NVIC_SetPriority(USB_HP_CAN1_TX_IRQn, 2, 0); HAL_NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn); - HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0, 0); + HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 2, 0); HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); /* USER CODE BEGIN USB_MspInit 1 */ diff --git a/bsp/radio-controller-1/radio-controller-1.gpdsc b/bsp/radio-controller-1/radio-controller-1.gpdsc index 8d085bb..5ebbb9d 100644 --- a/bsp/radio-controller-1/radio-controller-1.gpdsc +++ b/bsp/radio-controller-1/radio-controller-1.gpdsc @@ -1,7 +1,7 @@ @@ -11,7 +11,7 @@ STM32CubeMX generated pack description - - Generated: 30/05/2017 22:50:29 + - Generated: 03/06/2017 13:16:33 diff --git a/bsp/radio-controller-1/radio-controller-1.ioc b/bsp/radio-controller-1/radio-controller-1.ioc index 11a988f..33865c7 100644 --- a/bsp/radio-controller-1/radio-controller-1.ioc +++ b/bsp/radio-controller-1/radio-controller-1.ioc @@ -7,28 +7,32 @@ Mcu.IP1=NVIC Mcu.IP2=RCC Mcu.IP3=SYS Mcu.IP4=TIM1 -Mcu.IP5=USART2 -Mcu.IP6=USB -Mcu.IP7=USB_DEVICE -Mcu.IPNb=8 +Mcu.IP5=TIM2 +Mcu.IP6=USART2 +Mcu.IP7=USB +Mcu.IP8=USB_DEVICE +Mcu.IPNb=9 Mcu.Name=STM32F103C(4-6)Tx Mcu.Package=LQFP48 Mcu.Pin0=PC14-OSC32_IN Mcu.Pin1=PC15-OSC32_OUT -Mcu.Pin10=PA14 -Mcu.Pin11=VP_IWDG_VS_IWDG -Mcu.Pin12=VP_SYS_VS_Systick -Mcu.Pin13=VP_TIM1_VS_ControllerModeReset -Mcu.Pin14=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS +Mcu.Pin10=PA12 +Mcu.Pin11=PA13 +Mcu.Pin12=PA14 +Mcu.Pin13=VP_IWDG_VS_IWDG +Mcu.Pin14=VP_SYS_VS_Systick +Mcu.Pin15=VP_TIM1_VS_ControllerModeReset +Mcu.Pin16=VP_TIM2_VS_ControllerModeReset +Mcu.Pin17=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS Mcu.Pin2=PD0-OSC_IN Mcu.Pin3=PD1-OSC_OUT -Mcu.Pin4=PA2 -Mcu.Pin5=PA3 -Mcu.Pin6=PA8 -Mcu.Pin7=PA11 -Mcu.Pin8=PA12 -Mcu.Pin9=PA13 -Mcu.PinsNb=15 +Mcu.Pin4=PA0-WKUP +Mcu.Pin5=PA2 +Mcu.Pin6=PA3 +Mcu.Pin7=PA8 +Mcu.Pin8=PA10 +Mcu.Pin9=PA11 +Mcu.PinsNb=18 Mcu.UserConstants=RADIO_RX_TIMER_PRESCALER,(72000000/200000 - 1) Mcu.UserName=STM32F103C6Tx MxCube.Version=4.20.1 @@ -41,12 +45,19 @@ NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true -NVIC.SysTick_IRQn=true\:0\:0\:true\:false\:true -NVIC.TIM1_CC_IRQn=true\:1\:0\:true\:false\:true -NVIC.TIM1_TRG_COM_IRQn=true\:1\:0\:true\:false\:true -NVIC.USB_HP_CAN1_TX_IRQn=true\:0\:0\:false\:false\:true -NVIC.USB_LP_CAN1_RX0_IRQn=true\:0\:0\:false\:false\:true +NVIC.SysTick_IRQn=true\:1\:0\:true\:false\:true +NVIC.TIM1_CC_IRQn=true\:10\:0\:true\:false\:true +NVIC.TIM1_TRG_COM_IRQn=true\:10\:0\:true\:false\:true +NVIC.TIM2_IRQn=true\:10\:0\:true\:false\:true +NVIC.USB_HP_CAN1_TX_IRQn=true\:2\:0\:true\:false\:true +NVIC.USB_LP_CAN1_RX0_IRQn=true\:2\:0\:true\:false\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true +PA0-WKUP.GPIOParameters=GPIO_Label +PA0-WKUP.GPIO_Label=IR_RX +PA0-WKUP.Signal=S_TIM2_CH1_ETR +PA10.GPIOParameters=GPIO_Label +PA10.GPIO_Label=DEBUG_PIN +PA10.Signal=GPIO_Output PA11.Mode=Device PA11.Signal=USB_DM PA12.Mode=Device @@ -102,7 +113,7 @@ ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=Other Toolchains (GPDSC) ProjectManager.ToolChainLocation= ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL,2-SystemClock_Config-RCC-false-HAL,3-MX_IWDG_Init-IWDG-false-HAL,4-MX_TIM1_Init-TIM1-false-HAL,5-MX_USART2_UART_Init-USART2-false-HAL,6-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL,2-SystemClock_Config-RCC-false-HAL,3-MX_IWDG_Init-IWDG-false-HAL,4-MX_TIM1_Init-TIM1-false-HAL,5-MX_TIM2_Init-TIM2-false-HAL,6-MX_USART2_UART_Init-USART2-false-HAL,7-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL RCC.ADCFreqValue=36000000 RCC.AHBFreq_Value=72000000 RCC.APB1CLKDivider=RCC_HCLK_DIV2 @@ -128,12 +139,22 @@ RCC.VCOOutput2Freq_Value=8000000 SH.S_TIM1_CH1.0=TIM1_CH1,Input_Capture1_from_TI1 SH.S_TIM1_CH1.1=TIM1_CH1,TriggerSource_TI1FP1 SH.S_TIM1_CH1.ConfNb=2 +SH.S_TIM2_CH1_ETR.0=TIM2_CH1,TriggerSource_TI1FP1 +SH.S_TIM2_CH1_ETR.1=TIM2_CH1,Input_Capture1_from_TI1 +SH.S_TIM2_CH1_ETR.2=TIM2_CH1,Input_Capture2_from_TI1 +SH.S_TIM2_CH1_ETR.ConfNb=3 TIM1.Channel-Input_Capture1_from_TI1=TIM_CHANNEL_1 TIM1.ICFilter_CH1=0 TIM1.ICPolarity_CH1=TIM_INPUTCHANNELPOLARITY_RISING TIM1.IPParameters=Prescaler,Period,Channel-Input_Capture1_from_TI1,ICFilter_CH1,ICPolarity_CH1 TIM1.Period=0xffff TIM1.Prescaler=RADIO_RX_TIMER_PRESCALER +TIM2.Channel-Input_Capture1_from_TI1=TIM_CHANNEL_1 +TIM2.Channel-Input_Capture2_from_TI1=TIM_CHANNEL_2 +TIM2.ICPolarity_CH1=TIM_INPUTCHANNELPOLARITY_FALLING +TIM2.IPParameters=Channel-Input_Capture1_from_TI1,ICPolarity_CH1,Channel-Input_Capture2_from_TI1,Prescaler,Period +TIM2.Period=0xffff +TIM2.Prescaler=RADIO_RX_TIMER_PRESCALER USART2.IPParameters=VirtualMode USART2.VirtualMode=VM_ASYNC USB_DEVICE.CLASS_NAME_FS=CDC @@ -146,6 +167,8 @@ VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick VP_TIM1_VS_ControllerModeReset.Mode=Reset Mode VP_TIM1_VS_ControllerModeReset.Signal=TIM1_VS_ControllerModeReset +VP_TIM2_VS_ControllerModeReset.Mode=Reset Mode +VP_TIM2_VS_ControllerModeReset.Signal=TIM2_VS_ControllerModeReset VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS board=radio-controller-1 diff --git a/doc/tsop48.pdf b/doc/tsop48.pdf new file mode 100644 index 0000000..4355bf8 Binary files /dev/null and b/doc/tsop48.pdf differ diff --git a/include/misc.h b/include/misc.h new file mode 100644 index 0000000..aacba74 --- /dev/null +++ b/include/misc.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include +#include + +template +struct from_f_cpu_and_time_per_timer_tick { + template + using r = std::ratio; + + using f_cpu = r; + using seconds_per_cpu_tick = r<1, f_cpu::num>; + using seconds_per_timer_tick = SecondsPerTimerTick; + using timer_frequency = r; + +// static constexpr std::intmax_t prescaler = std::ratio_divive::value; + using prescaler_t = std::ratio_divide; + static_assert(prescaler_t::den == 1, "Could not represent the prescaler as an integer"); + static constexpr std::intmax_t prescaler = prescaler_t::num; + + // us_per_timer_tick = seconds_per_timer_tick * 1'000'000 + using us_per_timer_tick_t = typename std::ratio_multiply>::type; + + static constexpr uint16_t us_per_timer_tick = static_cast(us_per_timer_tick_t::num); + + template + __always_inline constexpr + static T to_us(unsigned int count) + { + return T(count * us_per_timer_tick); + } +}; + +using values = from_f_cpu_and_time_per_timer_tick<72'000'000, std::ratio_multiply, std::micro>>; + +//static_assert(values::timer_frequency::num == 200'000, "timer_frequency::num"); +static_assert(values::timer_frequency::den == 1, "timer_frequency::den"); +//static_assert(std::is_same< +// values::timer_frequency, +// std::ratio<200'000, 1>>::value, "Timer frequency is not 200kHz"); +static_assert(values::prescaler == 360, "Timer frequency is not 200kHz"); +static_assert(values::prescaler - 1 == RADIO_RX_TIMER_PRESCALER, "Bad prescaler from STM32CubeMX"); +static_assert(values::us_per_timer_tick == 5, "bad us_per_timer_tick"); + +static inline +void debug_pin(int count) { + for(int i = 0; i < count; i++) { + HAL_GPIO_WritePin(DEBUG_PIN_GPIO_Port, DEBUG_PIN_Pin, GPIO_PIN_SET); + __NOP(); + __NOP(); + __NOP(); + HAL_GPIO_WritePin(DEBUG_PIN_GPIO_Port, DEBUG_PIN_Pin, GPIO_PIN_RESET); + __NOP(); + __NOP(); + __NOP(); + } + __NOP(); + __NOP(); + __NOP(); +} diff --git a/src/radio-controller.cpp b/src/radio-controller.cpp index 0f60717..8b350d2 100644 --- a/src/radio-controller.cpp +++ b/src/radio-controller.cpp @@ -5,11 +5,13 @@ #include "mcu/arm/semihosting.h" #include "mcu/stm32cube/uart.h" #include "mcu/stm32cube/debug.h" +#include "misc.h" using mcu::arm::mutex; extern IWDG_HandleTypeDef hiwdg; extern TIM_HandleTypeDef htim1; +extern TIM_HandleTypeDef htim2; extern UART_HandleTypeDef huart2; mcu::stm32cube::uart::uart_port uart2(&huart2); @@ -20,25 +22,34 @@ struct sample { uint16_t pulse_us; }; -template -class sample_buffer { - sample samples[BufferSize]; +template +class buffer { + T samples[BufferSize]; - volatile unsigned int _size; + volatile unsigned int size_; - bool _first; + bool first_; + int part_; public: void reset() { - _size = 0; - _first = true; + size_ = 0; + first_ = true; + part_ = 1; + } + + bool check_first_part() + { + bool first = part_ == 1; + part_ = first ? 2 : 1; + return first; } bool check_first() { - if (_first) { - _first = false; + if (first_) { + first_ = false; return true; } return false; @@ -47,35 +58,47 @@ public: __always_inline unsigned int size() const { - return _size; + return size_; + } + + __always_inline + bool is_empty() const + { + return size_ == 0; } __always_inline bool is_full() const { - return _size == BufferSize; + return size_ == BufferSize; } __always_inline - void append(sample sample) + void append(T sample) { - if (_size == BufferSize) { + if (size_ == BufferSize) { return; } - samples[_size++] = sample; + samples[size_++] = sample; } __always_inline - sample at(int i) const + T at(int i) const { return samples[i]; } }; -volatile int sample_index; -sample_buffer<10> buffer; -mutex buffer_lock; +template +using sample_buffer = buffer; + +sample_buffer<10> radio_buffer; +mutex radio_buffer_lock; + +sample_buffer<30> ir_buffer; +buffer<100, uint16_t> ir_level_buffer; +mutex ir_buffer_lock; void main_pre_init() { @@ -99,60 +122,23 @@ void main_post_init() printf("Radio Controller\n"); - buffer.reset(); - sample_index = 0; + radio_buffer.reset(); + radio_buffer_lock.unlock(); + ir_buffer.reset(); + ir_level_buffer.reset(); + ir_buffer_lock.unlock(); uart2.enable(); hal_ok(HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1)); + hal_ok(HAL_TIM_Base_Start(&htim2)); + hal_ok(HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1)); + hal_ok(HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2)); } static uint32_t tick_next = 0; //static bool seen_high = false; -#include -#include -#include - -template -struct from_f_cpu_and_time_per_timer_tick { - template - using r = std::ratio; - - using f_cpu = r; - using seconds_per_cpu_tick = r<1, f_cpu::num>; - using seconds_per_timer_tick = SecondsPerTimerTick; - using timer_frequency = r; - -// static constexpr std::intmax_t prescaler = std::ratio_divive::value; - using prescaler_t = std::ratio_divide; - static_assert(prescaler_t::den == 1, "Could not represent the prescaler as an integer"); - static constexpr std::intmax_t prescaler = prescaler_t::num; - - // us_per_timer_tick = seconds_per_timer_tick * 1'000'000 - using us_per_timer_tick_t = typename std::ratio_multiply>::type; - - static constexpr uint16_t us_per_timer_tick = static_cast(us_per_timer_tick_t::num); - - template - __always_inline constexpr - static T to_us(unsigned int count) - { - return T(count * us_per_timer_tick); - } -}; - -using values = from_f_cpu_and_time_per_timer_tick<72'000'000, std::ratio_multiply, std::micro>>; - -//static_assert(values::timer_frequency::num == 200'000, "timer_frequency::num"); -static_assert(values::timer_frequency::den == 1, "timer_frequency::den"); -//static_assert(std::is_same< -// values::timer_frequency, -// std::ratio<200'000, 1>>::value, "Timer frequency is not 200kHz"); -static_assert(values::prescaler == 360, "Timer frequency is not 200kHz"); -static_assert(values::prescaler - 1 == RADIO_RX_TIMER_PRESCALER, "Bad prescaler from STM32CubeMX"); -static_assert(values::us_per_timer_tick == 5, "bad us_per_timer_tick"); - void main_loop() { auto now = HAL_GetTick(); @@ -167,44 +153,64 @@ void main_loop() // seen_high = false; } - if (buffer.is_full()) { - buffer_lock.lock(); + if (radio_buffer.is_full()) { + radio_buffer_lock.lock(); hal_ok(HAL_TIM_IC_Stop_IT(&htim1, TIM_CHANNEL_1)); -// printf("Period:"); -// for (unsigned int i = 0; i < buffer.size(); i++) { -// printf(" %u", buffer.at(i)); -// } -// printf("\n"); - -// dbg.print("Pulse: "); -// for (unsigned int i = 0; i < buffer.size(); i++) { -// auto p = values::to_us(buffer_pulse.at(i)); -// dbg.print(" %05u", p); -// } -// dbg.print("\n"); -// -// dbg.print("Period:"); -// for (unsigned int i = 0; i < buffer.size(); i++) { -// auto p = values::to_us(buffer_period.at(i)); -// dbg.print(" %05u", p); -// } -// dbg.print("\n"); - - dbg.println("Samples"); - for (unsigned int i = 0; i < buffer.size(); i++) { - sample s = buffer.at(i); + /* + dbg.println("Radio"); + for (unsigned int i = 0; i < radio_buffer.size(); i++) { + sample s = radio_buffer.at(i); auto pulse = s.pulse_us; auto period = s.period_us; - dbg.println("%d %d, %d%%", period, pulse, int(pulse / double(period) * 100)); + dbg.println("%d us %d us, %d%%", period, pulse, int(pulse / double(period) * 100)); } dbg.println(); + */ - buffer.reset(); - sample_index = 0; + radio_buffer.reset(); hal_ok(HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1)); - buffer_lock.unlock(); + radio_buffer_lock.unlock(); + } + + /* + if (ir_buffer.is_full()) { + ir_buffer_lock.lock(); + + hal_ok(HAL_TIM_IC_Stop_IT(&htim2, TIM_CHANNEL_1)); + hal_ok(HAL_TIM_IC_Stop_IT(&htim2, TIM_CHANNEL_2)); + dbg.println("IR"); + for (unsigned int i = 0; i < ir_buffer.size(); i++) { + sample s = ir_buffer.at(i); + auto pulse = s.pulse_us; + auto period = s.period_us; + dbg.println("% 5d us % 5d us, %.02d%%", period, pulse, int(pulse / double(period) * 100)); + } + dbg.println(); + + ir_buffer.reset(); + hal_ok(HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1)); + hal_ok(HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2)); + ir_buffer_lock.unlock(); + } + */ + + if (ir_level_buffer.is_full()) { + ir_buffer_lock.lock(); + + HAL_NVIC_DisableIRQ(TIM2_IRQn); + + dbg.println("IR"); + for (unsigned int i = 0; i < ir_level_buffer.size(); i++) { + uint16_t s = ir_level_buffer.at(i); + dbg.println("% 5d us", s); + } + dbg.println(); + + ir_level_buffer.reset(); + ir_buffer_lock.unlock(); + HAL_NVIC_EnableIRQ(TIM2_IRQn); } // seen_high |= HAL_GPIO_ReadPin(RADIO_RX_GPIO_Port, RADIO_RX_Pin); @@ -214,26 +220,63 @@ void main_loop() //static uint16_t start = 0; -void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) +uint16_t ir_value1, ir_value2; + +static +void ir_rx(TIM_HandleTypeDef *htim) { - if (htim->Channel != HAL_TIM_ACTIVE_CHANNEL_1) { + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { + debug_pin(2); + } + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { + debug_pin(3); + } + + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { + ir_value1 = static_cast(htim->Instance->CCR1); + } else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { + ir_value2 = static_cast(htim->Instance->CCR2); + } + + if (ir_level_buffer.check_first()) { return; } -// if (buffer.check_first()) { + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { + ir_level_buffer.append(values::to_us(ir_value1 - ir_value2)); + } else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { + ir_level_buffer.append(values::to_us(ir_value2)); + } + + /* + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1 && !ir_buffer.check_first()) { + if (ir_buffer_lock.try_lock()) { + ir_buffer.append({values::to_us(ir_value1), values::to_us(ir_value2)}); + + ir_buffer_lock.unlock(); + } + } + */ +} + +static +void radio_rx(TIM_HandleTypeDef *htim) +{ + if (htim->Channel != HAL_TIM_ACTIVE_CHANNEL_1) { + return; + } +// if (radio_buffer.check_first()) { // return; // } static uint16_t value1, value2; - if (sample_index == 0) { + if (radio_buffer.check_first_part()) { // value1 = static_cast(HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1)); value1 = static_cast(htim->Instance->CCR1); - sample_index = 1; } else { // value2 = static_cast(HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1)); - value2 = static_cast(htim->Instance->CCR1); - sample_index = 0; + value2 = static_cast(htim->Instance->CCR2); uint16_t diff; if (value2 > value1) { @@ -244,10 +287,20 @@ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) return; } - if (buffer_lock.try_lock()) { - buffer.append({values::to_us(0), values::to_us(diff)}); + if (radio_buffer_lock.try_lock()) { + radio_buffer.append({values::to_us(0), values::to_us(diff)}); - buffer_lock.unlock(); + radio_buffer_lock.unlock(); } } } + +void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) +{ + if (htim == &htim1) { + radio_rx(htim); + } + if (htim == &htim2) { + ir_rx(htim); + } +} -- cgit v1.2.3