add SoftwareSerial and fix some bug

This commit is contained in:
ZYQ-FEIYUE
2022-09-11 23:00:26 +08:00
parent b0c4415631
commit 6274558153
8 changed files with 613 additions and 18 deletions

View File

@@ -297,13 +297,19 @@ extern "C" {
int Print::printf (const char *__restrict __format, ...)
{
char printf_buff[PRINT_PRINTF_BUFFER_LENGTH];
// char printf_buff[PRINT_PRINTF_BUFFER_LENGTH];
// va_list args;
// va_start(args, __format);
// int ret_status = vsnprintf(printf_buff, sizeof(printf_buff), __format, args);
// va_end(args);
// print(printf_buff);
// return ret_status;
FILE *__restrict __stream;
int ret_status = 0;
va_list args;
va_start(args, __format);
int ret_status = vsnprintf(printf_buff, sizeof(printf_buff), __format, args);
va_start(args,__format);
ret_status = vfprintf(__stream, __format, args);
va_end(args);
print(printf_buff);
return ret_status;
return ret_status;
}

View File

@@ -0,0 +1,424 @@
/*
* SoftwareSerial.cpp (formerly NewSoftSerial.cpp)
*
* Multi-instance software serial library for Arduino/Wiring
* -- Interrupt-driven receive and other improvements by ladyada
* (http://ladyada.net)
* -- Tuning, circular buffer, derivation from class Print/Stream,
* multi-instance support, porting to 8MHz processors,
* various optimizations, PROGMEM delay tables, inverse logic and
* direct port writing by Mikal Hart (http://www.arduiniana.org)
* -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
* -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
* -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
* -- STM32 support by Armin van der Togt
* -- AT32F4 support by WeactStudio
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* The latest version of this library can always be found at
* http://arduiniana.org.
*/
//
// Includes
//
#include "SoftwareSerial.h"
#include "libcore/timer.h"
#define OVERSAMPLE 3 // in RX, Timer will generate interruption OVERSAMPLE time during a bit. Thus OVERSAMPLE ticks in a bit. (interrupt not synchronized with edge).
// defined in bit-periods
#define HALFDUPLEX_SWITCH_DELAY 5
// It's best to define TIMER_SERIAL in variant.h. If not defined, we choose one here
// The order is based on (lack of) features and compare channels, we choose the simplest available
// because we only need an update interrupt
#if !defined(TIMER_SERIAL)
#if defined (TMR18_BASE)
#define TIMER_SERIAL TIM18
#elif defined (TMR7_BASE)
#define TIMER_SERIAL TIM7
#elif defined (TMR6_BASE)
#define TIMER_SERIAL TIM6
#elif defined (TMR22_BASE)
#define TIMER_SERIAL TIM22
#elif defined (TMR21_BASE)
#define TIMER_SERIAL TIM21
#elif defined (TMR17_BASE)
#define TIMER_SERIAL TIM17
#elif defined (TMR16_BASE)
#define TIMER_SERIAL TIM16
#elif defined (TMR15_BASE)
#define TIMER_SERIAL TIM15
#elif defined (TMR14_BASE)
#define TIMER_SERIAL TIM14
#elif defined (TMR13_BASE)
#define TIMER_SERIAL TIM13
#elif defined (TMR11_BASE)
#define TIMER_SERIAL TIM11
#elif defined (TMR10_BASE)
#define TIMER_SERIAL TIM10
#elif defined (TMR12_BASE)
#define TIMER_SERIAL TIM12
#elif defined (TMR19_BASE)
#define TIMER_SERIAL TIM19
#elif defined (TMR9_BASE)
#define TIMER_SERIAL TIM9
#elif defined (TMR5_BASE)
#define TIMER_SERIAL TIM5
#elif defined (TMR4_BASE)
#define TIMER_SERIAL TIM4
#elif defined (TMR3_BASE)
#define TIMER_SERIAL TIM3
#elif defined (TMR2_BASE)
#define TIMER_SERIAL TIM2
#elif defined (TMR20_BASE)
#define TIMER_SERIAL TIM20
#elif defined (TMR8_BASE)
#define TIMER_SERIAL TIM8
#elif defined (TMR1_BASE)
#define TIMER_SERIAL TIM1
#else
#error No suitable timer found for SoftwareSerial, define TIMER_SERIAL in variant.h
#endif
#endif
//
// Static
//
SoftwareSerial *SoftwareSerial::active_listener = nullptr;
SoftwareSerial *volatile SoftwareSerial::active_out = nullptr;
SoftwareSerial *volatile SoftwareSerial::active_in = nullptr;
int32_t SoftwareSerial::tx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
int32_t volatile SoftwareSerial::rx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
uint32_t SoftwareSerial::tx_buffer = 0;
int32_t SoftwareSerial::tx_bit_cnt = 0;
uint32_t SoftwareSerial::rx_buffer = 0;
int32_t SoftwareSerial::rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
uint32_t SoftwareSerial::cur_speed = 0;
//
// Private methods
//
void SoftwareSerial::setSpeed(uint32_t speed)
{
return;
if (speed != cur_speed) {
// Timer_Pause(TIMER_SERIAL);
if (speed != 0) {
// Disable the timer
uint32_t clock_rate, cmp_value;
// Get timer clock
clock_rate = Timer_GetClockMax(TIMER_SERIAL);
int pre = 1;
// Calculate prescale an compare value
do {
cmp_value = clock_rate / (speed * OVERSAMPLE);
if (cmp_value >= UINT16_MAX) {
clock_rate = clock_rate / 2;
pre *= 2;
}
} while (cmp_value >= UINT16_MAX);
Timer_SetPrescaler(TIMER_SERIAL, pre);
Timer_SetReload(TIMER_SERIAL, cmp_value);
Timer_SetCounter(TIMER_SERIAL, 0);
// Timer_Resume(TIMER_SERIAL);
} else {
}
cur_speed = speed;
}
}
// This function sets the current object as the "listening"
// one and returns true if it replaces another
bool SoftwareSerial::listen()
{
if (active_listener != this) {
// wait for any transmit to complete as we may change speed
while (active_out);
if (active_listener != nullptr) {
active_listener->stopListening();
}
rx_tick_cnt = 1; // 1 : next interrupt will decrease rx_tick_cnt to 0 which means RX pin level will be considered.
rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
setSpeed(_speed);
active_listener = this;
if (!_half_duplex) {
active_in = this;
} else if (!active_out) {
setRXTX(true);
}
return true;
}
return false;
}
// Stop listening. Returns true if we were actually listening.
bool SoftwareSerial::stopListening()
{
if (active_listener == this) {
// wait for any output to complete
while (active_out);
if (_half_duplex) {
setRXTX(false);
}
active_listener = nullptr;
active_in = nullptr;
// turn off ints
setSpeed(0);
return true;
}
return false;
}
inline void SoftwareSerial::setTX()
{
if (_inverse_logic) {
GPIO_LOW(_transmitPinPort, _transmitPinNumber);
} else {
GPIO_HIGH(_transmitPinPort, _transmitPinNumber);
}
pinMode(_transmitPin, OUTPUT);
}
inline void SoftwareSerial::setRX()
{
pinMode(_receivePin, _inverse_logic ? INPUT_PULLDOWN : INPUT_PULLUP); // pullup for normal logic!
}
inline void SoftwareSerial::setRXTX(bool input)
{
if (_half_duplex) {
if (input) {
if (active_in != this) {
setRX();
rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
rx_tick_cnt = 2; // 2 : next interrupt will be discarded. 2 interrupts required to consider RX pin level
active_in = this;
}
} else {
if (active_in == this) {
setTX();
active_in = nullptr;
}
}
}
}
inline void SoftwareSerial::send()
{
if (--tx_tick_cnt <= 0) { // if tx_tick_cnt > 0 interrupt is discarded. Only when tx_tick_cnt reach 0 we set TX pin.
if (tx_bit_cnt++ < 10) { // tx_bit_cnt < 10 transmission is not fiisehed (10 = 1 start +8 bits + 1 stop)
// send data (including start and stop bits)
if (tx_buffer & 1) {
GPIO_HIGH(_transmitPinPort, _transmitPinNumber);
} else {
GPIO_LOW(_transmitPinPort, _transmitPinNumber);
}
tx_buffer >>= 1;
tx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE tick to send next bit
} else { // Transmission finished
tx_tick_cnt = 1;
if (_output_pending) {
active_out = nullptr;
// When in half-duplex mode, wait for HALFDUPLEX_SWITCH_DELAY bit-periods after the byte has
// been transmitted before allowing the switch to RX mode
} else if (tx_bit_cnt > 10 + OVERSAMPLE * HALFDUPLEX_SWITCH_DELAY) {
if (_half_duplex && active_listener == this) {
setRXTX(true);
}
active_out = nullptr;
}
}
}
}
//
// The receive routine called by the interrupt handler
//
inline void SoftwareSerial::recv()
{
if (--rx_tick_cnt <= 0) { // if rx_tick_cnt > 0 interrupt is discarded. Only when rx_tick_cnt reach 0 RX pin is considered
bool inbit = GPIO_READ(_receivePinPort, _receivePinNumber) ^ _inverse_logic;
if (rx_bit_cnt == -1) { // rx_bit_cnt = -1 : waiting for start bit
if (!inbit) {
// got start bit
rx_bit_cnt = 0; // rx_bit_cnt == 0 : start bit received
rx_tick_cnt = OVERSAMPLE + 1; // Wait 1 bit (OVERSAMPLE ticks) + 1 tick in order to sample RX pin in the middle of the edge (and not too close to the edge)
rx_buffer = 0;
} else {
rx_tick_cnt = 1; // Waiting for start bit, but we don't get right level. Wait for next Interrupt to ckech RX pin level
}
} else if (rx_bit_cnt >= 8) { // rx_bit_cnt >= 8 : waiting for stop bit
if (inbit) {
// stop bit read complete add to buffer
uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
if (next != _receive_buffer_head) {
// save new data in buffer: tail points to where byte goes
_receive_buffer[_receive_buffer_tail] = rx_buffer; // save new byte
_receive_buffer_tail = next;
} else { // rx_bit_cnt = x with x = [0..7] correspond to new bit x received
_buffer_overflow = true;
}
}
// Full trame received. Restart waiting for start bit at next interrupt
rx_tick_cnt = 1;
rx_bit_cnt = -1;
} else {
// data bits
rx_buffer >>= 1;
if (inbit) {
rx_buffer |= 0x80;
}
rx_bit_cnt++; // Preprare for next bit
rx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks before sampling next bit
}
}
}
//
// Interrupt handling
//
/* static */
inline void SoftwareSerial::handleInterrupt()
{
if (active_in) {
active_in->recv();
}
if (active_out) {
active_out->send();
}
}
//
// Constructor
//
SoftwareSerial::SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic /* = false */) :
_receivePin(receivePin),
_transmitPin(transmitPin),
_receivePinPort(digitalPinToPort(receivePin)),
_receivePinNumber(digitalPinToBitMask(receivePin)),
_transmitPinPort(digitalPinToPort(transmitPin)),
_transmitPinNumber(digitalPinToBitMask(transmitPin)),
_speed(0),
_buffer_overflow(false),
_inverse_logic(inverse_logic),
_half_duplex(receivePin == transmitPin),
_output_pending(0),
_receive_buffer_tail(0),
_receive_buffer_head(0)
{
}
//
// Destructor
//
SoftwareSerial::~SoftwareSerial()
{
end();
}
//
// Public methods
//
void SoftwareSerial::begin(long speed)
{
#ifdef FORCE_BAUD_RATE
speed = FORCE_BAUD_RATE;
#endif
_speed = speed;
Timer_SetInterrupt(TIMER_SERIAL, 1000, handleInterrupt);
if (!_half_duplex) {
setTX();
setRX();
listen();
} else {
setTX();
}
}
void SoftwareSerial::end()
{
stopListening();
}
// Read data from buffer
int SoftwareSerial::read()
{
// Empty buffer?
if (_receive_buffer_head == _receive_buffer_tail) {
return -1;
}
// Read from "head"
uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
_receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
return d;
}
int SoftwareSerial::available()
{
return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
}
size_t SoftwareSerial::write(uint8_t b)
{
// wait for previous transmit to complete
_output_pending = 1;
while (active_out)
;
// add start and stop bits.
tx_buffer = b << 1 | 0x200;
if (_inverse_logic) {
tx_buffer = ~tx_buffer;
}
tx_bit_cnt = 0;
tx_tick_cnt = OVERSAMPLE;
setSpeed(_speed);
if (_half_duplex) {
setRXTX(false);
}
_output_pending = 0;
// make us active
active_out = this;
return 1;
}
void SoftwareSerial::flush()
{
noInterrupts();
_receive_buffer_head = _receive_buffer_tail = 0;
interrupts();
}
int SoftwareSerial::peek()
{
// Empty buffer?
if (_receive_buffer_head == _receive_buffer_tail) {
return -1;
}
// Read from "head"
return _receive_buffer[_receive_buffer_head];
}
void SoftwareSerial::setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority)
{
}

