commit 6c3ade40cf13e4e886cb52f8fcdeb528ab59c67d Author: zhaohe Date: Sat Jun 29 14:27:02 2024 +0800 first commit diff --git a/doc/ADC通道映射.png b/doc/ADC通道映射.png new file mode 100644 index 0000000..7de6377 Binary files /dev/null and b/doc/ADC通道映射.png differ diff --git a/doc/定时器映射表.png b/doc/定时器映射表.png new file mode 100644 index 0000000..e37c6ed Binary files /dev/null and b/doc/定时器映射表.png differ diff --git a/logger.c b/logger.c new file mode 100644 index 0000000..d546ed1 --- /dev/null +++ b/logger.c @@ -0,0 +1,45 @@ +#include "logger.h" + +#include +#include +#include +#include +static UART_HandleTypeDef* m_huart; +bool g_enable_log = true; +/********************************************************************* + * @fn _write + * + * @brief Support Printf Function + * + * @param *buf - UART send Data. + * size - Data length + * + * @return size: Data length + */ +__attribute__((used)) int _write(int fd, char* buf, int size) { + int i; + + for (i = 0; i < size; i++) { + uint8_t c = *buf++; + if (m_huart != NULL) HAL_UART_Transmit(m_huart, &c, 1, 100); + } + + return size; +} + +void zlog_init(UART_HandleTypeDef* huart) { m_huart = huart; } +void zlog_enable(bool enable) { g_enable_log = enable; } +void zlog(const char* fmt, ...) { + if (g_enable_log) { + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + } +} + +void zlog_raw(const char* info) { + if (g_enable_log) { + printf(info); + } +} \ No newline at end of file diff --git a/logger.h b/logger.h new file mode 100644 index 0000000..1e4cc8d --- /dev/null +++ b/logger.h @@ -0,0 +1,49 @@ +#pragma once +#include +#include + +#include "cmsis_os.h" +#include "main.h" +extern bool g_enable_log; +#define ZLOG_RELEASE(TAG, fmt, ...) \ + if (g_enable_log) { \ + zlog(TAG "" fmt "\n", ##__VA_ARGS__); \ + } +#define ZLOGI(TAG, fmt, ...) \ + if (g_enable_log) { \ + zlog("%08lu INFO [%-8s] " fmt "\n", HAL_GetTick(), TAG, ##__VA_ARGS__); \ + } +#define ZLOGD(TAG, fmt, ...) \ + if (g_enable_log) { \ + zlog("%08lu DEBU [%-8s] " fmt "\n", HAL_GetTick(), TAG, ##__VA_ARGS__); \ + } +#define ZLOGE(TAG, fmt, ...) \ + if (g_enable_log) { \ + zlog("%08lu ERRO [%-8s] " fmt "\n", HAL_GetTick(), TAG, ##__VA_ARGS__); \ + } + +#define ZLOGW(TAG, fmt, ...) \ + if (g_enable_log) { \ + zlog("%08lu WARN [%-8s] " fmt "\n", HAL_GetTick(), TAG, ##__VA_ARGS__); \ + } + +#define ZASSERT(cond) \ + if (!(cond)) { \ + while (1) { \ + zlog("ASSERT: %s [%s:%d]\n", #cond, __FILE__, __LINE__); \ + osDelay(1000); \ + } \ + } + +#define ZASSERT_INFO(cond, info) \ + if (!(cond)) { \ + while (1) { \ + zlog("ASSERT: %s [%s:%d] %s\n", #cond, __FILE__, __LINE__, info); \ + osDelay(1000); \ + } \ + } + +void zlog(const char* fmt, ...); +void zlog_raw(const char* info); +void zlog_init(UART_HandleTypeDef* huart); +void zlog_enable(bool enable); diff --git a/mutex.cpp b/mutex.cpp new file mode 100644 index 0000000..b452048 --- /dev/null +++ b/mutex.cpp @@ -0,0 +1,35 @@ +#include "mutex.hpp" +#define TAG "zmutex" + +using namespace iflytop; + +/******************************************************************************* + * zmutex * + *******************************************************************************/ +zmutex::zmutex() {} +zmutex::~zmutex() { + vSemaphoreDelete(recursiveMutex); +} + +void zmutex::init() { + recursiveMutex = xSemaphoreCreateRecursiveMutex(); +} + +bool zmutex::isInit() { + return recursiveMutex != NULL; +} + +void zmutex::lock() { + xSemaphoreTakeRecursive(recursiveMutex, portMAX_DELAY); +} +void zmutex::unlock() { + xSemaphoreGiveRecursive(recursiveMutex); +} + +/******************************************************************************* + * zlock_guard * + *******************************************************************************/ +zlock_guard::zlock_guard(zmutex& mutex) : m_mutex(mutex) { + m_mutex.lock(); +} +zlock_guard::~zlock_guard() { m_mutex.unlock(); } diff --git a/mutex.hpp b/mutex.hpp new file mode 100644 index 0000000..310cca3 --- /dev/null +++ b/mutex.hpp @@ -0,0 +1,31 @@ +#pragma once +extern "C" { +#include "cmsis_os.h" +} +namespace iflytop { +using namespace std; + +class zmutex { + public: + SemaphoreHandle_t recursiveMutex; + + public: + zmutex(); + ~zmutex(); + + void init(); + bool isInit(); + + void lock(); + void unlock(); +}; + +class zlock_guard { + zmutex& m_mutex; + + public: + zlock_guard(zmutex& mutex); + ~zlock_guard(); +}; + +} // namespace iflytop \ No newline at end of file diff --git a/sdk.cpp b/sdk.cpp new file mode 100644 index 0000000..d27555c --- /dev/null +++ b/sdk.cpp @@ -0,0 +1,9 @@ +#include "sdk.hpp" + +#include "project_configs.h" + + +void sdkinit() { + zlog_init(&PC_DEBUG_UART); + zusdelay_init(&PC_SYS_DELAY_US_TIMER); +} diff --git a/sdk.hpp b/sdk.hpp new file mode 100644 index 0000000..4cb73c2 --- /dev/null +++ b/sdk.hpp @@ -0,0 +1,10 @@ +#pragma once +extern "C" { +#include "logger.h" +} +#include "zgpio.hpp" +#include "zusdelay.hpp" +#include "stm32/stm32.hpp" +#include "mutex.hpp" +#include "ticket.hpp" +void sdkinit(); \ No newline at end of file diff --git a/stm32/critical.c b/stm32/critical.c new file mode 100644 index 0000000..a3cb24a --- /dev/null +++ b/stm32/critical.c @@ -0,0 +1,15 @@ +#include "main.h" +static uint8_t g_port_exit_critical_count; + +void chip_critical_enter(void) { + if (g_port_exit_critical_count == 0) { + __disable_irq(); + } + g_port_exit_critical_count++; +} +void chip_critical_exit(void) { + g_port_exit_critical_count--; + if (g_port_exit_critical_count == 0) { + __enable_irq(); + } +} diff --git a/stm32/critical.h b/stm32/critical.h new file mode 100644 index 0000000..4fe2ea7 --- /dev/null +++ b/stm32/critical.h @@ -0,0 +1,3 @@ +#pragma once +void stm32_critical_enter(void); +void stm32_critical_exit(void); \ No newline at end of file diff --git a/stm32/gins.c b/stm32/gins.c new file mode 100644 index 0000000..89fdf68 --- /dev/null +++ b/stm32/gins.c @@ -0,0 +1,54 @@ +#include "gins.h" + +#include "main.h" + +DEFINE_GLOBAL(CAN_HandleTypeDef, hcan1); + +DEFINE_GLOBAL(TIM_HandleTypeDef, htim1); +DEFINE_GLOBAL(TIM_HandleTypeDef, htim2); +DEFINE_GLOBAL(TIM_HandleTypeDef, htim6); +DEFINE_GLOBAL(TIM_HandleTypeDef, htim7); + +DEFINE_GLOBAL(I2C_HandleTypeDef, hi2c1); + +DEFINE_GLOBAL(UART_HandleTypeDef, huart1); +DEFINE_GLOBAL(UART_HandleTypeDef, huart2); +DEFINE_GLOBAL(UART_HandleTypeDef, huart3); +DEFINE_GLOBAL(UART_HandleTypeDef, huart4); + +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma1_stream1); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma1_stream2); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma1_stream3); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma1_stream5); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma1_stream6); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma2_stream1); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma2_stream2); // used by common board +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma2_stream3); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma2_stream7); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma3_stream1); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma3_stream2); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma3_stream3); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma4_stream1); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma4_stream2); +DEFINE_GLOBAL(DMA_HandleTypeDef, hdma4_stream3); + +DEFINE_GLOBAL(SPI_HandleTypeDef, hspi1); +DEFINE_GLOBAL(SPI_HandleTypeDef, hspi2); +DEFINE_GLOBAL(SPI_HandleTypeDef, hspi3); + +DEFINE_GLOBAL(ADC_HandleTypeDef, hadc1); + + + + +/*********************************************************************************************************************** + * PTR * + ***********************************************************************************************************************/ +DEFINE_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart1_rx); +DEFINE_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart1_tx); +DEFINE_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart2_rx); +DEFINE_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart2_tx); +DEFINE_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart3_rx); +DEFINE_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart3_tx); +DEFINE_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart4_rx); +DEFINE_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart4_tx); diff --git a/stm32/gins.h b/stm32/gins.h new file mode 100644 index 0000000..035e81c --- /dev/null +++ b/stm32/gins.h @@ -0,0 +1,79 @@ +#pragma once + +#include + +#include "main.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define EXTERN_GLOBAL(type, name) \ + extern type name; \ + extern bool name##_enable; + +#define EXTERN_GLOBAL_PTR(type, name) extern type* name; + +#define DEFINE_GLOBAL(type, name) \ + type name; \ + bool name##_enable; + +#define DEFINE_GLOBAL_PTR(type, name) type* name; + +/*********************************************************************************************************************** + * GLOBAL * + ***********************************************************************************************************************/ + +EXTERN_GLOBAL(CAN_HandleTypeDef, hcan1); + +EXTERN_GLOBAL(TIM_HandleTypeDef, htim1); +EXTERN_GLOBAL(TIM_HandleTypeDef, htim2); +EXTERN_GLOBAL(TIM_HandleTypeDef, htim6); +EXTERN_GLOBAL(TIM_HandleTypeDef, htim7); + +EXTERN_GLOBAL(I2C_HandleTypeDef, hi2c1); + +EXTERN_GLOBAL(UART_HandleTypeDef, huart1); +EXTERN_GLOBAL(UART_HandleTypeDef, huart2); +EXTERN_GLOBAL(UART_HandleTypeDef, huart3); +EXTERN_GLOBAL(UART_HandleTypeDef, huart4); + +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma1_stream1); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma1_stream2); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma1_stream3); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma1_stream5); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma1_stream6); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma2_stream1); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma2_stream2); // used by common board +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma2_stream3); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma2_stream7); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma3_stream1); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma3_stream2); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma3_stream3); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma4_stream1); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma4_stream2); +EXTERN_GLOBAL(DMA_HandleTypeDef, hdma4_stream3); + +EXTERN_GLOBAL(SPI_HandleTypeDef, hspi1); +EXTERN_GLOBAL(SPI_HandleTypeDef, hspi2); +EXTERN_GLOBAL(SPI_HandleTypeDef, hspi3); + +EXTERN_GLOBAL(ADC_HandleTypeDef, hadc1); + + +/*********************************************************************************************************************** + * PTR * + ***********************************************************************************************************************/ + +EXTERN_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart1_rx); +EXTERN_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart1_tx); +EXTERN_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart2_rx); +EXTERN_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart2_tx); +EXTERN_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart3_rx); +EXTERN_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart3_tx); +EXTERN_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart4_rx); +EXTERN_GLOBAL_PTR(DMA_HandleTypeDef, hdma_usart4_tx); + +#ifdef __cplusplus +} +#endif diff --git a/stm32/marco.h b/stm32/marco.h new file mode 100644 index 0000000..9084402 --- /dev/null +++ b/stm32/marco.h @@ -0,0 +1,52 @@ +#pragma once +#ifndef ZARRAY_SIZE +#define ZARRAY_SIZE(x) ((int32_t)(sizeof(x) / sizeof(x[0]))) +#endif +#define ZMAX(a, b) ((a) > (b) ? (a) : (b)) +#define ZMIN(a, b) ((a) < (b) ? (a) : (b)) + +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32768) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647 - 1) +#endif +#ifndef INT64_MIN +#define INT64_MIN (-9223372036854775807LL - 1) +#endif + +#ifndef INT8_MAX +#define INT8_MAX 127 +#endif +#ifndef INT16_MAX +#define INT16_MAX 32767 +#endif +#ifndef INT32_MAX +#define INT32_MAX 2147483647 +#endif +#ifndef INT64_MAX +#define INT64_MAX 9223372036854775807LL +#endif + +#ifndef UINT8_MAX +#define UINT8_MAX 255 +#endif +#ifndef UINT16_MAX +#define UINT16_MAX 65535 +#endif +#ifndef UINT32_MAX +#define UINT32_MAX 0xffffffffU /* 4294967295U */ +#endif +#ifndef UINT64_MAX +#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ +#endif + +#define EARLY_ASSERT(x) \ + while (!(x)) { \ + ; \ + } + +// diff --git a/stm32/pin.c b/stm32/pin.c new file mode 100644 index 0000000..e142a81 --- /dev/null +++ b/stm32/pin.c @@ -0,0 +1,395 @@ +#include "pin.h" +const char* stm32pin2name(Pin_t pin) { + switch (pin) { + case PinNull: + return "PinNull"; + case PA0: + return "PA0"; + case PA1: + return "PA1"; + case PA2: + return "PA2"; + case PA3: + return "PA3"; + case PA4: + return "PA4"; + case PA5: + return "PA5"; + case PA6: + return "PA6"; + case PA7: + return "PA7"; + case PA8: + return "PA8"; + case PA9: + return "PA9"; + case PA10: + return "PA10"; + case PA11: + return "PA11"; + case PA12: + return "PA12"; + case PA13: + return "PA13"; + case PA14: + return "PA14"; + case PA15: + return "PA15"; + case PB0: + return "PB0"; + case PB1: + return "PB1"; + case PB2: + return "PB2"; + case PB3: + return "PB3"; + case PB4: + return "PB4"; + case PB5: + return "PB5"; + case PB6: + return "PB6"; + case PB7: + return "PB7"; + case PB8: + return "PB8"; + case PB9: + return "PB9"; + case PB10: + return "PB10"; + case PB11: + return "PB11"; + case PB12: + return "PB12"; + case PB13: + return "PB13"; + case PB14: + return "PB14"; + case PB15: + return "PB15"; + case PC0: + return "PC0"; + case PC1: + return "PC1"; + case PC2: + return "PC2"; + case PC3: + return "PC3"; + case PC4: + return "PC4"; + case PC5: + return "PC5"; + case PC6: + return "PC6"; + case PC7: + return "PC7"; + case PC8: + return "PC8"; + case PC9: + return "PC9"; + case PC10: + return "PC10"; + case PC11: + return "PC11"; + case PC12: + return "PC12"; + case PC13: + return "PC13"; + case PC14: + return "PC14"; + case PC15: + return "PC15"; + case PD0: + return "PD0"; + case PD1: + return "PD1"; + case PD2: + return "PD2"; + case PD3: + return "PD3"; + case PD4: + return "PD4"; + case PD5: + return "PD5"; + case PD6: + return "PD6"; + case PD7: + return "PD7"; + case PD8: + return "PD8"; + case PD9: + return "PD9"; + case PD10: + return "PD10"; + case PD11: + return "PD11"; + case PD12: + return "PD12"; + case PD13: + return "PD13"; + case PD14: + return "PD14"; + case PD15: + return "PD15"; + case PE0: + return "PE0"; + case PE1: + return "PE1"; + case PE2: + return "PE2"; + case PE3: + return "PE3"; + case PE4: + return "PE4"; + case PE5: + return "PE5"; + case PE6: + return "PE6"; + case PE7: + return "PE7"; + case PE8: + return "PE8"; + case PE9: + return "PE9"; + case PE10: + return "PE10"; + case PE11: + return "PE11"; + case PE12: + return "PE12"; + case PE13: + return "PE13"; + case PE14: + return "PE14"; + case PE15: + return "PE15"; + case PF0: + return "PF0"; + case PF1: + return "PF1"; + case PF2: + return "PF2"; + case PF3: + return "PF3"; + case PF4: + return "PF4"; + case PF5: + return "PF5"; + case PF6: + return "PF6"; + case PF7: + return "PF7"; + case PF8: + return "PF8"; + case PF9: + return "PF9"; + case PF10: + return "PF10"; + case PF11: + return "PF11"; + case PF12: + return "PF12"; + case PF13: + return "PF13"; + case PF14: + return "PF14"; + case PF15: + return "PF15"; + case PG0: + return "PG0"; + case PG1: + return "PG1"; + case PG2: + return "PG2"; + case PG3: + return "PG3"; + case PG4: + return "PG4"; + case PG5: + return "PG5"; + case PG6: + return "PG6"; + case PG7: + return "PG7"; + case PG8: + return "PG8"; + case PG9: + return "PG9"; + case PG10: + return "PG10"; + case PG11: + return "PG11"; + case PG12: + return "PG12"; + case PG13: + return "PG13"; + case PG14: + return "PG14"; + case PG15: + return "PG15"; + default: + break; + } + return "UNKNOWN_PIN"; +}; + +GPIO_TypeDef* stm32_get_gpio_group(Pin_t pin) { + int port = pin >> 4; + + switch (port) { + case (PA0 >> 4): +#ifdef GPIOA + return GPIOA; +#endif + break; + case (PB0 >> 4): +#ifdef GPIOB + return GPIOB; +#endif + break; + case (PC0 >> 4): +#ifdef GPIOC + return GPIOC; +#endif + break; + case (PD0 >> 4): +#ifdef GPIOD + return GPIOD; +#endif + break; + + case (PE0 >> 4): +#ifdef GPIOE + return GPIOE; +#endif + break; + case (PF0 >> 4): +#ifdef GPIOF + return GPIOF; +#endif + break; + case (PG0 >> 4): +#ifdef GPIOG + return GPIOG; +#endif + break; + default: + break; + } + return NULL; +} +const char* stm32_gpio_group_get_name(GPIO_TypeDef* gpio_group) { + if (gpio_group == GPIOA) { + return "GPIOA"; + } + if (gpio_group == GPIOB) { + return "GPIOB"; + } + if (gpio_group == GPIOC) { + return "GPIOC"; + } + if (gpio_group == GPIOD) { + return "GPIOD"; + } + if (gpio_group == GPIOE) { + return "GPIOE"; + } + if (gpio_group == GPIOF) { + return "GPIOF"; + } + if (gpio_group == GPIOG) { + return "GPIOG"; + } + return "unknown gpio group"; +} +uint16_t stm32_get_pinoff(Pin_t pin) { + uint16_t pinoff = pin & 0x0F; + switch (pinoff) { + case 0: + return GPIO_PIN_0; + case 1: + return GPIO_PIN_1; + case 2: + return GPIO_PIN_2; + case 3: + return GPIO_PIN_3; + case 4: + return GPIO_PIN_4; + case 5: + return GPIO_PIN_5; + case 6: + return GPIO_PIN_6; + case 7: + return GPIO_PIN_7; + case 8: + return GPIO_PIN_8; + case 9: + return GPIO_PIN_9; + case 10: + return GPIO_PIN_10; + case 11: + return GPIO_PIN_11; + case 12: + return GPIO_PIN_12; + case 13: + return GPIO_PIN_13; + case 14: + return GPIO_PIN_14; + case 15: + return GPIO_PIN_15; + default: + break; + }; + return 0; +} +const char* stm32_pinoff_get_name(uint16_t pinoff) { + if (pinoff == GPIO_PIN_0) { + return "0"; + } + if (pinoff == GPIO_PIN_1) { + return "1"; + } + if (pinoff == GPIO_PIN_2) { + return "2"; + } + if (pinoff == GPIO_PIN_3) { + return "3"; + } + if (pinoff == GPIO_PIN_4) { + return "4"; + } + if (pinoff == GPIO_PIN_5) { + return "5"; + } + if (pinoff == GPIO_PIN_6) { + return "6"; + } + if (pinoff == GPIO_PIN_7) { + return "7"; + } + if (pinoff == GPIO_PIN_8) { + return "8"; + } + if (pinoff == GPIO_PIN_9) { + return "9"; + } + if (pinoff == GPIO_PIN_10) { + return "10"; + } + if (pinoff == GPIO_PIN_11) { + return "11"; + } + if (pinoff == GPIO_PIN_12) { + return "12"; + } + if (pinoff == GPIO_PIN_13) { + return "13"; + } + if (pinoff == GPIO_PIN_14) { + return "14"; + } + if (pinoff == GPIO_PIN_15) { + return "15"; + } + return "unknown pinoff"; +} \ No newline at end of file diff --git a/stm32/pin.h b/stm32/pin.h new file mode 100644 index 0000000..fabd988 --- /dev/null +++ b/stm32/pin.h @@ -0,0 +1,125 @@ +#pragma once +#include "main.h" + +typedef enum { + PinNull = 0, + PA0 = 0x10, + PA1, + PA2, + PA3, + PA4, + PA5, + PA6, + PA7, + PA8, + PA9, + PA10, + PA11, + PA12, + PA13, + PA14, + PA15, + PB0 = 0x20, + PB1, + PB2, + PB3, + PB4, + PB5, + PB6, + PB7, + PB8, + PB9, + PB10, + PB11, + PB12, + PB13, + PB14, + PB15, + PC0 = 0x30, + PC1, + PC2, + PC3, + PC4, + PC5, + PC6, + PC7, + PC8, + PC9, + PC10, + PC11, + PC12, + PC13, + PC14, + PC15, + PD0 = 0x40, + PD1, + PD2, + PD3, + PD4, + PD5, + PD6, + PD7, + PD8, + PD9, + PD10, + PD11, + PD12, + PD13, + PD14, + PD15, + PE0 = 0x50, + PE1, + PE2, + PE3, + PE4, + PE5, + PE6, + PE7, + PE8, + PE9, + PE10, + PE11, + PE12, + PE13, + PE14, + PE15, + PF0 = 0x60, + PF1, + PF2, + PF3, + PF4, + PF5, + PF6, + PF7, + PF8, + PF9, + PF10, + PF11, + PF12, + PF13, + PF14, + PF15, + PG0 = 0x70, + PG1, + PG2, + PG3, + PG4, + PG5, + PG6, + PG7, + PG8, + PG9, + PG10, + PG11, + PG12, + PG13, + PG14, + PG15, +} Pin_t; + +const char* stm32pin2name(Pin_t pin); + +GPIO_TypeDef* stm32_get_gpio_group(Pin_t pin); +const char* stm32_gpio_group_get_name(GPIO_TypeDef* gpio_group); +uint16_t stm32_get_pinoff(Pin_t pin); +const char* stm32_pinoff_get_name(uint16_t pinoff); \ No newline at end of file diff --git a/stm32/stm32.hpp b/stm32/stm32.hpp new file mode 100644 index 0000000..3505208 --- /dev/null +++ b/stm32/stm32.hpp @@ -0,0 +1,123 @@ +#pragma once +extern "C" { +#include "main.h" + +#ifdef __STM32F4xx_HAL_H +#include "stm32f4xx.h" +#endif + +#ifdef HAL_CRYP_MODULE_ENABLED +#endif +#ifdef HAL_ADC_MODULE_ENABLED +#include "adc.h" +#endif +#ifdef HAL_CAN_MODULE_ENABLED +#include "can.h" +#endif +#ifdef HAL_CRC_MODULE_ENABLED +#include "crc.h" +#endif +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED +#endif +#ifdef HAL_DAC_MODULE_ENABLED +#endif +#ifdef HAL_DCMI_MODULE_ENABLED +#endif +#ifdef HAL_DMA2D_MODULE_ENABLED +#endif +#ifdef HAL_ETH_MODULE_ENABLED +#endif +#ifdef HAL_NAND_MODULE_ENABLED +#endif +#ifdef HAL_NOR_MODULE_ENABLED +#endif +#ifdef HAL_PCCARD_MODULE_ENABLED +#endif +#ifdef HAL_SRAM_MODULE_ENABLED +#endif +#ifdef HAL_SDRAM_MODULE_ENABLED +#endif +#ifdef HAL_HASH_MODULE_ENABLED +#endif +#ifdef HAL_I2C_MODULE_ENABLED +#include "i2c.h" +#endif +#ifdef HAL_I2S_MODULE_ENABLED +#endif +#ifdef HAL_IWDG_MODULE_ENABLED +#endif +#ifdef HAL_LTDC_MODULE_ENABLED +#endif +#ifdef HAL_RNG_MODULE_ENABLED +#endif +#ifdef HAL_RTC_MODULE_ENABLED +#endif +#ifdef HAL_SAI_MODULE_ENABLED +#endif +#ifdef HAL_SD_MODULE_ENABLED +#endif +#ifdef HAL_MMC_MODULE_ENABLED +#endif +#ifdef HAL_SPI_MODULE_ENABLED +#include "spi.h" +#endif +#ifdef HAL_TIM_MODULE_ENABLED +#include "tim.h" +#endif +#ifdef HAL_UART_MODULE_ENABLED +#include "usart.h" +#endif +#ifdef HAL_USART_MODULE_ENABLED +#include "usart.h" +#endif +#ifdef HAL_IRDA_MODULE_ENABLED +#endif +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#endif +#ifdef HAL_SMBUS_MODULE_ENABLED +#endif +#ifdef HAL_WWDG_MODULE_ENABLED +#endif +#ifdef HAL_PCD_MODULE_ENABLED +#endif +#ifdef HAL_HCD_MODULE_ENABLED +#endif +#ifdef HAL_DSI_MODULE_ENABLED +#endif +#ifdef HAL_QSPI_MODULE_ENABLED +#endif +#ifdef HAL_QSPI_MODULE_ENABLED +#endif +#ifdef HAL_CEC_MODULE_ENABLED +#endif +#ifdef HAL_FMPI2C_MODULE_ENABLED +#endif +#ifdef HAL_FMPSMBUS_MODULE_ENABLED +#endif +#ifdef HAL_SPDIFRX_MODULE_ENABLED +#endif +#ifdef HAL_DFSDM_MODULE_ENABLED +#endif +#ifdef HAL_LPTIM_MODULE_ENABLED +#endif +#ifdef HAL_GPIO_MODULE_ENABLED +#include "gpio.h" +#endif +#ifdef HAL_EXTI_MODULE_ENABLED +#endif +#ifdef HAL_DMA_MODULE_ENABLED +#endif +#ifdef HAL_RCC_MODULE_ENABLED +#endif +#ifdef HAL_FLASH_MODULE_ENABLED +#endif +#ifdef HAL_PWR_MODULE_ENABLED +#endif +#ifdef HAL_CORTEX_MODULE_ENABLED +#endif +#include "marco.h" +#include "pin.h" +#include "tim.h" +#include "critical.h" +#include "gins.h" +} diff --git a/stm32/stm32irq.c b/stm32/stm32irq.c new file mode 100644 index 0000000..0270390 --- /dev/null +++ b/stm32/stm32irq.c @@ -0,0 +1,51 @@ +#include "gins.h" +#include "stm32f4xx_it.h" + +void DebugMon_Handler(void) {} +/*********************************************************************************************************************** + * IRQ * + ***********************************************************************************************************************/ + +void DMA1_Stream1_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma1_stream1); } +void DMA2_Stream2_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma2_stream2); } +void DMA1_Stream3_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma1_stream3); } +void DMA2_Stream7_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma2_stream7); } +void DMA1_Stream5_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma1_stream5); } +void DMA1_Stream6_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma1_stream6); } + +void CAN1_TX_IRQHandler(void) { + if (hcan1_enable) HAL_CAN_IRQHandler(&hcan1); +} +void CAN1_RX0_IRQHandler(void) { + if (hcan1_enable) HAL_CAN_IRQHandler(&hcan1); +} +void CAN1_RX1_IRQHandler(void) { + if (hcan1_enable) HAL_CAN_IRQHandler(&hcan1); +} +void CAN1_SCE_IRQHandler(void) { + if (hcan1_enable) HAL_CAN_IRQHandler(&hcan1); +} +// 定时器 + +extern TIM_HandleTypeDef htim11; + +void TIM1_TRG_COM_TIM11_IRQHandler(void) { + HAL_TIM_IRQHandler(&htim11); + if (htim1_enable) HAL_TIM_IRQHandler(&htim1); +} + +void TIM6_DAC_IRQHandler(void) { + if (htim6_enable) HAL_TIM_IRQHandler(&htim6); +} +void TIM7_IRQHandler(void) { + if (htim7_enable) HAL_TIM_IRQHandler(&htim7); +} +// 串口 +void USART1_IRQHandler(void) { HAL_UART_IRQHandler(&huart1); } +void USART2_IRQHandler(void) { HAL_UART_IRQHandler(&huart2); } +void USART3_IRQHandler(void) { HAL_UART_IRQHandler(&huart3); } +void UART4_IRQHandler(void) { HAL_UART_IRQHandler(&huart4); } + +/*********************************************************************************************************************** + * EXT * + ***********************************************************************************************************************/ \ No newline at end of file diff --git a/stm32/tim.c b/stm32/tim.c new file mode 100644 index 0000000..2d2b4ca --- /dev/null +++ b/stm32/tim.c @@ -0,0 +1,76 @@ +#include "tim.h" + +const char* tim_get_name(TIM_TypeDef* tim) { +#ifdef TIM1 + if (tim == TIM1) { + return "TIM1"; + } +#endif +#ifdef TIM2 + if (tim == TIM2) { + return "TIM2"; + } +#endif +#ifdef TIM3 + if (tim == TIM3) { + return "TIM3"; + } +#endif +#ifdef TIM4 + if (tim == TIM4) { + return "TIM4"; + } +#endif +#ifdef TIM5 + if (tim == TIM5) { + return "TIM5"; + } +#endif +#ifdef TIM6 + if (tim == TIM6) { + return "TIM6"; + } +#endif +#ifdef TIM7 + if (tim == TIM7) { + return "TIM7"; + } +#endif +#ifdef TIM8 + if (tim == TIM8) { + return "TIM8"; + } +#endif +#ifdef TIM9 + if (tim == TIM9) { + return "TIM9"; + } +#endif +#ifdef TIM10 + if (tim == TIM10) { + return "TIM10"; + } +#endif +#ifdef TIM11 + if (tim == TIM11) { + return "TIM11"; + } +#endif +#ifdef TIM12 + if (tim == TIM12) { + return "TIM12"; + } +#endif +#ifdef TIM13 + if (tim == TIM13) { + return "TIM13"; + } +#endif +#ifdef TIM14 + if (tim == TIM14) { + return "TIM14"; + } +#endif + + return "unknowntim"; +} \ No newline at end of file diff --git a/stm32/tim.h b/stm32/tim.h new file mode 100644 index 0000000..84e4aff --- /dev/null +++ b/stm32/tim.h @@ -0,0 +1,4 @@ +#pragma once +#include "main.h" + +const char* tim_get_name(TIM_TypeDef* tim); \ No newline at end of file diff --git a/ticket.cpp b/ticket.cpp new file mode 100644 index 0000000..1e6de3a --- /dev/null +++ b/ticket.cpp @@ -0,0 +1,25 @@ +#include "ticket.hpp" +#include "main.h" + +extern "C" { +uint32_t zos_get_tick(void) { + // #ifdef PC_IFLYTOP_ENABLE_OS + // return osKernelSysTick(); + // #else + return HAL_GetTick(); + // #endif +} +uint32_t zos_haspassedms2(uint32_t lastticket, uint32_t nowticket) { + if (nowticket >= lastticket) { + return nowticket - lastticket; + } + return UINT32_MAX - lastticket + nowticket; +} +uint32_t zos_haspassedms(uint32_t ticket) { + uint32_t nowticket = zos_get_tick(); + if (nowticket >= ticket) { + return nowticket - ticket; + } + return UINT32_MAX - ticket + nowticket; +} +} diff --git a/ticket.hpp b/ticket.hpp new file mode 100644 index 0000000..9ad99d6 --- /dev/null +++ b/ticket.hpp @@ -0,0 +1,8 @@ +#pragma once +#include + +extern "C" { +uint32_t zos_get_tick(void); +uint32_t zos_haspassedms(uint32_t ticket); +uint32_t zos_haspassedms2(uint32_t lastticket, uint32_t nowticket); +} \ No newline at end of file diff --git a/zgpio.cpp b/zgpio.cpp new file mode 100644 index 0000000..9f7350d --- /dev/null +++ b/zgpio.cpp @@ -0,0 +1,375 @@ + +#include "zgpio.hpp" +extern "C" { +#include "logger.h" +} +#define TAG "GPIO" +#define PC_IRQ_PREEMPTPRIORITY_DEFAULT 5 + +namespace iflytop { +/******************************************************************************* + * LISTENER * + *******************************************************************************/ + +static ZGPIO *s_irqGPIO[20]; +int s_irqGPIO_num = 0; + +extern "C" { +/** + * @brief This function handles EXTI line3 interrupt. + */ +void EXTI0_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); } +void EXTI1_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1); } +void EXTI2_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2); } +void EXTI3_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); } +void EXTI4_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4); } +void EXTI9_5_IRQHandler(void) { + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9); +} +void EXTI15_10_IRQHandler(void) { + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15); +} +void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { + for (int i = 0; i < s_irqGPIO_num; i++) { + s_irqGPIO[i]->tryTriggerIRQ(GPIO_Pin); + } +} +} + +void ZGPIO::regListener(onirq_t listener) { m_onirq = listener; } + +/******************************************************************************* + * GPIOIMPL * + *******************************************************************************/ + +/******************************************************************************* + * BASE_FUNC * + *******************************************************************************/ +bool ZGPIO::enableClock() { +#ifdef GPIOA + if (m_gpio == GPIOA) { + __HAL_RCC_GPIOA_CLK_ENABLE(); + return true; + } +#endif +#ifdef GPIOB + if (m_gpio == GPIOB) { + __HAL_RCC_GPIOB_CLK_ENABLE(); + return true; + } +#endif +#ifdef GPIOC + if (m_gpio == GPIOC) { + __HAL_RCC_GPIOC_CLK_ENABLE(); + return true; + } +#endif +#ifdef GPIOD + if (m_gpio == GPIOD) { + __HAL_RCC_GPIOD_CLK_ENABLE(); + return true; + } +#endif +#ifdef GPIOE + if (m_gpio == GPIOE) { + __HAL_RCC_GPIOE_CLK_ENABLE(); + return true; + } +#endif +#ifdef GPIOF + if (m_gpio == GPIOF) { + __HAL_RCC_GPIOF_CLK_ENABLE(); + return true; + } +#endif +#ifdef GPIOG + if (m_gpio == GPIOG) { + __HAL_RCC_GPIOG_CLK_ENABLE(); + return true; + } +#endif +#ifdef GPIOH + if (m_gpio == GPIOH) { + __HAL_RCC_GPIOH_CLK_ENABLE(); + return true; + } +#endif +#ifdef GPIOI + if (m_gpio == GPIOI) { + __HAL_RCC_GPIOI_CLK_ENABLE(); + return true; + } +#endif +#ifdef GPIOJ + if (m_gpio == GPIOJ) { + __HAL_RCC_GPIOJ_CLK_ENABLE(); + return true; + } +#endif +#ifdef GPIOK + if (m_gpio == GPIOK) { + __HAL_RCC_GPIOK_CLK_ENABLE(); + return true; + } +#endif + return false; +} + +void regIRQGPIO(ZGPIO *gpio) { + for (int i = 0; i < s_irqGPIO_num; i++) { + if (s_irqGPIO[i] == gpio) { + return; + } + } + + EARLY_ASSERT((s_irqGPIO_num + 1) < (int)ZARRAY_SIZE(s_irqGPIO)); + s_irqGPIO[s_irqGPIO_num] = gpio; + s_irqGPIO_num++; +} + +bool ZGPIO::isMirror() { return m_mirror; } +void ZGPIO::initAsInput(Pin_t pin, GPIOMode_t mode, GPIOIrqType_t irqtype, bool mirror) { + if (pin == PinNull) return; + + m_mirror = mirror; + m_mode = mode; + m_irqtype = irqtype; + m_gpiotype = kType_Input; + + m_pin = pin; + m_gpio = stm32_get_gpio_group(pin); + m_pinoff = stm32_get_pinoff(pin); + + uint32_t pulluptype = 0; + if (mode == kMode_nopull) { + pulluptype = GPIO_NOPULL; + } else if (mode == kMode_pullup) { + pulluptype = GPIO_PULLUP; + } else if (mode == kMode_pulldown) { + pulluptype = GPIO_PULLDOWN; + } + + enableClock(); + GPIO_InitTypeDef m_GPIO_InitStruct = {0}; + if (m_irqtype == kIRQ_noIrq) { + m_GPIO_InitStruct.Pin = m_pinoff; + m_GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + m_GPIO_InitStruct.Pull = pulluptype; + m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + } else if (m_irqtype == kIRQ_risingIrq) { + m_GPIO_InitStruct.Pin = m_pinoff; + m_GPIO_InitStruct.Mode = m_mirror ? GPIO_MODE_IT_FALLING : GPIO_MODE_IT_RISING; + m_GPIO_InitStruct.Pull = pulluptype; + m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + } else if (m_irqtype == kIRQ_fallingIrq) { + m_GPIO_InitStruct.Pin = m_pinoff; + m_GPIO_InitStruct.Mode = !m_mirror ? GPIO_MODE_IT_FALLING : GPIO_MODE_IT_RISING; + m_GPIO_InitStruct.Pull = pulluptype; + m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + } else if (m_irqtype == kIRQ_risingAndFallingIrq) { + m_GPIO_InitStruct.Pin = m_pinoff; + m_GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; + m_GPIO_InitStruct.Pull = pulluptype; + m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + } + + HAL_GPIO_Init(m_gpio, &m_GPIO_InitStruct); + if (m_irqtype != kIRQ_noIrq) { + regIRQGPIO(this); + lastLevel = getState(); + HAL_NVIC_SetPriority(getEXTIIRQn(), PC_IRQ_PREEMPTPRIORITY_DEFAULT, 0); + HAL_NVIC_EnableIRQ(getEXTIIRQn()); + } + + m_initflag = true; + return; +} +void ZGPIO::initAsOutput(Pin_t pin, GPIOMode_t mode, bool mirror, bool initLevel) { + if (pin == PinNull) return; + + m_mirror = mirror; + m_mode = mode; + m_irqtype = kIRQ_noIrq; + m_gpiotype = kType_Output; + m_pin = pin; + m_gpio = stm32_get_gpio_group(pin); + m_pinoff = stm32_get_pinoff(pin); + + enableClock(); + + GPIO_InitTypeDef m_GPIO_InitStruct = {0}; + initLevel = m_mirror ? !initLevel : initLevel; + GPIO_PinState pinState = initLevel ? GPIO_PIN_SET : GPIO_PIN_RESET; + + HAL_GPIO_WritePin(m_gpio, m_pinoff, pinState); + if (m_mode == kMode_nopull) { + m_GPIO_InitStruct.Pin = m_pinoff; + m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + m_GPIO_InitStruct.Pull = GPIO_NOPULL; + m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + } else if (m_mode == kMode_pullup) { + m_GPIO_InitStruct.Pin = m_pinoff; + m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + m_GPIO_InitStruct.Pull = GPIO_PULLUP; + m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + } else if (m_mode == kMode_pulldown) { + m_GPIO_InitStruct.Pin = m_pinoff; + m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + m_GPIO_InitStruct.Pull = GPIO_PULLDOWN; + m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + } else if (m_mode == kMode_od) { + m_GPIO_InitStruct.Pin = m_pinoff; + m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + m_GPIO_InitStruct.Pull = 0; + m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + } + HAL_GPIO_Init(m_gpio, &m_GPIO_InitStruct); + m_initflag = true; + + return; +} +bool ZGPIO::isItRisingEXITGPIO() { return m_irqtype == kIRQ_risingIrq; } +bool ZGPIO::isItFallingEXITGPIO() { return m_irqtype == kIRQ_fallingIrq; } +bool ZGPIO::isItRisingAndItFallingEXITGPIO() { return m_irqtype == kIRQ_risingAndFallingIrq; } + +/******************************************************************************* + * EXT FUNC * + *******************************************************************************/ + +/** + * @brief 判断当前是否是这个引脚产生的中断 + * + * @param checkloop + * @param GPIO_Pin + * @return true + * @return false + * + * 由于STM32的GPIO中断线是共用的,所以需要根据GPIO的即时状态判断是否是这个引脚产生的中?? + * + * 判断逻辑??: + * 先判断所有中断模式是 GPIO_MODE_IT_RISING ?? GPIO_MODE_IT_FALLING 的引脚,采样当前电平判断是否是这个引脚产生的中断 + * 再判断中断模式是 GPIO_MODE_IT_RISING_FALLING 的引脚,直接返回true + */ +bool ZGPIO::tryTriggerIRQ(uint16_t GPIO_Pin) { + bool ret = false; + bool nostate = false; + if (GPIO_Pin != m_pinoff) return false; + if (!(isItRisingEXITGPIO() || isItFallingEXITGPIO() || isItRisingAndItFallingEXITGPIO())) { + return false; + } + + nostate = getState(); + + if (isItRisingEXITGPIO()) { + if (nostate) { + ret = true; + if (m_onirq) { + m_onirq(this, kRisingIrqEvent); + } + } + } else if (isItFallingEXITGPIO()) { + if (!nostate) { + ret = true; + if (m_onirq) { + m_onirq(this, kFallingIrqEvent); + } + } + } else { + if (lastLevel != nostate) { + ret = true; + if (m_onirq) { + if (lastLevel) + m_onirq(this, kRisingIrqEvent); + else + m_onirq(this, kFallingIrqEvent); + } + } + } + + lastLevel = nostate; + return ret; +} + +void ZGPIO::toggleState() { HAL_GPIO_TogglePin(m_gpio, m_pinoff); } +uint32_t ZGPIO::getStateUint32() { + if (getState()) + return 1; + else + return 0; +} + +bool ZGPIO::getState() { + if (m_pin == PinNull) return false; + bool ret = false; + if (HAL_GPIO_ReadPin(m_gpio, m_pinoff) == GPIO_PIN_SET) { + ret = true; + } else { + ret = false; + } + if (m_mirror) ret = !ret; + return ret; +} +bool ZGPIO::setState(bool state) { + if (m_pin == PinNull) return true; + + if (m_mirror) state = !state; + + if (m_log_when_setstate) { + ZLOGI(TAG, "%s%s set %d", stm32_gpio_group_get_name(m_gpio), stm32_pinoff_get_name(m_pinoff), state); + } + if (state) { + HAL_GPIO_WritePin(m_gpio, m_pinoff, GPIO_PIN_SET); + } else { + HAL_GPIO_WritePin(m_gpio, m_pinoff, GPIO_PIN_RESET); + } + return true; +} +IRQn_Type ZGPIO::getEXTIIRQn() { + switch (m_pinoff) { + case GPIO_PIN_0: + return EXTI0_IRQn; + case GPIO_PIN_1: + return EXTI1_IRQn; + case GPIO_PIN_2: + return EXTI2_IRQn; + case GPIO_PIN_3: + return EXTI3_IRQn; + case GPIO_PIN_4: + return EXTI4_IRQn; + case GPIO_PIN_5: + case GPIO_PIN_6: + case GPIO_PIN_7: + case GPIO_PIN_8: + case GPIO_PIN_9: + return EXTI9_5_IRQn; + case GPIO_PIN_10: + case GPIO_PIN_11: + case GPIO_PIN_12: + case GPIO_PIN_13: + case GPIO_PIN_14: + case GPIO_PIN_15: + return EXTI15_10_IRQn; + default: + ZASSERT(0); + } + return EXTI0_IRQn; +} +/** + * @brief 初始化GPIO为中断模?? + * + * @param pull GPIO_NOPULL, GPIO_PULLUP, GPIO_PULLDOWN + * @param mode GPIO_MODE_IT_RISING, GPIO_MODE_IT_FALLING, GPIO_MODE_IT_RISING_FALLING + * @return true + * @return false + */ + +} // namespace iflytop diff --git a/zgpio.hpp b/zgpio.hpp new file mode 100644 index 0000000..2fa0cca --- /dev/null +++ b/zgpio.hpp @@ -0,0 +1,100 @@ +#pragma once +#include +#include "stm32/stm32.hpp" +namespace iflytop { +using namespace std; + +#define STM32_GPIO_LISTENER_NUM 10 +class ZGPIO { + public: + typedef enum { + kRisingIrqEvent, + kFallingIrqEvent, + } IrqTypeEvent_t; + + typedef enum { + kMode_nopull, // + kMode_pullup, // + kMode_pulldown, // + kMode_od, // + } GPIOMode_t; + + typedef enum { kType_AIN, kType_Input, kType_Output } GPIOType_t; + + typedef enum { + kIRQ_noIrq, + kIRQ_risingIrq, + kIRQ_fallingIrq, + kIRQ_risingAndFallingIrq, + } GPIOIrqType_t; + + typedef function onirq_t; + + typedef struct { + Pin_t pin; + GPIOMode_t mode; + GPIOIrqType_t irqtype; + bool mirror; + } InputGpioCfg_t; + + typedef struct { + Pin_t pin; + GPIOMode_t mode; + bool mirror; + bool initLevel; + bool log_when_setstate; + } OutputGpioCfg_t; + + private: + Pin_t m_pin = PinNull; + GPIO_TypeDef *m_gpio; + uint16_t m_pinoff; + GPIOType_t m_gpiotype; + GPIOMode_t m_mode; + GPIOIrqType_t m_irqtype; + bool m_mirror; + bool lastLevel; + bool m_log_when_setstate = false; + + onirq_t m_onirq; + bool m_initflag; + + public: + ZGPIO(){}; + + void initAsInput(Pin_t pin, GPIOMode_t mode, GPIOIrqType_t irqtype, bool mirror); + void initAsOutput(Pin_t pin, GPIOMode_t mode, bool mirror, bool initLevel); + void initAsOutput(OutputGpioCfg_t *outputcfg) { + m_log_when_setstate = outputcfg->log_when_setstate; + initAsOutput(outputcfg->pin, outputcfg->mode, outputcfg->mirror, outputcfg->initLevel); + } + void initAsInput(InputGpioCfg_t *inputcfg) { initAsInput(inputcfg->pin, inputcfg->mode, inputcfg->irqtype, inputcfg->mirror); } + void enableTrace(bool enable) { m_log_when_setstate = enable; } + void regListener(onirq_t listener); + + bool isMirror(); + bool isItRisingEXITGPIO(); + bool isItFallingEXITGPIO(); + bool isItRisingAndItFallingEXITGPIO(); + + bool getState(); + uint32_t getStateUint32(); + bool setState(bool state); + void toggleState(); + + bool isNull() { return m_pin == PinNull; } + + Pin_t getPin() { return m_pin; } + + IRQn_Type getEXTIIRQn(); + GPIO_TypeDef *getHalPinPort() { return m_gpio; } + uint16_t getHalPin() { return m_pinoff; } + + bool tryTriggerIRQ(uint16_t GPIO_Pin); + + bool isInit() { return m_initflag; } + + private: + bool enableClock(); +}; +} // namespace iflytop \ No newline at end of file diff --git a/zusdelay.cpp b/zusdelay.cpp new file mode 100644 index 0000000..c1ae291 --- /dev/null +++ b/zusdelay.cpp @@ -0,0 +1,116 @@ +#include "zusdelay.hpp" +extern "C" { + +static TIM_HandleTypeDef* m_usdleaytim; + +static HAL_StatusTypeDef _HAL_TIM_Base_Start(TIM_HandleTypeDef* htim) __attribute__((optimize("O2"))); +static HAL_StatusTypeDef _HAL_TIM_Base_Stop(TIM_HandleTypeDef* htim) __attribute__((optimize("O2"))); + +static HAL_StatusTypeDef _HAL_TIM_Base_Start(TIM_HandleTypeDef* htim) { + uint32_t tmpsmcr; + /* Check the TIM state */ + if (htim->State != HAL_TIM_STATE_READY) { + return HAL_ERROR; + } + htim->State = HAL_TIM_STATE_BUSY; + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) { + __HAL_TIM_ENABLE(htim); + } + } else { + __HAL_TIM_ENABLE(htim); + } + return HAL_OK; +} + +static HAL_StatusTypeDef _HAL_TIM_Base_Stop(TIM_HandleTypeDef* htim) { + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_READY; + /* Return function status */ + return HAL_OK; +} + +static uint32_t chip_get_timer_clock_sorce_freq(TIM_HandleTypeDef* tim) { + uint32_t timClkFreq = 0; +#if 0 + uint32_t pclk1Freq = HAL_RCC_GetPCLK1Freq(); + uint32_t pclk2Freq = HAL_RCC_GetPCLK2Freq(); + uint32_t sysClkFreq = HAL_RCC_GetSysClockFreq(); +#endif + + uint32_t pFLatency; + RCC_ClkInitTypeDef clkconfig; + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + bool isAPB2 = false; + +#ifdef TIM1 + if (tim->Instance == TIM1) isAPB2 = true; +#endif +#ifdef TIM8 + if (tim->Instance == TIM8) isAPB2 = true; +#endif +#ifdef TIM9 + if (tim->Instance == TIM9) isAPB2 = true; +#endif +#ifdef TIM10 + if (tim->Instance == TIM10) isAPB2 = true; +#endif +#ifdef TIM11 + if (tim->Instance == TIM11) isAPB2 = true; +#endif + if (isAPB2) { + if (clkconfig.APB2CLKDivider == RCC_HCLK_DIV1) { + timClkFreq = HAL_RCC_GetPCLK2Freq(); + } else { + timClkFreq = 2 * HAL_RCC_GetPCLK2Freq(); + } + } else { + if (clkconfig.APB1CLKDivider == RCC_HCLK_DIV1) { + timClkFreq = HAL_RCC_GetPCLK1Freq(); + } else { + timClkFreq = 2 * HAL_RCC_GetPCLK1Freq(); + } + } + return timClkFreq; +} + +uint32_t zusdelay_init(TIM_HandleTypeDef* tim) { + m_usdleaytim = tim; + + uint32_t freq = chip_get_timer_clock_sorce_freq(tim); + uint32_t prescaler = freq / 1000000 - 1; // 1us + uint32_t autoreload = 65535; + + HAL_TIM_Base_DeInit(tim); + + tim->Init.Prescaler = prescaler; + tim->Init.CounterMode = TIM_COUNTERMODE_UP; + tim->Init.Period = autoreload; + tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + HAL_TIM_Base_Init(tim); + + return 0; +} +static inline void __zchip_clock_early_delayus(uint32_t n) { + volatile uint32_t counter = 0; + __HAL_TIM_SET_COUNTER(m_usdleaytim, 0); + _HAL_TIM_Base_Start(m_usdleaytim); + while (counter < n) { + counter = __HAL_TIM_GET_COUNTER(m_usdleaytim); + } + _HAL_TIM_Base_Stop(m_usdleaytim); +} +void zusdelay_early_delayus(uint32_t _us) { + uint32_t us = _us % 1000; + uint32_t ms = _us / 1000; + if (us > 0) { + __zchip_clock_early_delayus(us); + } + for (uint32_t i = 0; i < ms; i++) { + __zchip_clock_early_delayus(1000); + } +} +} \ No newline at end of file diff --git a/zusdelay.hpp b/zusdelay.hpp new file mode 100644 index 0000000..c5c72de --- /dev/null +++ b/zusdelay.hpp @@ -0,0 +1,12 @@ +#pragma once +#include + +#include "main.h" + +extern "C" { +// 微秒延迟定时器,注意该延时定时器需要按照以下文档进行配置 +// http://192.168.1.3:3000/zwikipedia/iflytop_wikipedia/src/branch/master/doc/stm32cubemx_us_timer.md + +uint32_t zusdelay_init(TIM_HandleTypeDef* tim); +void zusdelay_early_delayus(uint32_t us); +}