zhaohe 2 years ago
parent
commit
bc0cb51bab
  1. 7
      README.md
  2. 11
      chip/basic/base.hpp
  3. 8
      chip/basic/basic_h/basic.hpp
  4. 45
      chip/basic/basic_h/marco.h
  5. 117
      chip/basic/basic_h/pin.hpp
  6. 120
      chip/basic/basic_h/stm32_header.h
  7. 178
      chip/basic/chip_helper.cpp
  8. 17
      chip/basic/chip_helper.hpp
  9. 41
      chip/basic/clock.cpp
  10. 19
      chip/basic/clock.hpp
  11. 3
      chip/basic/cppdep.hpp
  12. 4
      chip/basic/critical_context.cpp
  13. 15
      chip/basic/critical_context.hpp
  14. 32
      chip/basic/logger.cpp
  15. 37
      chip/basic/logger.hpp
  16. 16
      chip/chip.cpp
  17. 19
      chip/chip.hpp
  18. 64
      chip/chip_tim_irq_shceduler.cpp
  19. 58
      chip/chip_tim_irq_shceduler.hpp
  20. 18
      chip/irq_dispatcher.cpp
  21. 24
      chip/irq_dispatcher.hpp
  22. 91
      chip/zcan_irq_dispatcher.cpp
  23. 41
      chip/zcan_irq_dispatcher.hpp
  24. 348
      chip/zgpio.cpp
  25. 74
      chip/zgpio.hpp
  26. 48
      chip/ztim.cpp
  27. 62
      chip/ztim.hpp
  28. 220
      chip/zuart.cpp
  29. 69
      chip/zuart.hpp
  30. 13
      os/README.md
  31. 19
      os/delay.cpp
  32. 7
      os/delay.hpp
  33. 53
      os/mutex.cpp
  34. 36
      os/mutex.hpp
  35. 6
      os/osbasic_h.hpp
  36. 11
      os/ticket.cpp
  37. 7
      os/ticket.hpp
  38. 4
      os/zos.cpp
  39. 19
      os/zos.hpp

7
README.md

@ -0,0 +1,7 @@
```
chip: stm32hal库对接接口
os : 操作系统相关方法,上层代码依赖这一层
hal : 硬件抽象层,依赖chip层和os层
components:
CHIP:
```

11
chip/basic/base.hpp

@ -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"

8
chip/basic/basic_h/basic.hpp

@ -0,0 +1,8 @@
#pragma once
#include <stdint.h>
//
#include "project_configs.h"
//
#include "marco.h"
#include "pin.hpp"
#include "stm32_header.h"

45
chip/basic/basic_h/marco.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

117
chip/basic/basic_h/pin.hpp

@ -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;

120
chip/basic/basic_h/stm32_header.h

@ -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;
}

178
chip/basic/chip_helper.cpp

@ -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;
}

17
chip/basic/chip_helper.hpp

@ -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);
}

41
chip/basic/clock.cpp

@ -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);
}
}
}

19
chip/basic/clock.hpp

@ -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);
}

3
chip/basic/cppdep.hpp

@ -0,0 +1,3 @@
#pragma once
#include <list>
#include <functional>

4
chip/basic/critical_context.cpp

@ -0,0 +1,4 @@
#include "critical_context.hpp"
using namespace iflytop;
CriticalContext::CriticalContext() { chip_critical_enter(); }
CriticalContext::~CriticalContext() { chip_critical_exit(); }

15
chip/basic/critical_context.hpp

@ -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

32
chip/basic/logger.cpp

@ -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; }
}

37
chip/basic/logger.hpp

@ -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);
}

16
chip/chip.cpp

@ -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);
}
}

19
chip/chip.hpp

@ -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);
}

64
chip/chip_tim_irq_shceduler.cpp

@ -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);
}
}

58
chip/chip_tim_irq_shceduler.hpp

@ -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

18
chip/irq_dispatcher.cpp

@ -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);
}
}

24
chip/irq_dispatcher.hpp

@ -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

91
chip/zcan_irq_dispatcher.cpp

@ -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

41
chip/zcan_irq_dispatcher.hpp

@ -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

348
chip/zgpio.cpp

@ -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
*
* STM32PIO銝剜鱏蝥踵糓仿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

74
chip/zgpio.hpp

@ -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

48
chip/ztim.cpp

@ -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);
}

62
chip/ztim.hpp

@ -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

220
chip/zuart.cpp

@ -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

69
chip/zuart.hpp

@ -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

13
os/README.md

@ -0,0 +1,13 @@
```
DEP:
dealy
------------------------------------------------------------------------
logger
------------------------------------------------------------------------
mutex
------------------------------------------------------------------------
os
------------------------------------------------------------------------
```

19
os/delay.cpp

@ -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
}

7
os/delay.hpp

@ -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);
}

53
os/mutex.cpp

@ -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(); }

36
os/mutex.hpp

@ -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

6
os/osbasic_h.hpp

@ -0,0 +1,6 @@
#pragma once
#include "../chip/chip.hpp"
//
#ifdef IFLYTOP_ENABLE_OS
#include "cmsis_os.h"
#endif

11
os/ticket.cpp

@ -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
}
}

7
os/ticket.hpp

@ -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);
}

4
os/zos.cpp

@ -0,0 +1,4 @@
#include "zos.hpp"
extern "C" {
void zos_init(zos_cfg_t* cfg) {}
}

19
os/zos.hpp

@ -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);
}
Loading…
Cancel
Save