View File

@@ -0,0 +1,125 @@
/*
* SoftwareSerial.h (formerly NewSoftSerial.h)
*
* Multi-instance software serial library for Arduino/Wiring
* -- Interrupt-driven receive and other improvements by ladyada
* (http://ladyada.net)
* -- Tuning, circular buffer, derivation from class Print/Stream,
* multi-instance support, porting to 8MHz processors,
* various optimizations, PROGMEM delay tables, inverse logic and
* direct port writing by Mikal Hart (http://www.arduiniana.org)
* -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
* -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
* -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* The latest version of this library can always be found at
* http://arduiniana.org.
*/
#ifndef SOFTWARESERIAL_H
#define SOFTWARESERIAL_H
#include <Arduino.h>
/******************************************************************************
* Definitions
******************************************************************************/
#define _SS_MAX_RX_BUFF 64 // RX buffer size
class SoftwareSerial : public Stream {
private:
// per object data
uint16_t _receivePin;
uint16_t _transmitPin;
GPIO_TypeDef *_receivePinPort;
uint32_t _receivePinNumber;
GPIO_TypeDef *_transmitPinPort;
uint32_t _transmitPinNumber;
uint32_t _speed;
uint16_t _buffer_overflow: 1;
uint16_t _inverse_logic: 1;
uint16_t _half_duplex: 1;
uint16_t _output_pending: 1;
unsigned char _receive_buffer[_SS_MAX_RX_BUFF];
volatile uint8_t _receive_buffer_tail;
volatile uint8_t _receive_buffer_head;
uint32_t delta_start = 0;
// static data
static bool initialised;
static SoftwareSerial *active_listener;
static SoftwareSerial *volatile active_out;
static SoftwareSerial *volatile active_in;
static int32_t tx_tick_cnt;
static volatile int32_t rx_tick_cnt;
static uint32_t tx_buffer;
static int32_t tx_bit_cnt;
static uint32_t rx_buffer;
static int32_t rx_bit_cnt;
static uint32_t cur_speed;
// private methods
void send();
void recv();
void setTX();
void setRX();
void setSpeed(uint32_t speed);
void setRXTX(bool input);
static void handleInterrupt();
public:
// public methods
SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic = false);
virtual ~SoftwareSerial();
void begin(long speed);
bool listen();
void end();
bool isListening()
{
return active_listener == this;
}
bool stopListening();
bool overflow()
{
bool ret = _buffer_overflow;
if (ret) {
_buffer_overflow = false;
}
return ret;
}
int peek();
virtual size_t write(uint8_t byte);
virtual int read();
virtual int available();
virtual void flush();
operator bool()
{
return true;
}
static void setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority);
using Print::write;
};
#endif // SOFTWARESERIAL_H

View File

@@ -46,20 +46,20 @@ const PinInfo_TypeDef PIN_MAP[PIN_MAX] =
{GPIOA, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PA12 */
{GPIOA, NULL, NULL, GPIO_Pin_13, 0, ADC_CHANNEL_X}, /* PA13 */
{GPIOA, NULL, NULL, GPIO_Pin_14, 0, ADC_CHANNEL_X}, /* PA14 */
{GPIOA, TIM2, NULL, GPIO_Pin_15, 1, ADC_CHANNEL_X}, /* PA15 */
{GPIOA, NULL, NULL, GPIO_Pin_15, 1, ADC_CHANNEL_X}, /* PA15 */
{GPIOB, TIM3, ADC1, GPIO_Pin_0, 3, ADC_CHANNEL_8}, /* PB0 */
{GPIOB, TIM3, ADC1, GPIO_Pin_1, 4, ADC_CHANNEL_9}, /* PB1 */
{GPIOB, NULL, NULL, GPIO_Pin_2, 0, ADC_CHANNEL_X}, /* PB2 */
{GPIOB, TIM2, NULL, GPIO_Pin_3, 2, ADC_CHANNEL_X}, /* PB3 */
{GPIOB, NULL, NULL, GPIO_Pin_3, 2, ADC_CHANNEL_X}, /* PB3 */
{GPIOB, TIM3, NULL, GPIO_Pin_4, 1, ADC_CHANNEL_X}, /* PB4 */
{GPIOB, TIM3, NULL, GPIO_Pin_5, 2, ADC_CHANNEL_X}, /* PB5 */
{GPIOB, TIM4, NULL, GPIO_Pin_6, 1, ADC_CHANNEL_X}, /* PB6 */
{GPIOB, TIM4, NULL, GPIO_Pin_7, 2, ADC_CHANNEL_X}, /* PB7 */
{GPIOB, TIM4, NULL, GPIO_Pin_8, 3, ADC_CHANNEL_X}, /* PB8 */
{GPIOB, TIM4, NULL, GPIO_Pin_9, 4, ADC_CHANNEL_X}, /* PB9 */
{GPIOB, TIM2, NULL, GPIO_Pin_10, 3, ADC_CHANNEL_X}, /* PB10 */
{GPIOB, TIM2, NULL, GPIO_Pin_11, 4, ADC_CHANNEL_X}, /* PB11 */
{GPIOB, NULL, NULL, GPIO_Pin_10, 3, ADC_CHANNEL_X}, /* PB10 */
{GPIOB, NULL, NULL, GPIO_Pin_11, 4, ADC_CHANNEL_X}, /* PB11 */
{GPIOB, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PB12 */
{GPIOB, NULL, NULL, GPIO_Pin_13, 0, ADC_CHANNEL_X}, /* PB13 */
#ifdef TMR12
@@ -75,10 +75,10 @@ const PinInfo_TypeDef PIN_MAP[PIN_MAX] =
{GPIOC, NULL, ADC1, GPIO_Pin_3, 0, ADC_CHANNEL_13},/* PC3 */
{GPIOC, NULL, ADC1, GPIO_Pin_4, 0, ADC_CHANNEL_14},/* PC4 */
{GPIOC, NULL, ADC1, GPIO_Pin_5, 0, ADC_CHANNEL_15},/* PC5 */
{GPIOC, TIM3, NULL, GPIO_Pin_6, 1, ADC_CHANNEL_X}, /* PC6 */
{GPIOC, TIM3, NULL, GPIO_Pin_7, 2, ADC_CHANNEL_X}, /* PC7 */
{GPIOC, TIM3, NULL, GPIO_Pin_8, 3, ADC_CHANNEL_X}, /* PC8 */
{GPIOC, TIM3, NULL, GPIO_Pin_9, 4, ADC_CHANNEL_X}, /* PC9 */
{GPIOC, NULL, NULL, GPIO_Pin_6, 1, ADC_CHANNEL_X}, /* PC6 */
{GPIOC, NULL, NULL, GPIO_Pin_7, 2, ADC_CHANNEL_X}, /* PC7 */
{GPIOC, NULL, NULL, GPIO_Pin_8, 3, ADC_CHANNEL_X}, /* PC8 */
{GPIOC, NULL, NULL, GPIO_Pin_9, 4, ADC_CHANNEL_X}, /* PC9 */
{GPIOC, NULL, NULL, GPIO_Pin_10, 0, ADC_CHANNEL_X}, /* PC10 */
{GPIOC, NULL, NULL, GPIO_Pin_11, 0, ADC_CHANNEL_X}, /* PC11 */
{GPIOC, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PC12 */

View File

@@ -403,6 +403,7 @@ match:
tmr_flag_clear(TIMx, TMR_OVF_FLAG);
tmr_interrupt_enable(TIMx, TMR_OVF_INT, TRUE);
tmr_counter_enable(TIMx, TRUE);
}
/**
@@ -484,7 +485,10 @@ void Timer_SetReload(tmr_type* TIMx, uint16_t Reload)
{
TIMx->pr = Reload;
}
void Timer_SetCounter(tmr_type* TIMx, uint32_t Counter)
{
TIMx->cval = Counter;
}
/**
* @brief 应用定时器更改
* @param TIMx: 定时器地址
@@ -495,6 +499,40 @@ void Timer_GenerateUpdate(tmr_type* TIMx)
TIMx->swevt_bit.ovfswtr = TRUE;
}
/**
* @brief stop timer
* @param None
* @retval None
*/
void Timer_Pause(tmr_type* TIMx)
{
// Disable all IT
tmr_interrupt_enable(TIMx, TMR_OVF_INT, FALSE);
tmr_interrupt_enable(TIMx, TMR_C1_INT, FALSE);
tmr_interrupt_enable(TIMx, TMR_C2_INT, FALSE);
tmr_interrupt_enable(TIMx, TMR_C3_INT, FALSE);
tmr_interrupt_enable(TIMx, TMR_C4_INT, FALSE);
// Stop timer
tmr_counter_enable(TIMx, FALSE);
}
/**
* @brief resume timer
* @param None
* @retval None
*/
void Timer_Resume(tmr_type* TIMx)
{
tmr_flag_clear(TIMx, TMR_OVF_FLAG);
tmr_interrupt_enable(TIMx, TMR_OVF_INT, TRUE);
tmr_counter_enable(TIMx, TRUE);
tmr_interrupt_enable(TIMx, TMR_C1_INT, TRUE);
tmr_interrupt_enable(TIMx, TMR_C2_INT, TRUE);
tmr_interrupt_enable(TIMx, TMR_C3_INT, TRUE);
tmr_interrupt_enable(TIMx, TMR_C4_INT, TRUE);
}
#define TMRx_IRQHANDLER(n) \
do{\
if (tmr_flag_get(TMR##n, TMR_OVF_FLAG) != RESET)\

View File

@@ -45,12 +45,14 @@ void Timer_SetInterruptBase(
void Timer_SetCompare(tmr_type* TIMx, uint8_t TimerChannel, uint32_t Compare);
void Timer_SetPrescaler(tmr_type* TIMx, uint16_t Prescaler);
void Timer_SetReload(tmr_type* TIMx, uint16_t Reload);
void Timer_SetCounter(tmr_type* TIMx, uint32_t Counter);
void Timer_ClockCmd(tmr_type* TIMx, bool Enable);
uint32_t Timer_GetClockMax(tmr_type* TIMx);
uint32_t Timer_GetClockOut(tmr_type* TIMx);
uint16_t Timer_GetCompare(tmr_type* TIMx, uint8_t TimerChannel);
void Timer_GenerateUpdate(tmr_type* TIMx);
void Timer_Pause(tmr_type* TIMx);
void Timer_Resume(tmr_type* TIMx);
#ifdef __cplusplus
}
#endif

View File

@@ -12,7 +12,7 @@
{
"name": "AT32F403ACGU7 Core Board",
"architecture": "at32f403a",
"version": "0.0.5",
"version": "0.0.6",
"category": "Contributed",
"url": "https://github.com/WeActStudio/ArduinoCore-AT32F4/archive/refs/heads/main.zip",
"archiveFileName": "ArduinoCore-AT32F4-main.zip",

View File

@@ -1,6 +1,6 @@
##==============================================##
name=WeActStudio AT32F403A Boards
version=0.0.5
version=0.0.6
##==============================================##
####AT32 compile variables