Merge: Pwm inputs (#8)

sr9wxz_new_configuration_for_ZZ06
Mateusz Lubecki 2022-04-30 14:05:14 +02:00
commit 6eded06c6c
6 zmienionych plików z 191 dodań i 21 usunięć

Wyświetl plik

@ -6,16 +6,19 @@
C_SRCS += \
../system/src/drivers/l4/flash_stm32l4x.c \
../system/src/drivers/l4/i2c_stm32l4x.c \
../system/src/drivers/l4/pwm_input_stm32l4x.c \
../system/src/drivers/l4/serial_stm32l4x.c
OBJS += \
./system/src/drivers/l4/flash_stm32l4x.o \
./system/src/drivers/l4/i2c_stm32l4x.o \
./system/src/drivers/l4/pwm_input_stm32l4x.o \
./system/src/drivers/l4/serial_stm32l4x.o
C_DEPS += \
./system/src/drivers/l4/flash_stm32l4x.d \
./system/src/drivers/l4/i2c_stm32l4x.d \
./system/src/drivers/l4/pwm_input_stm32l4x.d \
./system/src/drivers/l4/serial_stm32l4x.d

Wyświetl plik

@ -8,6 +8,12 @@
#ifndef IO_H_
#define IO_H_
/**
* This header file (and corresponding .c file is responsible for configuring and servicing
* various things connected to GPIO pins. Watchdog, Output collector out (for ParaTNC) and
* switching on/off different voltages across both ParaTNC and ParaMETEO
*/
#ifdef STM32F10X_MD_VL
#include <stm32f10x.h>
#endif

Wyświetl plik

@ -54,6 +54,7 @@
* USART1_IRQHandler - 9 -> uart to comm with KISS host
* I2C1_ER_IRQHandler - 10 -> I2C error interrupt
*
* TIM8_ - PWM input
*/

Wyświetl plik

@ -24,6 +24,7 @@
#include "aprsis.h"
#include "api/api.h"
#include "drivers/l4/pwm_input_stm32l4x.h"
#endif
#include <delay.h>
@ -282,7 +283,7 @@ int main(int argc, char* argv[]){
memset(main_own_aprs_msg, 0x00, OWN_APRS_MSG_LN);
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B) || defined(PARATNC_HWREV_C)
#if defined(STM32F10X_MD_VL)
RCC->APB1ENR |= (RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN | RCC_APB1ENR_TIM7EN | RCC_APB1ENR_TIM4EN);
RCC->APB2ENR |= (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN | RCC_APB2ENR_TIM1EN);
RCC->AHBENR |= RCC_AHBENR_CRCEN;
@ -339,7 +340,7 @@ int main(int argc, char* argv[]){
system_clock_configure_rtc_l4();
RCC->APB1ENR1 |= (RCC_APB1ENR1_TIM2EN | RCC_APB1ENR1_TIM3EN | RCC_APB1ENR1_TIM4EN | RCC_APB1ENR1_TIM5EN | RCC_APB1ENR1_TIM7EN | RCC_APB1ENR1_USART2EN | RCC_APB1ENR1_USART3EN | RCC_APB1ENR1_DAC1EN | RCC_APB1ENR1_I2C1EN | RCC_APB1ENR1_USART3EN);
RCC->APB2ENR |= (RCC_APB2ENR_TIM1EN | RCC_APB2ENR_USART1EN); // RCC_APB1ENR1_USART3EN
RCC->APB2ENR |= (RCC_APB2ENR_TIM1EN | RCC_APB2ENR_USART1EN | RCC_APB2ENR_TIM8EN); // RCC_APB1ENR1_USART3EN
RCC->AHB1ENR |= (RCC_AHB1ENR_CRCEN | RCC_AHB1ENR_DMA1EN);
RCC->AHB2ENR |= (RCC_AHB2ENR_ADCEN | RCC_AHB2ENR_GPIOAEN | RCC_AHB2ENR_GPIOBEN | RCC_AHB2ENR_GPIOCEN | RCC_AHB2ENR_GPIODEN);
RCC->BDCR |= RCC_BDCR_RTCEN;
@ -455,7 +456,7 @@ int main(int argc, char* argv[]){
// set packets intervals
packet_tx_configure(main_config_data_basic->wx_transmit_period, main_config_data_basic->beacon_transmit_period, main_config_data_mode->powersave);
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B) || defined(PARATNC_HWREV_C)
#if defined(STM32F10X_MD_VL)
// disabling access to BKP registers
RCC->APB1ENR &= (0xFFFFFFFF ^ (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN));
PWR->CR &= (0xFFFFFFFF ^ PWR_CR_DBP);
@ -528,7 +529,7 @@ int main(int argc, char* argv[]){
// waiting for 1 second to count number of ticks when the CPU is idle
main_idle_cpu_ticks = delay_fixed_with_count(1000);
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B) || defined(PARATNC_HWREV_C)
#if defined(STM32F10X_MD_VL)
// Configure I/O pins for USART1 (Kiss modem)
Configure_GPIO(GPIOA,10,PUD_INPUT); // RX
@ -540,7 +541,7 @@ int main(int argc, char* argv[]){
#endif
#if defined(PARAMETEO)
#if defined(STM32L471xx)
// USART1 - KISS
GPIO_InitTypeDef.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitTypeDef.Pin = LL_GPIO_PIN_10;
@ -594,16 +595,12 @@ int main(int argc, char* argv[]){
#endif
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B)
Configure_GPIO(GPIOA,7,GPPP_OUTPUT_2MHZ); // re/te
GPIO_ResetBits(GPIOA, GPIO_Pin_7);
#endif
#if defined(PARATNC_HWREV_C)
#if defined(STM32F10X_MD_VL)
Configure_GPIO(GPIOA,8,GPPP_OUTPUT_2MHZ); // re/te
GPIO_ResetBits(GPIOA, GPIO_Pin_8);
#endif
#if defined(PARAMETEO)
#if defined(STM32L471xx)
GPIO_InitTypeDef.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitTypeDef.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitTypeDef.Pin = LL_GPIO_PIN_2;
@ -613,7 +610,7 @@ int main(int argc, char* argv[]){
LL_GPIO_Init(GPIOA, &GPIO_InitTypeDef); // RE-TE
#endif
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B) || defined(PARATNC_HWREV_C)
#if defined(STM32F10X_MD_VL)
// enabling the clock for both USARTs
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
@ -717,11 +714,7 @@ int main(int argc, char* argv[]){
srl_init(main_wx_srl_ctx_ptr, USART2, srl_usart2_rx_buffer, RX_BUFFER_2_LN, srl_usart2_tx_buffer, TX_BUFFER_2_LN, main_target_wx_baudrate, 1);
}
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B)
main_wx_srl_ctx_ptr->te_pin = GPIO_Pin_7;
main_wx_srl_ctx_ptr->te_port = GPIOA;
#endif
#if defined(PARATNC_HWREV_C)
#if defined(STM32F10X_MD_VL)
main_wx_srl_ctx_ptr->te_pin = GPIO_Pin_8;
main_wx_srl_ctx_ptr->te_port = GPIOA;
#endif
@ -739,7 +732,7 @@ int main(int argc, char* argv[]){
main_own_path_ln = ConfigPath(main_own_path, main_config_data_basic);
#ifdef INTERNAL_WATCHDOG
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B) || defined(PARATNC_HWREV_C)
#if defined(STM32F10X_MD_VL)
// enable write access to watchdog registers
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
@ -780,11 +773,11 @@ int main(int argc, char* argv[]){
digi_init(main_config_data_mode);
if ((main_config_data_mode->wx & WX_ENABLED) == 1) {
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B) || defined(PARATNC_HWREV_C)
#if defined(STM32F10X_MD_VL)
dallas_init(GPIOC, GPIO_Pin_11, GPIO_PinSource11, &rte_wx_dallas_average);
#endif
#if defined(PARAMETEO)
#if defined(STM32L471xx)
// switch on voltages exclusively for ParaMETEO
@ -961,6 +954,10 @@ int main(int argc, char* argv[]){
aprsis_init(&main_gsm_srl_ctx, &main_gsm_state, "SP8EBC", 10, 23220, TEST_IP, 14580);
}
pwm_input_io_init();
pwm_input_init(1);
#endif
if (main_config_data_basic-> beacon_at_bootup == 1) {
@ -993,7 +990,8 @@ int main(int argc, char* argv[]){
}
main_set_monitor(0);
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B) || defined(PARATNC_HWREV_C)
#if defined(STM32F10X_MD_VL)
// read the state of a button input
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) {
@ -1344,6 +1342,8 @@ int main(int argc, char* argv[]){
if (!main_afsk.sending && main_woken_up == 0) {
pwr_save_pooling_handler(main_config_data_mode, main_config_data_basic, packet_tx_get_minutes_to_next_wx(), rte_main_average_battery_voltage);
}
pwm_input_pool();
#endif
main_set_monitor(9);

Wyświetl plik

@ -0,0 +1,17 @@
/*
* pwm_input_stm32l4x.h
*
* Created on: Apr 17, 2022
* Author: mateusz
*/
#ifndef INCLUDE_DRIVERS_L4_PWM_INPUT_STM32L4X_H_
#define INCLUDE_DRIVERS_L4_PWM_INPUT_STM32L4X_H_
#include <stdint.h>
void pwm_input_io_init(void);
void pwm_input_init(uint8_t channel);
void pwm_input_pool(void);
#endif /* INCLUDE_DRIVERS_L4_PWM_INPUT_STM32L4X_H_ */

Wyświetl plik

@ -0,0 +1,143 @@
#include "drivers/l4/pwm_input_stm32l4x.h"
#include <stm32l4xx.h>
#include <stm32l4xx_ll_tim.h>
#include <stm32l4xx_ll_gpio.h>
uint8_t pwm_input_current_channel = 0;
uint32_t pwm_first_channel = 0;
uint32_t pwm_second_channel = 0;
void pwm_input_io_init(void) {
LL_GPIO_InitTypeDef GPIO_InitTypeDef;
// PC6 - PWM_CH1
GPIO_InitTypeDef.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitTypeDef.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitTypeDef.Pin = LL_GPIO_PIN_6;
GPIO_InitTypeDef.Pull = LL_GPIO_PULL_DOWN;
GPIO_InitTypeDef.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitTypeDef.Alternate = LL_GPIO_AF_3;
LL_GPIO_Init(GPIOC, &GPIO_InitTypeDef);
// PC7 - PWM_CH2
GPIO_InitTypeDef.Pin = LL_GPIO_PIN_7;
LL_GPIO_Init(GPIOC, &GPIO_InitTypeDef);
}
void pwm_input_init(uint8_t channel) {
// check if user provided a channel which make any sense
if (channel == 0 || channel > 2) {
return;
}
// save current channel what is needed to pooling
pwm_input_current_channel = channel;
// disable timer
TIM8->CR1 &= (0xFFFFFFFF ^ TIM_CR1_CEN);
// this will produce 10kHz timebase, counter will overflow every ~6.5 seconds
TIM8->PSC = 2399;
// reset CCER value
TIM8->CCER = 0;
// reset CCMR configuration
TIM8->CCMR1 = 0;
if (channel == 1) {
// 01: CC1 channel is configured as input, IC1 is mapped on TI1
TIM8->CCMR1 |= TIM_CCMR1_CC1S_0;
// 10: CC2 channel is configured as input, IC2 is mapped on TI1
TIM8->CCMR1 |= TIM_CCMR1_CC2S_1;
}
else if (channel == 2) {
// 10: CC1 channel is configured as input, IC1 is mapped on TI2
TIM8->CCMR1 |= TIM_CCMR1_CC1S_1;
// 01: CC2 channel is configured as input, IC2 is mapped on TI2
TIM8->CCMR1 |= TIM_CCMR1_CC2S_0;
}
/**
* 1: OC1 active low (output mode) / Edge sensitivity selection (input mode, see below)
When CC1 channel is configured as input, both CC1NP/CC1P bits select the active polarity
of TI1FP1 and TI2FP1 for trigger or capture operations.
CC1NP=0, CC1P=0: non-inverted/rising edge. The circuit is sensitive to TIxFP1 rising edge
(capture or trigger operations in reset, external clock or trigger mode),
TIxFP1 is not inverted (trigger operation in gated mode or encoder
mode).
CC1NP=0, CC1P=1: inverted/falling edge. The circuit is sensitive to TIxFP1 falling edge
(capture or trigger operations in reset, external clock or trigger mode),
TIxFP1 is inverted (trigger operation in gated mode or encoder mode).
CC1NP=1, CC1P=1: non-inverted/both edges/ The circuit is sensitive to both TIxFP1 rising
and falling edges (capture or trigger operations in reset, external clock
or trigger mode), TIxFP1is not inverted (trigger operation in gated
mode). This configuration must not be used in encoder mode.
*
*
*/
TIM8->CCER |= TIM_CCER_CC2P;
// This bit-field selects the trigger input to be used to synchronize the counter.
// 101: Filtered Timer Input 1 (TI1FP1)
TIM8->SMCR |= (TIM_SMCR_TS_2 | TIM_SMCR_TS_0);
// Slave mode selection
// 0100: Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter
// and generates an update of the registers.
TIM8->SMCR |= TIM_SMCR_SMS_2;
// 1: Capture mode enabled / OC1 signal is output on the corresponding output pin
TIM8->CCER |= (TIM_CCER_CC1E | TIM_CCER_CC2E);
// enable timer
TIM8->CR1 |= TIM_CR1_CEN;
}
void pwm_input_pool(void) {
uint32_t pwm_rising_edge = TIM8->CCR1 + 1;
uint32_t pwm_falling_edge = TIM8->CCR2 + 1;
uint32_t pwm_result = 0;
// check preconditions
if ((pwm_rising_edge != 0) && (pwm_falling_edge != 0)) {
if (pwm_rising_edge > pwm_falling_edge) {
// result value is in percents scaled * 10 (100 means 10 percents)
pwm_falling_edge *= 1000;
pwm_result = (pwm_falling_edge / pwm_rising_edge );
}
}
else {
; // if not do nothing and keeps result to zero
}
if (pwm_input_current_channel == 1) {
// save a result of PWM measurement
pwm_first_channel = pwm_result;
// switch the channel to second
pwm_input_init(2);
}
else if (pwm_input_current_channel == 1) {
pwm_second_channel = pwm_result;
pwm_input_init(1);
}
}