39 changed files with 1981 additions and 0 deletions
-
7README.md
-
11chip/basic/base.hpp
-
8chip/basic/basic_h/basic.hpp
-
45chip/basic/basic_h/marco.h
-
117chip/basic/basic_h/pin.hpp
-
120chip/basic/basic_h/stm32_header.h
-
178chip/basic/chip_helper.cpp
-
17chip/basic/chip_helper.hpp
-
41chip/basic/clock.cpp
-
19chip/basic/clock.hpp
-
3chip/basic/cppdep.hpp
-
4chip/basic/critical_context.cpp
-
15chip/basic/critical_context.hpp
-
32chip/basic/logger.cpp
-
37chip/basic/logger.hpp
-
16chip/chip.cpp
-
19chip/chip.hpp
-
64chip/chip_tim_irq_shceduler.cpp
-
58chip/chip_tim_irq_shceduler.hpp
-
18chip/irq_dispatcher.cpp
-
24chip/irq_dispatcher.hpp
-
91chip/zcan_irq_dispatcher.cpp
-
41chip/zcan_irq_dispatcher.hpp
-
348chip/zgpio.cpp
-
74chip/zgpio.hpp
-
48chip/ztim.cpp
-
62chip/ztim.hpp
-
220chip/zuart.cpp
-
69chip/zuart.hpp
-
13os/README.md
-
19os/delay.cpp
-
7os/delay.hpp
-
53os/mutex.cpp
-
36os/mutex.hpp
-
6os/osbasic_h.hpp
-
11os/ticket.cpp
-
7os/ticket.hpp
-
4os/zos.cpp
-
19os/zos.hpp
@ -0,0 +1,7 @@ |
|||
``` |
|||
chip: stm32hal库对接接口 |
|||
os : 操作系统相关方法,上层代码依赖这一层 |
|||
hal : 硬件抽象层,依赖chip层和os层 |
|||
components: |
|||
CHIP: |
|||
``` |
@ -0,0 +1,11 @@ |
|||
#pragma once
|
|||
#include "basic_h/basic.hpp"
|
|||
//
|
|||
#include "cppdep.hpp"
|
|||
//
|
|||
#include "clock.hpp"
|
|||
#include "logger.hpp"
|
|||
//
|
|||
#include "chip_helper.hpp"
|
|||
//
|
|||
#include "critical_context.hpp"
|
@ -0,0 +1,8 @@ |
|||
#pragma once
|
|||
#include <stdint.h>
|
|||
//
|
|||
#include "project_configs.h"
|
|||
//
|
|||
#include "marco.h"
|
|||
#include "pin.hpp"
|
|||
#include "stm32_header.h"
|
@ -0,0 +1,45 @@ |
|||
#pragma once |
|||
#ifndef ZARRAY_SIZE |
|||
#define ZARRAY_SIZE(x) (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 |
@ -0,0 +1,117 @@ |
|||
#pragma once
|
|||
|
|||
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; |
@ -0,0 +1,120 @@ |
|||
#pragma once |
|||
|
|||
#include "main.h" |
|||
|
|||
#ifdef __STM32F4xx_HAL_H |
|||
#include "stm32f4xx.h" |
|||
#endif |
|||
|
|||
#ifdef HAL_CRYP_MODULE_ENABLED |
|||
#endif |
|||
#ifdef HAL_ADC_MODULE_ENABLED |
|||
#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 |
|||
#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 |
|||
|
|||
extern "C" { |
|||
typedef TIM_HandleTypeDef zchip_tim_t; |
|||
typedef UART_HandleTypeDef zchip_uart_t; |
|||
} |
@ -0,0 +1,178 @@ |
|||
#include "chip_helper.hpp"
|
|||
|
|||
extern "C" { |
|||
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(); |
|||
} |
|||
} |
|||
|
|||
GPIO_TypeDef* chip_get_gpio(Pin_t pin) { |
|||
int port = pin >> 4; |
|||
|
|||
switch (port) { |
|||
case 1: |
|||
#ifdef GPIOA
|
|||
return GPIOA; |
|||
#endif
|
|||
break; |
|||
case 2: |
|||
#ifdef GPIOB
|
|||
return GPIOB; |
|||
#endif
|
|||
break; |
|||
case 3: |
|||
#ifdef GPIOC
|
|||
return GPIOC; |
|||
#endif
|
|||
break; |
|||
case 4: |
|||
#ifdef GPIOD
|
|||
return GPIOD; |
|||
#endif
|
|||
break; |
|||
|
|||
case 5: |
|||
#ifdef GPIOE
|
|||
return GPIOE; |
|||
#endif
|
|||
break; |
|||
case 6: |
|||
#ifdef GPIOF
|
|||
return GPIOF; |
|||
#endif
|
|||
break; |
|||
case 7: |
|||
#ifdef GPIOG
|
|||
return GPIOG; |
|||
#endif
|
|||
break; |
|||
default: |
|||
break; |
|||
} |
|||
return NULL; |
|||
} |
|||
uint16_t chip_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; |
|||
} |
|||
|
|||
uint32_t chip_get_timer_clock_sorce_freq(TIM_HandleTypeDef* tim) { |
|||
uint32_t timClkFreq = 0; |
|||
uint32_t pclk1Freq = HAL_RCC_GetPCLK1Freq(); |
|||
uint32_t pclk2Freq = HAL_RCC_GetPCLK2Freq(); |
|||
uint32_t sysClkFreq = HAL_RCC_GetSysClockFreq(); |
|||
|
|||
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; |
|||
} |
|||
} |
|||
|
|||
bool chip_calculate_prescaler_and_autoreload_by_expect_freq(uint32_t timerInClk, float infreqhz, uint32_t* prescaler, uint32_t* autoreload) { |
|||
/**
|
|||
* @brief 计算寄存器数值 |
|||
*/ |
|||
float psc_x_arr = timerInClk / infreqhz; |
|||
uint32_t psc = 0; |
|||
uint32_t arr = 65534; |
|||
for (; arr > 2; arr--) { |
|||
psc = psc_x_arr / arr; |
|||
if (psc >= 1) { |
|||
uint32_t tmparr = psc_x_arr / psc; |
|||
if (tmparr >= 65534) continue; |
|||
break; |
|||
} |
|||
} |
|||
if (psc == 0) return false; |
|||
if (arr <= 3) return false; // 定时器一周期的分辨率太小了
|
|||
arr = psc_x_arr / psc; |
|||
|
|||
int psc_x_arr_real = arr * psc; |
|||
float realfreq = timerInClk / psc_x_arr_real; |
|||
|
|||
arr = arr - 1; |
|||
psc = psc - 1; |
|||
uint16_t comparevalue = 50 / 100.0 * arr; |
|||
|
|||
*prescaler = psc; |
|||
*autoreload = arr; |
|||
return true; |
|||
} |
@ -0,0 +1,17 @@ |
|||
#pragma once
|
|||
#include <stdio.h>
|
|||
|
|||
#include "basic_h/basic.hpp"
|
|||
//
|
|||
#include "clock.hpp"
|
|||
|
|||
extern "C" { |
|||
GPIO_TypeDef* chip_get_gpio(Pin_t pin); |
|||
uint16_t chip_get_pinoff(Pin_t pin); |
|||
|
|||
void chip_critical_enter(void); |
|||
void chip_critical_exit(void); |
|||
|
|||
uint32_t chip_get_timer_clock_sorce_freq(TIM_HandleTypeDef* tim); |
|||
bool chip_calculate_prescaler_and_autoreload_by_expect_freq(uint32_t timerInClk, float infreqhz, uint32_t* prescaler, uint32_t* autoreload); |
|||
} |
@ -0,0 +1,41 @@ |
|||
#include "clock.hpp"
|
|||
extern "C" { |
|||
|
|||
static zchip_tim_t* m_usdleaytim; |
|||
|
|||
uint32_t zchip_clock_init(zchip_clock_cfg_t* cfg) { |
|||
m_usdleaytim = cfg->usdleaytim; |
|||
return 0; |
|||
} |
|||
//
|
|||
uint32_t zchip_clock_get_ticket(void) { return HAL_GetTick(); } |
|||
uint32_t zchip_clock_hasspassed(uint32_t ticket) { |
|||
uint32_t nowticket = HAL_GetTick(); |
|||
if (nowticket >= ticket) { |
|||
return nowticket - ticket; |
|||
} |
|||
return UINT32_MAX - ticket + nowticket; |
|||
} |
|||
|
|||
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 zchip_clock_early_delayus(uint32_t n) { |
|||
uint32_t us = n % 1000; |
|||
uint32_t ms = n / 1000; |
|||
if (us > 0) { |
|||
__zchip_clock_early_delayus(us); |
|||
} |
|||
for (uint32_t i = 0; i < ms; i++) { |
|||
__zchip_clock_early_delayus(1000); |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,19 @@ |
|||
#pragma once
|
|||
#include <stdint.h>
|
|||
|
|||
#include "basic_h/basic.hpp"
|
|||
|
|||
extern "C" { |
|||
// 微秒延迟定时器,注意该延时定时器需要按照以下文档进行配置
|
|||
// http://192.168.1.3:3000/zwikipedia/iflytop_wikipedia/src/branch/master/doc/stm32cubemx_us_timer.md
|
|||
|
|||
typedef struct { |
|||
zchip_tim_t* usdleaytim; |
|||
} zchip_clock_cfg_t; |
|||
|
|||
uint32_t zchip_clock_init(zchip_clock_cfg_t* cfg); |
|||
|
|||
uint32_t zchip_clock_get_ticket(void); |
|||
uint32_t zchip_clock_hasspassed(uint32_t ticket); |
|||
void zchip_clock_early_delayus(uint32_t us); |
|||
} |
@ -0,0 +1,3 @@ |
|||
#pragma once
|
|||
#include <list>
|
|||
#include <functional>
|
@ -0,0 +1,4 @@ |
|||
#include "critical_context.hpp"
|
|||
using namespace iflytop; |
|||
CriticalContext::CriticalContext() { chip_critical_enter(); } |
|||
CriticalContext::~CriticalContext() { chip_critical_exit(); } |
@ -0,0 +1,15 @@ |
|||
#pragma once
|
|||
#include "basic_h/basic.hpp"
|
|||
#include "chip_helper.hpp"
|
|||
|
|||
namespace iflytop { |
|||
using namespace std; |
|||
|
|||
class CriticalContext { |
|||
public: |
|||
CriticalContext(); |
|||
~CriticalContext(); |
|||
}; |
|||
#define ZCriticalContext CriticalContext
|
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,32 @@ |
|||
#include "logger.hpp"
|
|||
|
|||
|
|||
extern "C" { |
|||
|
|||
/*********************************************************************
|
|||
* @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; |
|||
} |
|||
|
|||
static zchip_uart_t* m_huart; |
|||
bool g_enable_log = true; |
|||
|
|||
void zchip_loggger_init(zchip_uart_t* huart) { m_huart = huart; } |
|||
void zchip_loggger_enable(bool enable) { g_enable_log = enable; } |
|||
} |
@ -0,0 +1,37 @@ |
|||
#pragma once
|
|||
#include <stdio.h>
|
|||
|
|||
#include "basic_h/basic.hpp"
|
|||
//
|
|||
#include "clock.hpp"
|
|||
|
|||
extern "C" { |
|||
extern bool g_enable_log; |
|||
#define ZLOG_RELEASE(TAG, fmt, ...) \
|
|||
if (g_enable_log) { \ |
|||
printf(TAG "" fmt "\n", ##__VA_ARGS__); \ |
|||
} |
|||
#define ZLOGI(TAG, fmt, ...) \
|
|||
if (g_enable_log) { \ |
|||
printf("%08lu INFO [%-8s] " fmt "\n", chip_get_ticket(), TAG, ##__VA_ARGS__); \ |
|||
} |
|||
#define ZLOGD(TAG, fmt, ...) \
|
|||
if (g_enable_log) { \ |
|||
printf("%08lu DEBU [%-8s] " fmt "\n", chip_get_ticket(), TAG, ##__VA_ARGS__); \ |
|||
} |
|||
#define ZLOGE(TAG, fmt, ...) \
|
|||
if (g_enable_log) { \ |
|||
printf("%08lu ERRO [%-8s] " fmt "\n", chip_get_ticket(), TAG, ##__VA_ARGS__); \ |
|||
} |
|||
|
|||
#define ZASSERT(cond) \
|
|||
if (!(cond)) { \ |
|||
while (1) { \ |
|||
printf("ASSERT: %s [%s:%d]\n", #cond, __FILE__, __LINE__); \ |
|||
zchip_clock_early_delayus(1000 * 1000); \ |
|||
} \ |
|||
} |
|||
|
|||
void zchip_loggger_init(zchip_uart_t *huart); |
|||
void zchip_loggger_enable(bool enable); |
|||
} |
@ -0,0 +1,16 @@ |
|||
#include "chip.hpp"
|
|||
|
|||
extern "C" { |
|||
void chip_init(chip_cfg_t *cfg) { |
|||
//
|
|||
zchip_clock_cfg_t zchip_clock_cfg; |
|||
zchip_clock_cfg.usdleaytim = cfg->us_dleay_tim; |
|||
zchip_clock_init(&zchip_clock_cfg); |
|||
//
|
|||
zchip_loggger_init(cfg->huart); |
|||
//
|
|||
iflytop::ChipTimIrqShceduler::Cfg ChipTimIrqShceduler_cfg; |
|||
ChipTimIrqShceduler_cfg.schedulertim = cfg->tim_irq_scheduler_tim; |
|||
iflytop::ChipTimIrqShceduler::instance().initialize(&ChipTimIrqShceduler_cfg); |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
#pragma once
|
|||
|
|||
#include "chip_tim_irq_shceduler.hpp"
|
|||
#include "irq_dispatcher.hpp"
|
|||
#include "zcan_irq_dispatcher.hpp"
|
|||
#include "zgpio.hpp"
|
|||
#include "ztim.hpp"
|
|||
#include "zuart.hpp"
|
|||
|
|||
extern "C" { |
|||
|
|||
typedef struct { |
|||
zchip_tim_t *us_dleay_tim; |
|||
zchip_tim_t *tim_irq_scheduler_tim; |
|||
zchip_uart_t *huart; |
|||
} chip_cfg_t; |
|||
|
|||
void chip_init(chip_cfg_t *cfg); |
|||
} |
@ -0,0 +1,64 @@ |
|||
#include "chip_tim_irq_shceduler.hpp"
|
|||
|
|||
using namespace iflytop; |
|||
using namespace std; |
|||
|
|||
ChipTimIrqShceduler::ChipTimIrqShceduler(/* args */) {} |
|||
ChipTimIrqShceduler::~ChipTimIrqShceduler() {} |
|||
|
|||
ChipTimIrqShceduler& ChipTimIrqShceduler::instance() { |
|||
static ChipTimIrqShceduler instance; |
|||
return instance; |
|||
} |
|||
void ChipTimIrqShceduler::initialize(Cfg* cfg) { |
|||
m_cfg = *cfg; |
|||
m_htim = m_cfg.schedulertim; |
|||
|
|||
simpleTimer_startByPeriod(1000); |
|||
} |
|||
void ChipTimIrqShceduler::regPeriodJob(jobcb_t jobcb, uint32_t period_ms) { |
|||
ChipTimIrqShceduler::Job* periodJob = new ChipTimIrqShceduler::Job(jobcb, period_ms); |
|||
ZASSERT(periodJob != NULL); |
|||
m_periodJobs.push_back(periodJob); |
|||
} |
|||
|
|||
/*******************************************************************************
|
|||
* simpleTimer * |
|||
*******************************************************************************/ |
|||
void ChipTimIrqShceduler::simpleTimer_startByPeriod(uint32_t periodus) { simpleTimer_startByFreq(1000000.0 / periodus); } |
|||
void ChipTimIrqShceduler::simpleTimer_startByFreq(float freq) { |
|||
ZASSERT(m_htim->Init.AutoReloadPreload == TIM_AUTORELOAD_PRELOAD_ENABLE) |
|||
|
|||
uint32_t prescaler = 0; |
|||
uint32_t autoreload = 0; |
|||
|
|||
ZASSERT(chip_calculate_prescaler_and_autoreload_by_expect_freq(chip_get_timer_clock_sorce_freq(m_htim), freq, &prescaler, &autoreload)); |
|||
|
|||
__HAL_TIM_SET_AUTORELOAD(m_htim, autoreload); |
|||
__HAL_TIM_SET_PRESCALER(m_htim, prescaler); |
|||
|
|||
HAL_TIM_Base_Start_IT(m_htim); |
|||
|
|||
ZIRQDispatcher::instance().regTimIrqListener([this](zchip_tim_t* tim) { |
|||
if (tim != m_htim) return; |
|||
onTimIrq(tim); |
|||
}); |
|||
} |
|||
void ChipTimIrqShceduler::simpleTimer_stop() { HAL_TIM_Base_Stop(m_htim); } |
|||
|
|||
void ChipTimIrqShceduler::onTimIrq(zchip_tim_t* tim) { |
|||
if (tim != m_cfg.schedulertim) { |
|||
return; |
|||
} |
|||
|
|||
ticket++; |
|||
for (auto iter = m_periodJobs.begin(); iter != m_periodJobs.end(); iter++) { |
|||
auto periodJob = *iter; |
|||
periodJob->count_ms++; |
|||
if (periodJob->count_ms != periodJob->period_ms) { |
|||
continue; |
|||
} |
|||
periodJob->count_ms = 0; |
|||
periodJob->jobcb(periodJob); |
|||
} |
|||
} |
@ -0,0 +1,58 @@ |
|||
|
|||
#pragma once
|
|||
#include <functional>
|
|||
#include <list>
|
|||
|
|||
#include "basic/base.hpp"
|
|||
#include "irq_dispatcher.hpp"
|
|||
|
|||
namespace iflytop { |
|||
using namespace std; |
|||
|
|||
class ChipTimIrqShceduler { |
|||
private: |
|||
ChipTimIrqShceduler(){}; |
|||
|
|||
public: |
|||
class Cfg { |
|||
public: |
|||
zchip_tim_t* schedulertim; |
|||
}; |
|||
class Job; |
|||
typedef function<void(Job*)> jobcb_t; |
|||
|
|||
class Job { |
|||
public: |
|||
Job(jobcb_t jobcb, uint32_t period_ms) { |
|||
this->jobcb = jobcb; |
|||
this->period_ms = period_ms; |
|||
} |
|||
jobcb_t jobcb; |
|||
uint32_t period_ms = 0; |
|||
uint32_t count_ms = 0; |
|||
}; |
|||
|
|||
private: |
|||
Cfg m_cfg; |
|||
zchip_tim_t* m_htim; |
|||
list<Job*> m_periodJobs; |
|||
uint64_t ticket; |
|||
|
|||
volatile bool m_timer_start; |
|||
|
|||
public: |
|||
static ChipTimIrqShceduler& instance(); |
|||
|
|||
void initialize(Cfg* cfg); |
|||
void regPeriodJob(jobcb_t job, uint32_t period_ms); |
|||
~ChipTimIrqShceduler(); |
|||
|
|||
private: |
|||
void onTimIrq(zchip_tim_t* tim); |
|||
|
|||
void simpleTimer_startByPeriod(uint32_t periodus); |
|||
void simpleTimer_startByFreq(float freq); |
|||
void simpleTimer_stop(); |
|||
}; |
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,18 @@ |
|||
#include "irq_dispatcher.hpp"
|
|||
|
|||
using namespace iflytop; |
|||
using namespace std; |
|||
|
|||
extern "C" { |
|||
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim) { ZIRQDispatcher::instance()._callOnTimIrq(htim); } |
|||
} |
|||
|
|||
ZIRQDispatcher &ZIRQDispatcher::instance() {} |
|||
|
|||
void ZIRQDispatcher::regTimIrqListener(ontimirq_t listener) { m_ontimirqs.push_back(listener); } |
|||
|
|||
void ZIRQDispatcher::_callOnTimIrq(zchip_tim_t *tim) { |
|||
for (auto &listener : m_ontimirqs) { |
|||
listener(tim); |
|||
} |
|||
} |
@ -0,0 +1,24 @@ |
|||
#pragma once
|
|||
#include <functional>
|
|||
#include <list>
|
|||
|
|||
#include "basic/base.hpp"
|
|||
|
|||
namespace iflytop { |
|||
using namespace std; |
|||
class ZIRQDispatcher { |
|||
public: |
|||
typedef function<void(zchip_tim_t *)> ontimirq_t; |
|||
|
|||
list<ontimirq_t> m_ontimirqs; |
|||
|
|||
public: |
|||
static ZIRQDispatcher &instance(); |
|||
|
|||
void regTimIrqListener(ontimirq_t listener); |
|||
|
|||
public: |
|||
void _callOnTimIrq(zchip_tim_t *tim); |
|||
}; |
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,91 @@ |
|||
#include "zcan_irq_dispatcher.hpp"
|
|||
#ifdef HAL_CAN_MODULE_ENABLED
|
|||
|
|||
extern "C" { |
|||
|
|||
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_TxMailbox0Complete(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_TxMailbox1Complete(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_TxMailbox2Complete(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_TxMailbox0Abort(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_TxMailbox1Abort(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_TxMailbox2Abort(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_RxFifo0MsgPending(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_RxFifo0Full(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_RxFifo1MsgPending(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_RxFifo1Full(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_Sleep(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_WakeUpFromRxMsg(hcan); |
|||
} |
|||
} |
|||
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { |
|||
for (int i = 0; i < iflytop::ZCanIRQDispatcher::instance().m_listenerNum; i++) { |
|||
iflytop::ZCanIRQDispatcher::instance().m_listener[i]->STM32_HAL_onCAN_Error(hcan); |
|||
} |
|||
} |
|||
} |
|||
|
|||
using namespace iflytop; |
|||
void ZCanIRQDispatcher::regListener(ZCanIRQListener *listener) { |
|||
if (listener == NULL) return; |
|||
for (int i = 0; i < STM32_HAL_LISTENER_NUM; i++) { |
|||
if (m_listener[i] == NULL) { |
|||
m_listener[i] = listener; |
|||
m_listenerNum++; |
|||
return; |
|||
} |
|||
} |
|||
ZASSERT(0); |
|||
} |
|||
|
|||
ZCanIRQDispatcher &ZCanIRQDispatcher::instance() { |
|||
static ZCanIRQDispatcher instance; |
|||
return instance; |
|||
} |
|||
|
|||
#endif
|
@ -0,0 +1,41 @@ |
|||
#pragma once
|
|||
#include <functional>
|
|||
|
|||
#include "basic/base.hpp"
|
|||
|
|||
#define STM32_HAL_LISTENER_NUM 3
|
|||
namespace iflytop { |
|||
class ZCanIRQListener { |
|||
public: |
|||
/*******************************************************************************
|
|||
* 中断管理 * |
|||
*******************************************************************************/ |
|||
#ifdef HAL_CAN_MODULE_ENABLED
|
|||
virtual void STM32_HAL_onCAN_TxMailbox0Complete(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_TxMailbox1Complete(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_TxMailbox2Complete(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_TxMailbox0Abort(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_TxMailbox1Abort(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_TxMailbox2Abort(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_RxFifo0Full(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_RxFifo1MsgPending(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_RxFifo1Full(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_Sleep(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_WakeUpFromRxMsg(CAN_HandleTypeDef *can){}; |
|||
virtual void STM32_HAL_onCAN_Error(CAN_HandleTypeDef *can){}; |
|||
#endif
|
|||
}; |
|||
|
|||
class ZCanIRQDispatcher { |
|||
ZCanIRQDispatcher(){}; |
|||
|
|||
public: |
|||
ZCanIRQListener *m_listener[STM32_HAL_LISTENER_NUM]; |
|||
int m_listenerNum; |
|||
void regListener(ZCanIRQListener *listener); |
|||
|
|||
static ZCanIRQDispatcher &instance(); |
|||
}; |
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,348 @@ |
|||
|
|||
#include "zgpio.hpp"
|
|||
#define TAG "GPIO"
|
|||
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; |
|||
} |
|||
} |
|||
|
|||
ZASSERT((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) { |
|||
m_mirror = mirror; |
|||
m_mode = mode; |
|||
m_irqtype = irqtype; |
|||
m_gpiotype = kType_Input; |
|||
|
|||
m_gpio = chip_get_gpio(pin); |
|||
m_pinoff = chip_get_pinoff(pin); |
|||
|
|||
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 = 0; |
|||
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 = 0; |
|||
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 = 0; |
|||
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 = 0; |
|||
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(), 0, 0); |
|||
HAL_NVIC_EnableIRQ(getEXTIIRQn()); |
|||
} |
|||
return; |
|||
} |
|||
void ZGPIO::initAsOutput(Pin_t pin, GPIOMode_t mode, bool mirror, bool initLevel) { |
|||
m_mirror = mirror; |
|||
m_mode = mode; |
|||
m_irqtype = kIRQ_noIrq; |
|||
m_gpiotype = kType_Output; |
|||
|
|||
m_gpio = chip_get_gpio(pin); |
|||
m_pinoff = chip_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); |
|||
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��PIO銝剜鱏蝥踵糓�梁鍂�����隞仿�閬�覔�埂PIO��朖�嗥𠶖��ế�剜糓�行糓餈嗘葵撘閗�鈭抒���葉�? |
|||
* |
|||
* �斗鱏�餉��?: |
|||
* ��ế�剜��劐葉�剜芋撘𤩺糓 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() { |
|||
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_mirror) state = !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 �嘥��𨰦PIO銝箔葉�剜芋撘? |
|||
* |
|||
* @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
|
@ -0,0 +1,74 @@ |
|||
|
|||
#pragma once
|
|||
#include <functional>
|
|||
|
|||
#include "basic/base.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<void(ZGPIO *GPIO_Pin, IrqTypeEvent_t irqevent)> onirq_t; |
|||
|
|||
private: |
|||
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; |
|||
|
|||
onirq_t m_onirq; |
|||
|
|||
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 regListener(onirq_t listener); |
|||
|
|||
bool isMirror(); |
|||
bool isItRisingEXITGPIO(); |
|||
bool isItFallingEXITGPIO(); |
|||
bool isItRisingAndItFallingEXITGPIO(); |
|||
|
|||
bool getState(); |
|||
uint32_t getStateUint32(); |
|||
bool setState(bool state); |
|||
void toggleState(); |
|||
|
|||
IRQn_Type getEXTIIRQn(); |
|||
GPIO_TypeDef *getPort() { return m_gpio; } |
|||
uint16_t getPin() { return m_pinoff; } |
|||
|
|||
bool tryTriggerIRQ(uint16_t GPIO_Pin); |
|||
|
|||
private: |
|||
bool enableClock(); |
|||
}; |
|||
} // namespace iflytop
|
@ -0,0 +1,48 @@ |
|||
#include "ztim.hpp"
|
|||
|
|||
#include "irq_dispatcher.hpp"
|
|||
using namespace iflytop; |
|||
|
|||
void ZTIM::initialize(zchip_tim_t *htim, mode_t mode) { |
|||
m_htim = htim; |
|||
m_mode = mode; |
|||
} |
|||
ZTIM::mode_t ZTIM::getMode() { return m_mode; } |
|||
|
|||
/******************************************************
|
|||
* kTimMode_timer * |
|||
******************************************************/ |
|||
|
|||
/**
|
|||
* @brief startTimer |
|||
* |
|||
* @param periodus 定时器周期 |
|||
* @param onirq 回调函数,如果为null,则使用上次注册的回调函数 |
|||
*/ |
|||
|
|||
void ZTIM::simpleTimer_startByPeriod(uint32_t periodus) { simpleTimer_startByFreq(1000000.0 / periodus); } |
|||
void ZTIM::simpleTimer_startByFreq(float freq) { |
|||
ZASSERT(m_htim->Init.AutoReloadPreload == TIM_AUTORELOAD_PRELOAD_ENABLE) |
|||
m_timer_start = true; |
|||
|
|||
uint32_t prescaler = 0; |
|||
uint32_t autoreload = 0; |
|||
|
|||
uint32_t timClkFreq = chip_get_timer_clock_sorce_freq(m_htim); |
|||
|
|||
ZASSERT(chip_calculate_prescaler_and_autoreload_by_expect_freq(timClkFreq, freq, &prescaler, &autoreload)); |
|||
|
|||
__HAL_TIM_SET_AUTORELOAD(m_htim, autoreload); |
|||
__HAL_TIM_SET_PRESCALER(m_htim, prescaler); |
|||
|
|||
HAL_TIM_Base_Start_IT(m_htim); |
|||
|
|||
ZIRQDispatcher::instance().regTimIrqListener([this](zchip_tim_t *tim) { |
|||
if (tim != m_htim) return; |
|||
if (m_timer_start && m_simpleTimer_cb) m_simpleTimer_cb(); |
|||
}); |
|||
} |
|||
void ZTIM::simpleTimer_stop() { |
|||
m_timer_start = false; |
|||
HAL_TIM_Base_Stop(m_htim); |
|||
} |
@ -0,0 +1,62 @@ |
|||
|
|||
#pragma once
|
|||
#include <functional>
|
|||
|
|||
#include "basic/base.hpp"
|
|||
|
|||
#ifdef HAL_TIM_MODULE_ENABLED
|
|||
|
|||
namespace iflytop { |
|||
using namespace iflytop; |
|||
class ZTIM { |
|||
public: |
|||
typedef enum { |
|||
ktm_null, |
|||
ktm_timer, |
|||
ktm_pwm, |
|||
} mode_t; |
|||
|
|||
typedef function<void()> ontimirq_t; |
|||
|
|||
private: |
|||
zchip_tim_t *m_htim; |
|||
mode_t m_mode; |
|||
|
|||
volatile bool m_timer_start; |
|||
|
|||
ontimirq_t m_simpleTimer_cb; |
|||
|
|||
public: |
|||
ZTIM() {} |
|||
|
|||
void initialize(zchip_tim_t *htim, mode_t mode); |
|||
mode_t getMode(); |
|||
|
|||
/******************************************************
|
|||
* kTimMode_timer * |
|||
******************************************************/ |
|||
|
|||
/**
|
|||
* @brief startTimer |
|||
* |
|||
* @param periodus 定时器周期 |
|||
* @param onirq 回调函数,如果为null,则使用上次注册的回调函数 |
|||
*/ |
|||
|
|||
void simpleTimer_regCb(ontimirq_t cb) { m_simpleTimer_cb = cb; } |
|||
void simpleTimer_startByPeriod(uint32_t periodus); |
|||
void simpleTimer_startByFreq(float freq); |
|||
void simpleTimer_stop(); |
|||
|
|||
/*******************************************************************************
|
|||
* PWM_MODE * |
|||
*******************************************************************************/ |
|||
void setPWMFreq(float freq); |
|||
void startPWM(uint32_t Channel, float duty); |
|||
void stopPWM(uint32_t Channel); |
|||
|
|||
}; |
|||
|
|||
} // namespace iflytop
|
|||
|
|||
#endif
|
@ -0,0 +1,220 @@ |
|||
#include "zuart.hpp"
|
|||
|
|||
#include <stdio.h>
|
|||
#include <string.h>
|
|||
|
|||
using namespace iflytop; |
|||
|
|||
static ZUART *s_uart_table[10]; |
|||
static int s_numUart; |
|||
|
|||
static void prv_reg_uart(ZUART *uart) { |
|||
if (s_numUart < 10) { |
|||
s_uart_table[s_numUart++] = uart; |
|||
} |
|||
} |
|||
|
|||
ZUART *prv_find_uart(UART_HandleTypeDef *huart) { |
|||
for (int i = 0; i < s_numUart; i++) { |
|||
if (s_uart_table[i]->getHuart() == huart) { |
|||
return s_uart_table[i]; |
|||
} |
|||
} |
|||
return NULL; |
|||
} |
|||
|
|||
extern "C" { |
|||
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { |
|||
ZUART *stm32uart = prv_find_uart(huart); |
|||
if (stm32uart != NULL) stm32uart->HAL_UART_TxCpltCallback(); |
|||
} |
|||
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) { |
|||
ZUART *stm32uart = prv_find_uart(huart); |
|||
if (stm32uart != NULL) stm32uart->HAL_UART_TxHalfCpltCallback(); |
|||
} |
|||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { |
|||
ZUART *stm32uart = prv_find_uart(huart); |
|||
if (stm32uart != NULL) stm32uart->HAL_UART_RxCpltCallback(); |
|||
} |
|||
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) { |
|||
ZUART *stm32uart = prv_find_uart(huart); |
|||
if (stm32uart != NULL) stm32uart->HAL_UART_RxHalfCpltCallback(); |
|||
} |
|||
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { |
|||
ZUART *stm32uart = prv_find_uart(huart); |
|||
if (stm32uart != NULL) stm32uart->HAL_UART_ErrorCallback(); |
|||
} |
|||
void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart) { |
|||
ZUART *stm32uart = prv_find_uart(huart); |
|||
if (stm32uart != NULL) stm32uart->HAL_UART_AbortCpltCallback(); |
|||
} |
|||
void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart) { |
|||
ZUART *stm32uart = prv_find_uart(huart); |
|||
if (stm32uart != NULL) stm32uart->HAL_UART_AbortTransmitCpltCallback(); |
|||
} |
|||
void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart) { |
|||
ZUART *stm32uart = prv_find_uart(huart); |
|||
if (stm32uart != NULL) stm32uart->HAL_UART_AbortReceiveCpltCallback(); |
|||
} |
|||
} |
|||
|
|||
IRQn_Type ZUART::getUartIRQType() { |
|||
#ifdef USART1
|
|||
if (m_huart->Instance == USART1) { |
|||
return USART1_IRQn; |
|||
} |
|||
#endif
|
|||
#ifdef USART2
|
|||
if (m_huart->Instance == USART2) { |
|||
return USART2_IRQn; |
|||
} |
|||
#endif
|
|||
#ifdef USART3
|
|||
if (m_huart->Instance == USART3) { |
|||
return USART3_IRQn; |
|||
} |
|||
#endif
|
|||
#ifdef UART4
|
|||
if (m_huart->Instance == UART4) { |
|||
return UART4_IRQn; |
|||
} |
|||
#endif
|
|||
#ifdef UART5
|
|||
if (m_huart->Instance == UART5) { |
|||
return UART5_IRQn; |
|||
} |
|||
#endif
|
|||
#ifdef USART6
|
|||
if (m_huart->Instance == USART6) { |
|||
return USART6_IRQn; |
|||
} |
|||
#endif
|
|||
ZASSERT(false); |
|||
return USART1_IRQn; |
|||
} |
|||
|
|||
void ZUART::initialize(cfg_t *cfg, callback_t cb) { |
|||
m_name = cfg->name; |
|||
m_huart = cfg->huart; |
|||
m_cb = cb; |
|||
m_rxovertime_ms = cfg->rxovertime_ms; |
|||
|
|||
m_rxBuffer = (uint8_t *)malloc(cfg->rxbuffersize); |
|||
memset(m_rxBuffer, 0, cfg->rxbuffersize); |
|||
ZASSERT(m_rxBuffer != NULL); |
|||
m_rxBufferLen = cfg->rxbuffersize; |
|||
|
|||
m_isRxing = false; |
|||
m_dataIsReady = false; |
|||
m_rxBufferPos = 0; |
|||
m_lastRxTime = 0; |
|||
onebyte = 0; |
|||
|
|||
ChipTimIrqShceduler::instance().regPeriodJob([this](ChipTimIrqShceduler::Job *job) { periodicJob(); }, 1); |
|||
prv_reg_uart(this); |
|||
} |
|||
void ZUART::initialize(cfg_t *cfg) { initialize(cfg, NULL); } |
|||
|
|||
bool ZUART::tx(uint8_t *data, size_t len) { |
|||
HAL_UART_Transmit(m_huart, data, len, 0xffff); |
|||
return true; |
|||
} |
|||
bool ZUART::tx(const char *data) { |
|||
HAL_UART_Transmit(m_huart, (uint8_t *)data, strlen(data), 0xffff); |
|||
return true; |
|||
} |
|||
|
|||
bool ZUART::startRxIt() { |
|||
ZASSERT(m_rxBuffer != NULL); |
|||
ZASSERT(NVIC_GetEnableIRQ(getUartIRQType()) != 0); |
|||
|
|||
if (m_isRxing) return true; |
|||
m_isRxing = true; |
|||
|
|||
HAL_UART_Receive_IT(m_huart, &onebyte, 1); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
bool ZUART::dataIsReady() { |
|||
// CriticalContext criticalContext;
|
|||
if (m_dataIsReady) { |
|||
return true; |
|||
} |
|||
if (!m_dataIsReady && m_rxBufferPos != 0) { |
|||
if (zchip_clock_hasspassed(m_lastRxTime) > (uint32_t)m_rxovertime_ms) { |
|||
m_dataIsReady = true; |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
void ZUART::clearRxData() { |
|||
// ZCriticalContext criticalContext;
|
|||
m_dataIsReady = false; |
|||
memset(m_rxBuffer, 0, m_rxBufferLen); |
|||
m_rxBufferPos = 0; |
|||
} |
|||
void ZUART::periodicJob() { |
|||
if (dataIsReady()) { |
|||
if (m_cb) { |
|||
m_cb(m_rxBuffer, m_rxBufferPos); |
|||
} |
|||
clearRxData(); |
|||
} |
|||
} |
|||
|
|||
void ZUART::forceCchedule() { periodicJob(); } |
|||
|
|||
/*******************************************************************************
|
|||
* 中断 * |
|||
*******************************************************************************/ |
|||
void ZUART::HAL_UART_TxCpltCallback() {} |
|||
void ZUART::HAL_UART_TxHalfCpltCallback() {} |
|||
void ZUART::HAL_UART_RxCpltCallback() { |
|||
if (m_dataIsReady) { |
|||
HAL_UART_Receive_IT(m_huart, &onebyte, 1); |
|||
return; |
|||
} |
|||
|
|||
m_rxBuffer[m_rxBufferPos] = onebyte; |
|||
m_rxBufferPos++; |
|||
m_lastRxTime = zchip_clock_get_ticket(); |
|||
|
|||
if (m_rxBufferPos >= m_rxBufferLen) { |
|||
m_dataIsReady = true; |
|||
} |
|||
HAL_UART_Receive_IT(m_huart, &onebyte, 1); |
|||
} |
|||
|
|||
void ZUART::HAL_UART_RxHalfCpltCallback() {} |
|||
void ZUART::HAL_UART_ErrorCallback() { |
|||
HAL_UART_AbortReceive_IT(m_huart); |
|||
HAL_UART_Receive_IT(m_huart, &onebyte, 1); |
|||
} |
|||
void ZUART::HAL_UART_AbortCpltCallback() {} |
|||
void ZUART::HAL_UART_AbortTransmitCpltCallback() {} |
|||
void ZUART::HAL_UART_AbortReceiveCpltCallback() {} |
|||
|
|||
namespace iflytop { |
|||
#if 0
|
|||
#ifdef USART1
|
|||
ZUART STM32_UART1("uart1", USART1); |
|||
#endif
|
|||
#ifdef USART2
|
|||
ZUART STM32_UART2("uart2", USART2); |
|||
#endif
|
|||
#ifdef USART3
|
|||
ZUART STM32_UART3("uart3", USART3); |
|||
#endif
|
|||
#ifdef UART4
|
|||
ZUART STM32_UART4("uart4", UART4); |
|||
#endif
|
|||
#ifdef UART5
|
|||
ZUART STM32_UART5("uart5", UART5); |
|||
#endif
|
|||
#ifdef USART6
|
|||
ZUART STM32_UART6("uart6", USART6); |
|||
#endif
|
|||
#endif
|
|||
} // namespace iflytop
|
@ -0,0 +1,69 @@ |
|||
#pragma once
|
|||
#include <functional>
|
|||
|
|||
#include "basic/base.hpp"
|
|||
#include "chip_tim_irq_shceduler.hpp"
|
|||
namespace iflytop { |
|||
using namespace std; |
|||
class ZUART { |
|||
public: |
|||
typedef struct { |
|||
const char *name; |
|||
UART_HandleTypeDef *huart; |
|||
int32_t rxbuffersize = 128; |
|||
int32_t rxovertime_ms = 3; |
|||
} cfg_t; |
|||
typedef function<void(uint8_t *data, size_t len)> callback_t; |
|||
|
|||
private: |
|||
const char *m_name; |
|||
UART_HandleTypeDef *m_huart; |
|||
|
|||
uint8_t *m_rxBuffer; |
|||
volatile int32_t m_rxBufferPos; |
|||
int32_t m_rxBufferLen; |
|||
|
|||
volatile uint32_t m_lastRxTime; |
|||
|
|||
int32_t m_rxovertime_ms = 3; |
|||
|
|||
uint8_t onebyte; |
|||
|
|||
bool m_isRxing = false; |
|||
volatile bool m_dataIsReady = false; |
|||
|
|||
callback_t m_cb; |
|||
|
|||
public: |
|||
ZUART() {} |
|||
void initialize(cfg_t *cfg, callback_t cb); |
|||
void initialize(cfg_t *cfg); |
|||
|
|||
void setrxcb(callback_t cb) { m_cb = cb; } |
|||
|
|||
bool tx(const char *data); |
|||
bool tx(uint8_t *data, size_t len); |
|||
bool startRxIt(); |
|||
|
|||
void clearRxData(); |
|||
void forceCchedule(); |
|||
|
|||
public: |
|||
void HAL_UART_TxCpltCallback(); |
|||
void HAL_UART_TxHalfCpltCallback(); |
|||
void HAL_UART_RxCpltCallback(); |
|||
void HAL_UART_RxHalfCpltCallback(); |
|||
void HAL_UART_ErrorCallback(); |
|||
void HAL_UART_AbortCpltCallback(); |
|||
void HAL_UART_AbortTransmitCpltCallback(); |
|||
void HAL_UART_AbortReceiveCpltCallback(); |
|||
|
|||
UART_HandleTypeDef *getHuart() { return m_huart; } |
|||
|
|||
private: |
|||
IRQn_Type getUartIRQType(); |
|||
bool dataIsReady(); |
|||
void periodicJob(); |
|||
}; |
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,13 @@ |
|||
``` |
|||
DEP: |
|||
|
|||
dealy |
|||
------------------------------------------------------------------------ |
|||
logger |
|||
------------------------------------------------------------------------ |
|||
mutex |
|||
------------------------------------------------------------------------ |
|||
os |
|||
------------------------------------------------------------------------ |
|||
|
|||
``` |
@ -0,0 +1,19 @@ |
|||
#include "delay.hpp"
|
|||
|
|||
#ifdef IFLYTOP_ENABLE_OS
|
|||
#include "cmsis_os.h"
|
|||
#endif
|
|||
|
|||
extern "C" { |
|||
void zos_early_delayus(int var_nus) { zchip_clock_early_delayus(var_nus); } |
|||
void zos_early_delay(int ms) { |
|||
for (int i = 0; i < ms; i++) { |
|||
zos_early_delayus(1000); |
|||
} |
|||
} |
|||
#ifdef IFLYTOP_ENABLE_OS
|
|||
void zos_delay(int ms) { osDelay(ms); } |
|||
#else
|
|||
void zos_delay(int ms) { z_early_delay(ms); } |
|||
#endif
|
|||
} |
@ -0,0 +1,7 @@ |
|||
#pragma once
|
|||
#include "osbasic_h.hpp"
|
|||
extern "C" { |
|||
void zos_early_delay(int ms); |
|||
void zos_early_delayus(int us); |
|||
void zos_delay(int ms); |
|||
} |
@ -0,0 +1,53 @@ |
|||
#include "mutex.hpp"
|
|||
#define TAG "zmutex"
|
|||
|
|||
using namespace iflytop; |
|||
|
|||
/*******************************************************************************
|
|||
* zmutex * |
|||
*******************************************************************************/ |
|||
zmutex::zmutex() {} |
|||
zmutex::~zmutex() { |
|||
#ifdef IFLYTOP_ENABLE_OS
|
|||
vSemaphoreDelete(recursiveMutex); |
|||
#endif
|
|||
} |
|||
|
|||
void zmutex::init() { |
|||
#ifdef IFLYTOP_ENABLE_OS
|
|||
recursiveMutex = xSemaphoreCreateRecursiveMutex(); |
|||
#endif
|
|||
} |
|||
|
|||
bool zmutex::isInit() { |
|||
#ifdef IFLYTOP_ENABLE_OS
|
|||
return recursiveMutex != NULL; |
|||
#else
|
|||
return true; |
|||
#endif
|
|||
} |
|||
|
|||
void zmutex::lock() { |
|||
#ifdef IFLYTOP_ENABLE_OS
|
|||
ZASSERT(recursiveMutex != NULL); |
|||
xSemaphoreTakeRecursive(recursiveMutex, portMAX_DELAY); |
|||
#else
|
|||
chip_critical_enter(); |
|||
#endif
|
|||
} |
|||
void zmutex::unlock() { |
|||
#ifdef IFLYTOP_ENABLE_OS
|
|||
xSemaphoreGiveRecursive(recursiveMutex); |
|||
#else
|
|||
chip_critical_exit(); |
|||
#endif
|
|||
} |
|||
|
|||
/*******************************************************************************
|
|||
* zlock_guard * |
|||
*******************************************************************************/ |
|||
zlock_guard::zlock_guard(zmutex* mutex) { |
|||
m_mutex = mutex; |
|||
m_mutex->lock(); |
|||
} |
|||
zlock_guard::~zlock_guard() { m_mutex->unlock(); } |
@ -0,0 +1,36 @@ |
|||
#pragma once
|
|||
#include "osbasic_h.hpp"
|
|||
namespace iflytop { |
|||
using namespace std; |
|||
|
|||
class zmutex { |
|||
public: |
|||
#ifdef IFLYTOP_ENABLE_OS
|
|||
SemaphoreHandle_t recursiveMutex; |
|||
#endif
|
|||
|
|||
public: |
|||
zmutex(); |
|||
~zmutex(); |
|||
|
|||
void init(); |
|||
bool isInit(); |
|||
|
|||
void lock(); |
|||
void unlock(); |
|||
}; |
|||
|
|||
class zlock_guard { |
|||
zmutex* m_mutex; |
|||
zlock_guard(zmutex* mutex); |
|||
~zlock_guard(); |
|||
}; |
|||
|
|||
class CriticalContext { |
|||
public: |
|||
CriticalContext(); |
|||
~CriticalContext(); |
|||
}; |
|||
#define ZCriticalContext CriticalContext
|
|||
|
|||
} // namespace iflytop
|
@ -0,0 +1,6 @@ |
|||
#pragma once
|
|||
#include "../chip/chip.hpp"
|
|||
//
|
|||
#ifdef IFLYTOP_ENABLE_OS
|
|||
#include "cmsis_os.h"
|
|||
#endif
|
@ -0,0 +1,11 @@ |
|||
#include "ticket.hpp"
|
|||
|
|||
extern "C" { |
|||
uint32_t zos_get_tick(void) { |
|||
#ifdef IFLYTOP_ENABLE_OS
|
|||
return osKernelSysTick(); |
|||
#else
|
|||
return HAL_GetTick(); |
|||
#endif
|
|||
} |
|||
} |
@ -0,0 +1,7 @@ |
|||
#pragma once
|
|||
#include "osbasic_h.hpp"
|
|||
|
|||
extern "C" { |
|||
uint32_t zos_get_tick(void); |
|||
uint32_t zos_haspassedms(uint32_t ticket); |
|||
} |
@ -0,0 +1,4 @@ |
|||
#include "zos.hpp"
|
|||
extern "C" { |
|||
void zos_init(zos_cfg_t* cfg) {} |
|||
} |
@ -0,0 +1,19 @@ |
|||
#pragma once
|
|||
//
|
|||
#include "osbasic_h.hpp"
|
|||
//
|
|||
#include "oscppdep.hpp"
|
|||
//
|
|||
#include "delay.hpp"
|
|||
//
|
|||
#include "mutex.hpp"
|
|||
//
|
|||
#include "ticket.hpp"
|
|||
|
|||
extern "C" { |
|||
typedef struct { |
|||
uint32_t __reserved0; |
|||
} zos_cfg_t; |
|||
|
|||
void zos_init(zos_cfg_t* cfg); |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue