diff --git a/flake.lock b/flake.lock index 8ff01b4..850f6c5 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1670929434, - "narHash": "sha256-n5UBO6XBV4h3TB7FYu2yAuNQMEYOrQyKeODUwKe06ow=", + "lastModified": 1786514691, + "narHash": "sha256-9dkt1i5JNbEfPb+EjLcSDNs8zqEHQ/1JlSaKgj0SBAg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1710ed1f6f8ceb75cf7d1cf55ee0cc21760e1c7a", + "rev": "867dcbc30bafe3c862ef88620f2e7a109d7d3be5", "type": "github" }, "original": { @@ -22,13 +22,31 @@ "utils": "utils" } }, - "utils": { + "systems": { "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { diff --git a/main.cpp b/main.cpp index 450871d..2dd678a 100644 --- a/main.cpp +++ b/main.cpp @@ -1,353 +1,690 @@ +#include #include -#include - -#include /* - * reserve PB11-PB15 for SPI2 + * LED1 = GPIO_PIN_8 OUTPUT PUSH-PULL + * LED CNF: 10 (3:1 2:0) + * LED MODE: 00 (1:0 0:0) + * + * BTN + * Input, PullDown, 10Mhz + * MODE: 00 + * CNF: 10 + * + * PORT GPIOC + * RCC = 0x4002 1000 - 0x4002 13FF + * GPIOC = 0x4001 1000 - 0x4001 13FF + * GPIO PORT C RCC_APB2ENR 4 */ -// STM32VL-Discovery green led - PC9 -#define BTN_PORT GPIOA -#define LED_PORT GPIOC -#define LED1_PIN GPIO_PIN_8 -#define LED2_PIN GPIO_PIN_9 -#define BTN_PIN GPIO_PIN_0 -#define LED_PORT_CLK_ENABLE __HAL_RCC_GPIOC_CLK_ENABLE +//inline constexpr uint32_t RCC_BASE = 0x40021000UL; +//inline constexpr uint32_t RCC_CR_OFFSET = 0x000; +//inline constexpr uint32_t RCC_CFGR_OFFSET = 0x004; +inline constexpr uint32_t RCC_APB2ENR_OFFSET = 0x018; +inline constexpr uint32_t RCC_APB1ENR_OFFSET = 0x01C; -#define LoRa_RESET_Pin GPIO_PIN_4 -#define LoRa_RESET_GPIO_Port GPIOC -#define LoRa_CS_Pin GPIO_PIN_5 -#define LoRa_CS_GPIO_Port GPIOC +inline constexpr uint32_t RCC_APB2ENR_ADDR = (RCC_BASE + RCC_APB2ENR_OFFSET); +inline constexpr uint32_t RCC_APB1ENR_ADDR = (RCC_BASE + RCC_APB1ENR_OFFSET); +inline constexpr uint32_t RCC_CR_ADDR = (RCC_BASE + RCC_CR_OFFSET); +inline constexpr uint32_t RCC_CFGR_ADDR = (RCC_BASE + RCC_CFGR_OFFSET); -#include "commons.hpp" -#include "logging.hpp" -#include "rfm95.hpp" -#include "spi.hpp" +//inline constexpr uint32_t GPIOA_BASE = 0x40010800; +//inline constexpr uint32_t GPIOC_BASE = 0x40011000; -extern uint8_t LoRa_buff[RH_RF95_FIFO_SIZE]; -extern SPI_HandleTypeDef hspi1; +inline constexpr uint32_t GPIOX_CRL_OFFSET = 0x00; +inline constexpr uint32_t GPIOX_CRH_OFFSET = 0x04; +inline constexpr uint32_t GPIOX_IDR_OFFSET = 0x08; +inline constexpr uint32_t GPIOX_ODR_OFFSET = 0x0C; -void print_version(void) { log::info("running PentaTrack v0.2.0"); } -void print_help(void); +inline constexpr uint32_t GPIOA_CRL = (GPIOA_BASE + GPIOX_CRL_OFFSET); +inline constexpr uint32_t GPIOA_CRH = (GPIOA_BASE + GPIOX_CRH_OFFSET); +inline constexpr uint32_t GPIOA_ODR = (GPIOA_BASE + GPIOX_ODR_OFFSET); +inline constexpr uint32_t GPIOA_IDR = (GPIOA_BASE + GPIOX_IDR_OFFSET); -void loglevel_error(void) { log::set_loglevel(LogLevel::ERROR); } -void loglevel_info(void) { log::set_loglevel(LogLevel::INFO); } -void loglevel_debug(void) { log::set_loglevel(LogLevel::DEBUG); } +inline constexpr uint32_t GPIOC_CRH = (GPIOC_BASE + GPIOX_CRH_OFFSET); +inline constexpr uint32_t GPIOC_ODR = (GPIOC_BASE + GPIOX_ODR_OFFSET); -template -class cmd_holder { - public: - typedef void (*functionPointerType)(void); +inline constexpr unsigned long PC8 = 8; +inline constexpr unsigned long PC9 = 9; +inline constexpr unsigned long PA0 = 0; - using command_t = - std::tuple; - template - using command_array_t = std::array; - - template - constexpr cmd_holder(Args... command_list) - : commands{std::forward(command_list)...} {} - - constexpr functionPointerType get_func(std::string_view message) const { - for (const auto &[cmd_name, cmd_help, func] : commands) { - if (message == cmd_name) { - return func; - } - } - - return nullptr; - } - - void print_help() const { - log::info("Listing available commands:"); - for (const auto &[cmd_name, cmd_help, func] : commands) { - log::info("\t", cmd_name, " - ", cmd_help); - } - } - - private: - std::array commands; -}; - -static bool updated_main_buf = false; -static bool print_main_buf = false; -static buffer main_buffer{}; -static gps_data gps; - -void print_buf(void) { main_buffer.print(); } -void print_gps(void) { gps.print(); } -void print_buf_toggle(void) { print_main_buf = !print_main_buf; } - -class cmd_handler { - public: - static constexpr auto MaxCmdLength = 24; - using array_t = std::array; - using iterator_t = array_t::iterator; - using const_iterator_t = array_t::const_iterator; - - constexpr cmd_handler() : symbols{}, iterator{symbols.begin()} {} - - static cmd_handler &get() { - static auto c = cmd_handler{}; - return c; - }; - - void add_symbol(uint8_t symbol) { - *iterator = symbol; - iterator++; - if (iterator == symbols.end()) { - iterator = symbols.begin(); - } - } - - std::string_view get_current_cmd() const { - return {reinterpret_cast(symbols.data()), - static_cast( - std::distance(symbols.begin(), const_iterator_t{iterator}))}; - } - - bool exists() const { - return commands.get_func(get_current_cmd()) != nullptr; - } - - void execute() { - const auto current_cmd = get_current_cmd(); - log::debug("Try executing command: ", current_cmd); - const auto func = commands.get_func(current_cmd); - iterator = symbols.begin(); - - if (func == nullptr) { - log::info("Unknown Command: ", current_cmd); - log::info("Type 'help' to show available commands."); - return; - } - - func(); - } - - void queue_execution() { ShouldExecute = true; } - - void run() { - if (ShouldExecute) { - execute(); - ShouldExecute = false; - } - } - - void print_help_() const { commands.print_help(); } - - private: - static constexpr cmd_holder<8> commands{ - std::make_tuple("ver", "Prints current version.", &print_version), - std::make_tuple("error", "Set LogLevel to Error.", &loglevel_error), - std::make_tuple("info", "Set LogLevel to Info.", &loglevel_info), - std::make_tuple("debug", "Set LogLevel to Debug.", &loglevel_debug), - std::make_tuple("gps", "Prints captured gps data", &print_gps), - std::make_tuple("buf", "Prints uart2 buffer", &print_buf), - std::make_tuple("buft", "toggles continous printing of uart2 buffer", - &print_buf_toggle), - std::make_tuple("help", "Prints available commands", &print_help)}; - - array_t symbols; - iterator_t iterator; - bool ShouldExecute = false; -}; - -void print_help(void) { cmd_handler::get().print_help_(); } - -// This prevent name mangling for functions used in C/assembly files. -extern "C" { -void SysTick_Handler(void) { - HAL_IncTick(); - HAL_SYSTICK_IRQHandler(); +void SetBit(uint32_t value, uint32_t bit) { + uint32_t* ptr_value = (uint32_t*)value; + *ptr_value |= (1 << bit); } -void USART2_IRQHandler(void) { - HAL_UART_IRQHandler(&gps_interface::s_UARTHandle); - HAL_UART_Receive_IT(&gps_interface::s_UARTHandle, uart_interface::get_buf(), - 1); +void UnsetBit(uint32_t value, uint32_t bit) { + uint32_t* ptr_value = (uint32_t*)value; + *ptr_value &= ~(1 << bit); } -void USART1_IRQHandler(void) { - HAL_UART_IRQHandler(&uart_interface::s_UARTHandle); - HAL_UART_Receive_IT(&uart_interface::s_UARTHandle, uart_interface::get_buf(), - 1); +bool GetBit(uint32_t value, uint32_t bit) { + uint32_t* ptr_value = (uint32_t*)value; + return static_cast((*ptr_value >> bit) & 1); } -void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { - if (huart == &gps_interface::s_UARTHandle) { - return; - } - - const uint8_t value = *uart_interface::get_buf(); - - if (value == '\r') { - cmd_handler::get().queue_execution(); - return; - } - - cmd_handler::get().add_symbol(value); +void SetBit(uint32_t* value, uint32_t bit) { + *value |= (1 << bit); } -void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { - // const uint8_t value = *gps_interface::get_buf(); - // gps_interface::write({reinterpret_cast(&value), 1}); +void UnsetBit(uint32_t* value, uint32_t bit) { + *value &= ~(1 << bit); } -void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { - // log::debug("DMA Callback"); - - HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_SET); - if (main_buffer.copy_from(gps_interface::new_rx_buf, Size)) { - updated_main_buf = true; - } - HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_RESET); - - HAL_UARTEx_ReceiveToIdle_DMA(&gps_interface::s_UARTHandle, - gps_interface::new_rx_buf.data(), - gps_interface::new_rx_buf.size()); - __HAL_DMA_DISABLE_IT(&gps_interface::s_DMAHandle, DMA_IT_HT); +bool GetBit(uint32_t* value, uint32_t bit) { + return static_cast((*value >> bit) & 1); } -/** - * @brief This function handles DMA1 channel6 global interrupt. +// Clock +/* + * We wanna set PLL to 16Mhz (minimum). Maximum would be 24Mhz + * For that we use HSI Clock divided by two (4 Mhz) as input + * 16Mhz = (8Mhz / 2) * 4 + * */ -void DMA1_Channel6_IRQHandler(void) { - /* USER CODE BEGIN DMA1_Channel6_IRQn 0 */ - /* USER CODE END DMA1_Channel6_IRQn 0 */ - HAL_DMA_IRQHandler(&gps_interface::s_DMAHandle); - /* USER CODE BEGIN DMA1_Channel6_IRQn 1 */ +// INTERRUPTS +/* + * Setps: + * - Configure GPIO to Input mode + * - Use SYSCFG register to connect GPIO to an EXTI lin + * - Confiure EXTI for a specific trigger (rising, falling, ...) + * + * Common Mistakes to Avoid: + * - Forgetting enable SYSFG CLK + * - Mapping Multiple Pins to same EXTI Line (for example PA1 and PB1) + * - Not unmasking the line in EXTI Register + * - Forgetting to do enable in NVIC + * - Not clearing the pending bit in ISR -> infinite loop + * + * BTN is on GPIOA0 (PA0) + * PA0 -> EXTI0 + * EXTI_IMR Bit 0 auf 1 Setzen + */ - /* USER CODE END DMA1_Channel6_IRQn 1 */ -} -} - -void initGPIO() { - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOA_CLK_ENABLE(); - - GPIO_InitTypeDef GPIO_Config2; - GPIO_Config2.Mode = GPIO_MODE_INPUT; - GPIO_Config2.Pull = GPIO_PULLDOWN; - GPIO_Config2.Speed = GPIO_SPEED_FREQ_HIGH; - GPIO_Config2.Pin = BTN_PIN; - - GPIO_InitTypeDef GPIO_Config; - GPIO_Config.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_Config.Pull = GPIO_NOPULL; - GPIO_Config.Speed = GPIO_SPEED_FREQ_HIGH; - GPIO_Config.Pin = LED1_PIN | LED2_PIN; - - GPIO_InitTypeDef GPIO_ConfigSPI; - GPIO_ConfigSPI.Mode = GPIO_MODE_OUTPUT_PP; - // GPIO_ConfigSPI.Pull = GPIO_NOPULL; - GPIO_ConfigSPI.Speed = GPIO_SPEED_FREQ_HIGH; - GPIO_ConfigSPI.Pin = LoRa_CS_Pin | LoRa_RESET_Pin; - - // bare metal init of led1: - // volatile uint32_t* CRH = reinterpret_cast(0x40011000 + - // 0x04); - //*CRH |= 0x3; - //*CRH &= (~0xC); - - HAL_GPIO_Init(LED_PORT, &GPIO_Config); - HAL_GPIO_Init(BTN_PORT, &GPIO_Config2); - HAL_GPIO_Init(LoRa_CS_GPIO_Port, &GPIO_ConfigSPI); - // HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_SET); - // HAL_GPIO_WritePin(LoRa_RESET_GPIO_Port, LoRa_RESET_Pin, - // GPIO_PIN_SET); -} +//inline constexpr uint32_t EXTI_BASE = 0x40010400; +inline constexpr uint32_t EXTI_IMR = (EXTI_BASE + 0x00); +inline constexpr uint32_t EXTI_EMR = (EXTI_BASE + 0x04); +inline constexpr uint32_t EXTI_RTSR = (EXTI_BASE + 0x08); +inline constexpr uint32_t EXTI_FTSR = (EXTI_BASE + 0x0C); +inline constexpr uint32_t EXTI_SWIER = (EXTI_BASE + 0x10); +inline constexpr uint32_t EXTI_PR = (EXTI_BASE + 0x14); extern "C" { -#include -void start_interrupt() { - HAL_UARTEx_ReceiveToIdle_DMA(&gps_interface::s_UARTHandle, - gps_interface::new_rx_buf.data(), - gps_interface::new_rx_buf.size()); - __HAL_DMA_DISABLE_IT(&gps_interface::s_DMAHandle, DMA_IT_HT); -} -} + static int ActiveBlink = 0; + /* + * Handles EXTI line interrupt for a given GPIO pin. + */ + void GPIO_IRQHandling(uint8_t PinNumber) + { + // clear the exti pr register corresponding to the pin number + if (EXTI->PR & (1UL << PinNumber)) + { + // clear + EXTI->PR |= (1UL << PinNumber); -int main(void) { - HAL_Init(); - HAL_SYSTICK_Config(1); - initGPIO(); - - if (!log::init()) { - // toggle status led or something - } - log::set_loglevel(LogLevel::DEBUG); - log::info("logging Initialized"); - - if (!MX_SPI1_Init()) { - // toggle status led or something - } - HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(LoRa_RESET_GPIO_Port, LoRa_RESET_Pin, GPIO_PIN_SET); - HAL_Delay(10); - - log::debug("SPI1 Initialized."); - - if (!gps_interface::init()) { - log::error("UART2 Initialization failed, needed for GPS"); - } else { - log::debug("Uart2 Initialized"); - } - - log::debug("Initialization done."); - - char OP_Mode = 0x01; - char buff = 0x7F & OP_Mode; - char res = 0; - - HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_RESET); - [[maybe_unused]] auto result = - HAL_SPI_Transmit(&hspi1, (uint8_t *)&buff, 1, 100); - HAL_SPI_Receive(&hspi1, (uint8_t *)&res, 1, 100); - HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_SET); - - // RF95_Init(); - - HAL_GPIO_WritePin(LED_PORT, LED2_PIN, GPIO_PIN_RESET); - - while (1) { - cmd_handler::get().run(); - - // gps_interface::write("TEST"); - // RF95_setModeRx_Continuous(); - // HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_RESET); - // RF95_receive(LoRa_buff); - // HAL_Delay(100); - // HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_SET); - // HAL_Delay(100); - - if (gps.is_valid()) { - HAL_GPIO_WritePin(LED_PORT, LED2_PIN, GPIO_PIN_SET); + uint32_t *pGpioCOdr = (uint32_t*) GPIOC_ODR; + GPIOC->ODR ^= (1 << PC9); + if (ActiveBlink == 0) { + ActiveBlink = 1; + TIM2->ARR = 100; + } else { + ActiveBlink = 0; + TIM2->ARR = 1000; + } + } } - if (updated_main_buf) { - updated_main_buf = false; - gps.extract_gps_data(main_buffer); - - if (print_main_buf) { - updated_main_buf = !main_buffer.print(); - } + void EXTI0_IRQHandler(void) { + GPIO_IRQHandling(PA0); } - // std::string_view msg{reinterpret_cast(LoRa_buff)}; - // log::info("Received Message"); - // log::debug("Received Message"); - // log::debug(msg); - - // std::string_view foo{"Das ist ein test"}; - // strcpy((char *)LoRa_buff, foo.data()); - - // RF95_send(LoRa_buff); - } - - return 0; + void TIM2_IRQHandler(void) { + // Handle a timer 'update' interrupt event + if (TIM2->SR & TIM_SR_UIF) { + TIM2->SR &= ~(TIM_SR_UIF); + // Toggle the LED output pin. + GPIOC->ODR ^= (1 << PC8); + } + } } + + +int main(void) +{ + // Init system Clock + uint32_t *pRccCfgr = (uint32_t*) RCC_CFGR_ADDR; + //set PLLMUL to x4 + UnsetBit(pRccCfgr, 18); + SetBit(pRccCfgr, 19); + UnsetBit(pRccCfgr, 20); + UnsetBit(pRccCfgr, 21); + + //set PLLSRC to HSI oscillator / 2 + UnsetBit(pRccCfgr, 16); + + uint32_t *pRccCr = (uint32_t*) RCC_CR_ADDR; + //enable PLL clock + SetBit(pRccCr, 24); + + //wait till PLL clock is ready + while (!GetBit(pRccCr, 25)) {}; + + //Set PLL clock as system clock + UnsetBit(pRccCfgr, 0); + SetBit(pRccCfgr, 1); + + //wait till PLL clock is set as system clock + while (!(GetBit(pRccCfgr, 3) && !GetBit(pRccCfgr, 2))) {} + + const auto coreClockHz = 16000000; + + // BUTTON INTERRUPT CFG + + //enable interrupt requests for interrupt line 0 + uint32_t *pExtiIMR = (uint32_t*) EXTI_IMR; + SetBit(pExtiIMR, 0); + + //enable rising trigger on interrupt line + uint32_t *pExtiRTSR = (uint32_t*) EXTI_RTSR; + SetBit(pExtiRTSR, 0); + + uint32_t *pExtiFTSR = (uint32_t*) EXTI_FTSR; + UnsetBit(pExtiFTSR, 0); + + + NVIC_SetPriority(EXTI0_IRQn, 0); + NVIC_EnableIRQ(EXTI0_IRQn); + + // TIMER INTERRUPT CFG + uint32_t *pRccApb1Enr = (uint32_t*) RCC_APB1ENR_ADDR; + + //Enable TIM2 + SetBit(pRccApb1Enr, 0); + + //Disable TIM2 Counter + TIM2->CR1 &= ~(TIM_CR1_CEN); + + //Reset TIM2 + //SetBit(RCC->APB1RSTR, 0); + //UnsetBit(RCC->APB1RSTR, 0); + RCC->APB1RSTR |= (RCC_APB1RSTR_TIM2RST); + RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM2RST); + + //Set TIM2 to count every millisecond + TIM2->PSC = coreClockHz / 1000; + + // Reset timmer counter every 1000 counts (1 second) + TIM2->ARR = 1000; + + // enable ARR register buffering, needed to change ARR counter on the fly + TIM2->CR1 |= TIM_CR1_ARPE; + + // Send an update event to reset the timer and apply settings + TIM2->EGR |= TIM_EGR_UG; + + // Enable interrupts on timer updates + TIM2->DIER |= TIM_DIER_UIE; + //SetBit(TIM2->DIER, TIM_DIER_UIE); + + //Enable TIM2 Counter + TIM2->CR1 |= TIM_CR1_CEN; + //SetBit(TIM2->CR1, TIM_CR1_CEN); + + //Activate Interrupts for TIM2 + NVIC_SetPriority(TIM2_IRQn, 3); + NVIC_EnableIRQ(TIM2_IRQn); + + uint32_t *pRccApb2Enr = (uint32_t*) RCC_APB2ENR_ADDR; + + // enalbe clock for GPIO Port A on APB2 + *pRccApb2Enr |= (1 << 2); + + // enalbe clock for GPIO Port C on APB2 + *pRccApb2Enr |= (1 << 4); + + //Configure LED 8 Pin as Output with Push-Pull Resistor + uint32_t *pGpioCCrh = (uint32_t*) GPIOC_CRH; + //Set LED MODE + SetBit(pGpioCCrh, 0); + UnsetBit(pGpioCCrh, 1); + ////Set LED CNF + UnsetBit(pGpioCCrh, 2); + UnsetBit(pGpioCCrh, 3); + + //Configure LED 9 Pin as Output with Push-Pull Resistor + //Set LED MODE + SetBit(pGpioCCrh, 4); + UnsetBit(pGpioCCrh, 5); + ////Set LED CNF + UnsetBit(pGpioCCrh, 6); + UnsetBit(pGpioCCrh, 7); + + //Configure BTN Pin as Input with PullDown Resistor + uint32_t *pGpioACrl = (uint32_t*) GPIOA_CRL; + //Set BTN MODE + UnsetBit(pGpioACrl, 0); + UnsetBit(pGpioACrl, 1); + //Set BTN CNF + UnsetBit(pGpioACrl, 2); + SetBit(pGpioACrl, 3); + + uint32_t *pGpioAIdr = (uint32_t*) GPIOA_IDR; + uint32_t *pGpioCOdr = (uint32_t*) GPIOC_ODR; + while(1) + { + //const auto buttonIsSet = GetBit(pGpioAIdr, 0); + //auto DoBlink = static_cast(ActiveBlink); + + //SetBit(pGpioCOdr, PC8); + //if (DoBlink) { + // SetBit(pGpioCOdr, PC9); + //} + for (uint32_t i = 0; i < 500000; i++); + + //DoBlink = static_cast(ActiveBlink); + + //UnsetBit(pGpioCOdr, PC8); + //if (DoBlink) { + // UnsetBit(pGpioCOdr, PC9); + //} + for (uint32_t i = 0; i < 500000; i++); + } + return 0; +} + +//#include +//#include +//#include +//#include +// +//#include +// +///* +// * reserve PB11-PB15 for SPI2 +// */ +// +//// STM32VL-Discovery green led - PC9 +//#define BTN_PORT GPIOA +//#define LED_PORT GPIOC +//#define LED1_PIN GPIO_PIN_8 +//#define LED2_PIN GPIO_PIN_9 +//#define BTN_PIN GPIO_PIN_0 +//#define LED_PORT_CLK_ENABLE __HAL_RCC_GPIOC_CLK_ENABLE +// +//#define LoRa_RESET_Pin GPIO_PIN_4 +//#define LoRa_RESET_GPIO_Port GPIOC +//#define LoRa_CS_Pin GPIO_PIN_5 +//#define LoRa_CS_GPIO_Port GPIOC +// +//#include "commons.hpp" +//#include "logging.hpp" +//#include "rfm95.hpp" +//#include "spi.hpp" +// +//extern uint8_t LoRa_buff[RH_RF95_FIFO_SIZE]; +//extern SPI_HandleTypeDef hspi1; +// +//void print_version(void) { log::info("running PentaTrack v0.2.0"); } +//void print_help(void); +// +//void loglevel_error(void) { log::set_loglevel(LogLevel::ERROR); } +//void loglevel_info(void) { log::set_loglevel(LogLevel::INFO); } +//void loglevel_debug(void) { log::set_loglevel(LogLevel::DEBUG); } +// +//template +//class cmd_holder { +// public: +// typedef void (*functionPointerType)(void); +// +// using command_t = +// std::tuple; +// template +// using command_array_t = std::array; +// +// template +// constexpr cmd_holder(Args... command_list) +// : commands{std::forward(command_list)...} {} +// +// constexpr functionPointerType get_func(std::string_view message) const { +// for (const auto &[cmd_name, cmd_help, func] : commands) { +// if (message == cmd_name) { +// return func; +// } +// } +// +// return nullptr; +// } +// +// void print_help() const { +// log::info("Listing available commands:"); +// for (const auto &[cmd_name, cmd_help, func] : commands) { +// log::info("\t", cmd_name, " - ", cmd_help); +// } +// } +// +// private: +// std::array commands; +//}; +// +//static bool updated_main_buf = false; +//static bool print_main_buf = false; +//static buffer main_buffer{}; +//static gps_data gps; +// +//void print_buf(void) { main_buffer.print(); } +//void print_gps(void) { gps.print(); } +//void print_buf_toggle(void) { print_main_buf = !print_main_buf; } +// +//class cmd_handler { +// public: +// static constexpr auto MaxCmdLength = 24; +// using array_t = std::array; +// using iterator_t = array_t::iterator; +// using const_iterator_t = array_t::const_iterator; +// +// constexpr cmd_handler() : symbols{}, iterator{symbols.begin()} {} +// +// static cmd_handler &get() { +// static auto c = cmd_handler{}; +// return c; +// }; +// +// void add_symbol(uint8_t symbol) { +// *iterator = symbol; +// iterator++; +// if (iterator == symbols.end()) { +// iterator = symbols.begin(); +// } +// } +// +// std::string_view get_current_cmd() const { +// return {reinterpret_cast(symbols.data()), +// static_cast( +// std::distance(symbols.begin(), const_iterator_t{iterator}))}; +// } +// +// bool exists() const { +// return commands.get_func(get_current_cmd()) != nullptr; +// } +// +// void execute() { +// const auto current_cmd = get_current_cmd(); +// log::debug("Try executing command: ", current_cmd); +// const auto func = commands.get_func(current_cmd); +// iterator = symbols.begin(); +// +// if (func == nullptr) { +// log::info("Unknown Command: ", current_cmd); +// log::info("Type 'help' to show available commands."); +// return; +// } +// +// func(); +// } +// +// void queue_execution() { ShouldExecute = true; } +// +// void run() { +// if (ShouldExecute) { +// execute(); +// ShouldExecute = false; +// } +// } +// +// void print_help_() const { commands.print_help(); } +// +// private: +// static constexpr cmd_holder<8> commands{ +// std::make_tuple("ver", "Prints current version.", &print_version), +// std::make_tuple("error", "Set LogLevel to Error.", &loglevel_error), +// std::make_tuple("info", "Set LogLevel to Info.", &loglevel_info), +// std::make_tuple("debug", "Set LogLevel to Debug.", &loglevel_debug), +// std::make_tuple("gps", "Prints captured gps data", &print_gps), +// std::make_tuple("buf", "Prints uart2 buffer", &print_buf), +// std::make_tuple("buft", "toggles continous printing of uart2 buffer", +// &print_buf_toggle), +// std::make_tuple("help", "Prints available commands", &print_help)}; +// +// array_t symbols; +// iterator_t iterator; +// bool ShouldExecute = false; +//}; +// +//void print_help(void) { cmd_handler::get().print_help_(); } +// +//// This prevent name mangling for functions used in C/assembly files. +//extern "C" { +//void SysTick_Handler(void) { +// HAL_IncTick(); +// HAL_SYSTICK_IRQHandler(); +//} +// +//void EXTI0_IRQHandler(void) +//{ +// /* USER CODE BEGIN EXTI0_IRQn 0 */ +// +// /* USER CODE END EXTI0_IRQn 0 */ +// HAL_GPIO_EXTI_IRQHandler(BTN_PIN); +// /* USER CODE BEGIN EXTI0_IRQn 1 */ +// +// /* USER CODE END EXTI0_IRQn 1 */ +//} +// +//void USART2_IRQHandler(void) { +// HAL_UART_IRQHandler(&gps_interface::s_UARTHandle); +// HAL_UART_Receive_IT(&gps_interface::s_UARTHandle, uart_interface::get_buf(), +// 1); +//} +// +//void USART1_IRQHandler(void) { +// HAL_UART_IRQHandler(&uart_interface::s_UARTHandle); +// HAL_UART_Receive_IT(&uart_interface::s_UARTHandle, uart_interface::get_buf(), +// 1); +//} +// +//void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { +// if (huart == &gps_interface::s_UARTHandle) { +// return; +// } +// +// const uint8_t value = *uart_interface::get_buf(); +// +// if (value == '\r') { +// cmd_handler::get().queue_execution(); +// return; +// } +// +// cmd_handler::get().add_symbol(value); +//} +// +//void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { +// // const uint8_t value = *gps_interface::get_buf(); +// // gps_interface::write({reinterpret_cast(&value), 1}); +//} +// +//void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { +// // log::debug("DMA Callback"); +// +// HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_SET); +// if (main_buffer.copy_from(gps_interface::new_rx_buf, Size)) { +// updated_main_buf = true; +// } +// HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_RESET); +// +// HAL_UARTEx_ReceiveToIdle_DMA(&gps_interface::s_UARTHandle, +// gps_interface::new_rx_buf.data(), +// gps_interface::new_rx_buf.size()); +// __HAL_DMA_DISABLE_IT(&gps_interface::s_DMAHandle, DMA_IT_HT); +//} +// +///** +// * @brief This function handles DMA1 channel6 global interrupt. +// */ +//void DMA1_Channel6_IRQHandler(void) { +// /* USER CODE BEGIN DMA1_Channel6_IRQn 0 */ +// +// /* USER CODE END DMA1_Channel6_IRQn 0 */ +// HAL_DMA_IRQHandler(&gps_interface::s_DMAHandle); +// +// /* USER CODE BEGIN DMA1_Channel6_IRQn 1 */ +// +// /* USER CODE END DMA1_Channel6_IRQn 1 */ +//} +//} +// +//void initGPIO() { +// __HAL_RCC_GPIOC_CLK_ENABLE(); +// __HAL_RCC_GPIOA_CLK_ENABLE(); +// +// //GPIO_InitTypeDef GPIO_Config2; +// //GPIO_Config2.Mode = GPIO_MODE_INPUT; +// //GPIO_Config2.Pull = GPIO_PULLDOWN; +// //GPIO_Config2.Speed = GPIO_SPEED_FREQ_HIGH; +// //GPIO_Config2.Pin = BTN_PIN; +// +// GPIO_InitTypeDef GPIO_Config2; +// GPIO_Config2.Mode = GPIO_MODE_IT_FALLING; +// GPIO_Config2.Pull = GPIO_PULLUP; +// GPIO_Config2.Pin = BTN_PIN; +// +// GPIO_InitTypeDef GPIO_Config; +// GPIO_Config.Mode = GPIO_MODE_OUTPUT_PP; +// GPIO_Config.Pull = GPIO_NOPULL; +// GPIO_Config.Speed = GPIO_SPEED_FREQ_HIGH; +// GPIO_Config.Pin = LED1_PIN | LED2_PIN; +// +// GPIO_InitTypeDef GPIO_ConfigSPI; +// GPIO_ConfigSPI.Mode = GPIO_MODE_OUTPUT_PP; +// // GPIO_ConfigSPI.Pull = GPIO_NOPULL; +// GPIO_ConfigSPI.Speed = GPIO_SPEED_FREQ_HIGH; +// GPIO_ConfigSPI.Pin = LoRa_CS_Pin | LoRa_RESET_Pin; +// +// // bare metal init of led1: +// // volatile uint32_t* CRH = reinterpret_cast(0x40011000 + +// // 0x04); +// //*CRH |= 0x3; +// //*CRH &= (~0xC); +// +// HAL_GPIO_Init(LED_PORT, &GPIO_Config); +// HAL_GPIO_Init(BTN_PORT, &GPIO_Config2); +// HAL_GPIO_Init(LoRa_CS_GPIO_Port, &GPIO_ConfigSPI); +// // HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_SET); +// // HAL_GPIO_WritePin(LoRa_RESET_GPIO_Port, LoRa_RESET_Pin, +// // GPIO_PIN_SET); +//} +// +//extern "C" { +//#include +// +//void start_interrupt() { +// HAL_UARTEx_ReceiveToIdle_DMA(&gps_interface::s_UARTHandle, +// gps_interface::new_rx_buf.data(), +// gps_interface::new_rx_buf.size()); +// __HAL_DMA_DISABLE_IT(&gps_interface::s_DMAHandle, DMA_IT_HT); +// HAL_GPIOEx_EnableEventout(); +//} +// +//void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { +// if (GPIO_Pin == BTN_PIN) { +// // Your interrupt handling code goes here +// // For example, toggle an LED +// HAL_GPIO_TogglePin(LED_PORT, LED1_PIN); +// } +//} +// +//} +// +//int main(void) { +// HAL_Init(); +// HAL_SYSTICK_Config(1); +// initGPIO(); +// +// if (!log::init()) { +// // toggle status led or something +// } +// log::set_loglevel(LogLevel::DEBUG); +// log::info("logging Initialized"); +// +// //if (!MX_SPI1_Init()) { +// // // toggle status led or something +// //} +// //HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_SET); +// //HAL_GPIO_WritePin(LoRa_RESET_GPIO_Port, LoRa_RESET_Pin, GPIO_PIN_SET); +// +// HAL_NVIC_SetPriority(EXTI0_IRQn, 0 ,0); +// HAL_NVIC_EnableIRQ(EXTI0_IRQn); +// +// while(1) { +// HAL_GPIO_WritePin(LED_PORT, LED2_PIN, GPIO_PIN_SET); +// HAL_Delay(100); +// HAL_GPIO_WritePin(LED_PORT, LED2_PIN, GPIO_PIN_RESET); +// HAL_Delay(100); +// } +// // HAL_Delay(10); +// +// // log::debug("SPI1 Initialized."); +// // log::debug("SPI1 Initialized."); +// +// // if (!gps_interface::init()) { +// // log::error("UART2 Initialization failed, needed for GPS"); +// // } else { +// // log::debug("Uart2 Initialized"); +// // } +// +// // log::debug("Initialization done."); +// +// // char OP_Mode = 0x01; +// // char buff = 0x7F & OP_Mode; +// // char res = 0; +// +// // HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_RESET); +// // [[maybe_unused]] auto result = +// // HAL_SPI_Transmit(&hspi1, (uint8_t *)&buff, 1, 100); +// // HAL_SPI_Receive(&hspi1, (uint8_t *)&res, 1, 100); +// // HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_SET); +// +// // // RF95_Init(); +// +// // HAL_GPIO_WritePin(LED_PORT, LED2_PIN, GPIO_PIN_RESET); +// +// // while (1) { +// // cmd_handler::get().run(); +// +// // // gps_interface::write("TEST"); +// // // RF95_setModeRx_Continuous(); +// // // HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_RESET); +// // // RF95_receive(LoRa_buff); +// // // HAL_Delay(100); +// // // HAL_GPIO_WritePin(LED_PORT, LED1_PIN, GPIO_PIN_SET); +// // // HAL_Delay(100); +// +// // if (gps.is_valid()) { +// // HAL_GPIO_WritePin(LED_PORT, LED2_PIN, GPIO_PIN_SET); +// // } +// +// // if (updated_main_buf) { +// // updated_main_buf = false; +// // gps.extract_gps_data(main_buffer); +// +// // if (print_main_buf) { +// // updated_main_buf = !main_buffer.print(); +// // } +// // } +// +// // // std::string_view msg{reinterpret_cast(LoRa_buff)}; +// // // log::info("Received Message"); +// // // log::debug("Received Message"); +// // // log::debug(msg); +// +// // // std::string_view foo{"Das ist ein test"}; +// // // strcpy((char *)LoRa_buff, foo.data()); +// +// // // RF95_send(LoRa_buff); +// // } +// +// return 0; +//} +// diff --git a/shell.nix b/shell.nix index de410d2..ac7f704 100644 --- a/shell.nix +++ b/shell.nix @@ -10,7 +10,7 @@ mkShell { gnumake stlink screen - gcc-arm-embedded-10 + gcc-arm-embedded-15 libstm32cube libstm32stdperiph esptool diff --git a/stm32f1xx_it.h b/stm32f1xx_it.h index c7815c5..ca319e2 100644 --- a/stm32f1xx_it.h +++ b/stm32f1xx_it.h @@ -57,6 +57,8 @@ void PendSV_Handler(void); void SysTick_Handler(void); void DMA1_Channel6_IRQHandler(void); void USART1_IRQHandler(void); +void EXTI0_IRQHandler(void); + /* USER CODE BEGIN EFP */