support linux system

This commit is contained in:
ZYQ-FEIYUE
2022-08-09 22:38:26 +08:00
parent ef453b4ba6
commit d2816d24b5
130 changed files with 22 additions and 24 deletions

118
cores/arduino/Arduino.h Normal file
View File

@@ -0,0 +1,118 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __ARDUINO_H
#define __ARDUINO_H
#include <stdlib.h>
#include <stdbool.h>
#include "libcore/mcu_core.h"
#include "binary.h"
#include "avr/pgmspace.h"
#ifdef __cplusplus
extern "C" {
#endif
#define KEILDUINO_VERSION 100
#define PI 3.1415926535897932384626433832795f
#define HALF_PI 1.5707963267948966192313216916398f
#define TWO_PI 6.283185307179586476925286766559f
#define DEG_TO_RAD 0.017453292519943295769236907684886f
#define RAD_TO_DEG 57.295779513082320876798154814105f
#define EULER 2.718281828459045235360287471352f
#define SERIAL 0x0
#define DISPLAY 0x1
#define LSBFIRST 0x0
#define MSBFIRST 0x1
#define LOW 0x0
#define HIGH 0x1
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define ABS(x) (((x)>0)?(x):-(x)) //abs(x) is define in stdlib.h
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
//#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))
#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
#ifndef _BV
# define _BV(bit) (1 << (bit))
#endif
#define clockCyclesPerMicrosecond() (F_CPU / 1000000L)
#define clockCyclesToMicroseconds(a) (((a) * 1000L) / (F_CPU / 1000L))
#define microsecondsToClockCycles(a) ((a) * (F_CPU / 1000000L))
#define delay(ms) delay_ms(ms)
#define delayMicroseconds(us) delay_us(us)
#define interrupts() sei()
#define noInterrupts() cli()
#define NOT_A_PIN 0xFF
#define NOT_A_PORT 0xFF
#define NOT_AN_INTERRUPT -1
#define boolean bool
typedef unsigned char byte;
void pinMode(uint8_t pin, PinMode_TypeDef mode);
void digitalWrite(uint8_t pin, uint8_t value);
uint8_t digitalRead(uint8_t pin);
void analogWrite(uint8_t pin, uint16_t value);
uint16_t analogRead(uint8_t pin);
uint16_t analogRead_DMA(uint8_t pin);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value);
uint32_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint32_t bitOrder);
uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout);
long map(long x, long in_min, long in_max, long out_min, long out_max);
float fmap(float x, float in_min, float in_max, float out_min, float out_max);
void yield(void);
#ifdef __cplusplus
}// extern "C"
#endif
#ifdef __cplusplus
# include "WCharacter.h"
# include "WString.h"
# include "WMath.h"
# include <Tone.h>
# include <HardwareSerial.h>
#endif
#endif

View File

@@ -0,0 +1,292 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "HardwareSerial.h"
#define SERIAL_GET_WORDLENGTH(SERIAL_x) ((uint16_t)(SERIAL_x&0xF000))
#define SERIAL_GET_PARITY(SERIAL_x) ((uint16_t)(SERIAL_x&0x0F00))
#define SERIAL_GET_STOPBITS(SERIAL_x) ((uint16_t)((SERIAL_x&0x00F0) << 8))
typedef struct
{
usart_data_bit_num_type data_bit;
usart_parity_selection_type parity_selection;
usart_stop_bit_num_type stop_bit;
} SERIAL_ConfigGrp_t;
static const SERIAL_ConfigGrp_t SERIAL_ConfigGrp[] =
{
{USART_DATA_8BITS, USART_PARITY_NONE, USART_STOP_1_BIT}, // SERIAL_8N1
{USART_DATA_8BITS, USART_PARITY_NONE, USART_STOP_2_BIT}, // SERIAL_8N2
{USART_DATA_8BITS, USART_PARITY_EVEN, USART_STOP_1_BIT}, // SERIAL_8E1
{USART_DATA_8BITS, USART_PARITY_EVEN, USART_STOP_2_BIT}, // SERIAL_8E2
{USART_DATA_8BITS, USART_PARITY_ODD, USART_STOP_1_BIT}, // SERIAL_8O1
{USART_DATA_8BITS, USART_PARITY_ODD, USART_STOP_2_BIT}, // SERIAL_8O2
{USART_DATA_8BITS, USART_PARITY_NONE, USART_STOP_0_5_BIT}, // SERIAL_8N0_5
{USART_DATA_8BITS, USART_PARITY_NONE, USART_STOP_1_5_BIT}, // SERIAL_8N1_5
{USART_DATA_8BITS, USART_PARITY_EVEN, USART_STOP_0_5_BIT}, // SERIAL_8E0_5
{USART_DATA_8BITS, USART_PARITY_EVEN, USART_STOP_1_5_BIT}, // SERIAL_8E1_5
{USART_DATA_8BITS, USART_PARITY_ODD, USART_STOP_0_5_BIT}, // SERIAL_8O0_5
{USART_DATA_8BITS, USART_PARITY_ODD, USART_STOP_1_5_BIT}, // SERIAL_8O1_5
{USART_DATA_9BITS, USART_PARITY_NONE, USART_STOP_1_BIT}, // SERIAL_9N1
{USART_DATA_9BITS, USART_PARITY_NONE, USART_STOP_2_BIT}, // SERIAL_9N2
{USART_DATA_9BITS, USART_PARITY_EVEN, USART_STOP_1_BIT}, // SERIAL_9E1
{USART_DATA_9BITS, USART_PARITY_EVEN, USART_STOP_2_BIT}, // SERIAL_9E2
{USART_DATA_9BITS, USART_PARITY_ODD, USART_STOP_1_BIT}, // SERIAL_9O1
{USART_DATA_9BITS, USART_PARITY_ODD, USART_STOP_2_BIT}, // SERIAL_9O2
{USART_DATA_9BITS, USART_PARITY_NONE, USART_STOP_0_5_BIT}, // SERIAL_9N0_5
{USART_DATA_9BITS, USART_PARITY_NONE, USART_STOP_1_5_BIT}, // SERIAL_9N1_5
{USART_DATA_9BITS, USART_PARITY_EVEN, USART_STOP_0_5_BIT}, // SERIAL_9E0_5
{USART_DATA_9BITS, USART_PARITY_EVEN, USART_STOP_1_5_BIT}, // SERIAL_9E1_5
{USART_DATA_9BITS, USART_PARITY_ODD, USART_STOP_0_5_BIT}, // SERIAL_9O0_5
{USART_DATA_9BITS, USART_PARITY_ODD, USART_STOP_1_5_BIT}, // SERIAL_9O1_5
};
/**
* @brief 串口对象构造函数
* @param 串口外设地址
* @retval 无
*/
HardwareSerial::HardwareSerial(usart_type* usart)
: _USARTx(usart)
, _callbackFunction(NULL)
, _rxBufferHead(0)
, _rxBufferTail(0)
{
memset(_rxBuffer, 0, sizeof(_rxBuffer));
}
/**
* @brief 串口中断入口
* @param 无
* @retval 无
*/
void HardwareSerial::IRQHandler()
{
if(usart_flag_get(_USARTx, USART_RDBF_FLAG) != RESET)
{
uint8_t c = usart_data_receive(_USARTx);
uint16_t i = (uint16_t)(_rxBufferHead + 1) % SERIAL_RX_BUFFER_SIZE;
if (i != _rxBufferTail)
{
_rxBuffer[_rxBufferHead] = c;
_rxBufferHead = i;
}
if(_callbackFunction)
{
_callbackFunction(this);
}
usart_flag_clear(_USARTx, USART_RDBF_FLAG);
}
}
/**
* @brief 串口初始化
* @param BaudRate: 波特率
* @param Config: 配置参数
* @param PreemptionPriority: 抢占优先级
* @param SubPriority: 从优先级
* @retval 无
*/
void HardwareSerial::begin(
uint32_t baudRate,
SERIAL_Config_t config,
uint8_t preemptionPriority,
uint8_t subPriority
)
{
gpio_type *GPIOx;
gpio_init_type gpio_init_struct;
uint16_t Tx_Pin, Rx_Pin;
IRQn_Type USARTx_IRQn;
if(_USARTx == USART1)
{
GPIOx = GPIOA;
Tx_Pin = GPIO_Pin_9;
Rx_Pin = GPIO_Pin_10;
USARTx_IRQn = USART1_IRQn;
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
}
else if(_USARTx == USART2)
{
GPIOx = GPIOA;
Tx_Pin = GPIO_Pin_2;
Rx_Pin = GPIO_Pin_3;
USARTx_IRQn = USART2_IRQn;
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, TRUE);
}
else if(_USARTx == USART3)
{
GPIOx = GPIOB;
Tx_Pin = GPIO_Pin_10;
Rx_Pin = GPIO_Pin_11;
USARTx_IRQn = USART3_IRQn;
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_USART3_PERIPH_CLOCK, TRUE);
}
else
{
return;
}
gpio_default_para_init(&gpio_init_struct);
gpio_init_struct.gpio_pins = Tx_Pin | Rx_Pin;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init(GPIOx, &gpio_init_struct);
usart_init(_USARTx, baudRate, SERIAL_ConfigGrp[config].data_bit, SERIAL_ConfigGrp[config].stop_bit);
usart_parity_selection_config(_USARTx, SERIAL_ConfigGrp[config].parity_selection);
usart_transmitter_enable(_USARTx, TRUE);
usart_receiver_enable(_USARTx, TRUE);
nvic_irq_enable(USARTx_IRQn, preemptionPriority, subPriority);
usart_interrupt_enable(_USARTx, USART_RDBF_INT, TRUE);
usart_enable(_USARTx, TRUE);
}
/**
* @brief 关闭串口
* @param 无
* @retval 无
*/
void HardwareSerial::end(void)
{
usart_interrupt_enable(_USARTx, USART_RDBF_INT, FALSE);
usart_enable(_USARTx, FALSE);
}
/**
* @brief 串口中断回调
* @param Function: 回调函数
* @retval 无
*/
void HardwareSerial::attachInterrupt(CallbackFunction_t func)
{
_callbackFunction = func;
}
/**
* @brief 获取可从串行端口读取的字节数
* @param 无
* @retval 可读取的字节数
*/
int HardwareSerial::available(void)
{
return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rxBufferHead - _rxBufferTail)) % SERIAL_RX_BUFFER_SIZE;
}
/**
* @brief 读取传入的串行数据(字符)
* @param 无
* @retval 可用的传入串行数据的第一个字节 (如果没有可用的数据, 则为-1)
*/
int HardwareSerial::read(void)
{
// if the head isn't ahead of the tail, we don't have any characters
if (_rxBufferHead == _rxBufferTail)
{
return -1;
}
else
{
uint8_t c = _rxBuffer[_rxBufferTail];
_rxBufferTail = (uint16_t)(_rxBufferTail + 1) % SERIAL_RX_BUFFER_SIZE;
return c;
}
}
/**
* @brief 返回传入串行数据的下一个字节(字符), 而不将其从内部串行缓冲区中删除
* @param 无
* @retval 可用的传入串行数据的第一个字节 (如果没有可用的数据, 则为-1)
*/
int HardwareSerial::peek(void)
{
if (_rxBufferHead == _rxBufferTail)
{
return -1;
}
else
{
return _rxBuffer[_rxBufferTail];
}
}
/**
* @brief 清空串口缓存
* @param 无
* @retval 无
*/
void HardwareSerial::flush(void)
{
_rxBufferHead = _rxBufferTail;
}
/**
* @brief 串口写入一个字节
* @param 写入的字节
* @retval 字节
*/
size_t HardwareSerial::write(uint8_t n)
{
while(!usart_flag_get(_USARTx, USART_TDBE_FLAG)) {};
usart_data_transmit(_USARTx, n);
return 1;
}
#if SERIAL_1_ENABLE
HardwareSerial Serial(SERIAL_1_USART);
extern "C" SERIAL_1_IRQ_HANDLER_DEF()
{
Serial.IRQHandler();
}
#endif
#if SERIAL_2_ENABLE
HardwareSerial Serial2(SERIAL_2_USART);
extern "C" SERIAL_2_IRQ_HANDLER_DEF()
{
Serial2.IRQHandler();
}
#endif
#if SERIAL_3_ENABLE
HardwareSerial Serial3(SERIAL_3_USART);
extern "C" SERIAL_3_IRQ_HANDLER_DEF()
{
Serial3.IRQHandler();
}
#endif

View File

@@ -0,0 +1,142 @@
/*
* MIT License
* Copyright (c) 2019 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __HardwareSerial_h
#define __HardwareSerial_h
#include "Arduino.h"
#include "Print.h"
#include "Stream.h"
typedef enum
{
SERIAL_7N1,
SERIAL_7N2,
SERIAL_7E1,
SERIAL_7E2,
SERIAL_7O1,
SERIAL_7O2,
SERIAL_7N0_5,
SERIAL_7N1_5,
SERIAL_7E0_5,
SERIAL_7E1_5,
SERIAL_7O0_5,
SERIAL_7O1_5,
SERIAL_8N1,
SERIAL_8N2,
SERIAL_8E1,
SERIAL_8E2,
SERIAL_8O1,
SERIAL_8O2,
SERIAL_8N0_5,
SERIAL_8N1_5,
SERIAL_8E0_5,
SERIAL_8E1_5,
SERIAL_8O0_5,
SERIAL_8O1_5,
SERIAL_9N1,
SERIAL_9N2,
SERIAL_9E1,
SERIAL_9E2,
SERIAL_9O1,
SERIAL_9O2,
SERIAL_9N0_5,
SERIAL_9N1_5,
SERIAL_9E0_5,
SERIAL_9E1_5,
SERIAL_9O0_5,
SERIAL_9O1_5,
} SERIAL_Config_t;
class HardwareSerial : public Stream
{
typedef void(*CallbackFunction_t)(HardwareSerial* serial);
public:
HardwareSerial(usart_type* usart);
usart_type* getUSART()
{
return _USARTx;
}
void begin(
uint32_t baudRate,
SERIAL_Config_t config = SERIAL_CONFIG_DEFAULT,
uint8_t preemptionPriority = SERIAL_PREEMPTIONPRIORITY_DEFAULT,
uint8_t subPriority = SERIAL_SUBPRIORITY_DEFAULT
);
void end(void);
void attachInterrupt(CallbackFunction_t func);
virtual int available(void);
virtual int peek(void);
virtual int read(void);
virtual void flush(void);
virtual size_t write(uint8_t n);
inline size_t write(unsigned long n)
{
return write((uint8_t)n);
}
inline size_t write(long n)
{
return write((uint8_t)n);
}
inline size_t write(unsigned int n)
{
return write((uint8_t)n);
}
inline size_t write(int n)
{
return write((uint8_t)n);
}
using Print::write; // pull in write(str) and write(buf, size) from Print
operator bool()
{
return true;
}
void IRQHandler();
private:
usart_type* _USARTx;
CallbackFunction_t _callbackFunction;
volatile uint16_t _rxBufferHead;
volatile uint16_t _rxBufferTail;
uint8_t _rxBuffer[SERIAL_RX_BUFFER_SIZE];
};
#if SERIAL_1_ENABLE
extern HardwareSerial Serial;
#endif
#if SERIAL_2_ENABLE
extern HardwareSerial Serial2;
#endif
#if SERIAL_3_ENABLE
extern HardwareSerial Serial3;
#endif
#endif

288
cores/arduino/Print.cpp Normal file
View File

@@ -0,0 +1,288 @@
/*
Print.cpp - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
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
Modified 23 November 2006 by David A. Mellis
Modified 03 August 2015 by Chuck Todd
*/
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include "Print.h"
#include "libcore/config/mcu_config.h"
// Public Methods //////////////////////////////////////////////////////////////
/* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
while (size--)
{
if (write(*buffer++)) n++;
else break;
}
return n;
}
size_t Print::print(const __FlashStringHelper *ifsh)
{
PGM_P p = reinterpret_cast<PGM_P>(ifsh);
size_t n = 0;
while (1)
{
unsigned char c = pgm_read_byte(p++);
if (c == 0) break;
if (write(c)) n++;
else break;
}
return n;
}
size_t Print::print(const String &s)
{
return write(s.c_str(), s.length());
}
size_t Print::print(const char str[])
{
return write(str);
}
size_t Print::print(char c)
{
return write(c);
}
size_t Print::print(unsigned char b, int base)
{
return print((unsigned long) b, base);
}
size_t Print::print(int n, int base)
{
return print((long) n, base);
}
size_t Print::print(unsigned int n, int base)
{
return print((unsigned long) n, base);
}
size_t Print::print(long n, int base)
{
if (base == 0)
{
return write(n);
}
else if (base == 10)
{
if (n < 0)
{
int t = print('-');
n = -n;
return printNumber(n, 10) + t;
}
return printNumber(n, 10);
}
else
{
return printNumber(n, base);
}
}
size_t Print::print(unsigned long n, int base)
{
if (base == 0) return write(n);
else return printNumber(n, base);
}
size_t Print::print(double n, int digits)
{
return printFloat(n, digits);
}
size_t Print::println(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}
size_t Print::print(const Printable& x)
{
return x.printTo(*this);
}
size_t Print::println(void)
{
return write("\r\n");
}
size_t Print::println(const String &s)
{
size_t n = print(s);
n += println();
return n;
}
size_t Print::println(const char c[])
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(char c)
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(unsigned char b, int base)
{
size_t n = print(b, base);
n += println();
return n;
}
size_t Print::println(int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(double num, int digits)
{
size_t n = print(num, digits);
n += println();
return n;
}
size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
}
// Private Methods /////////////////////////////////////////////////////////////
size_t Print::printNumber(unsigned long n, uint8_t base)
{
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1];
*str = '\0';
// prevent crash if called with base == 1
if (base < 2) base = 10;
do
{
char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10;
}
while(n);
return write(str);
}
size_t Print::printFloat(double number, uint8_t digits)
{
size_t n = 0;
if (isnan(number)) return print("nan");
if (isinf(number)) return print("inf");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number < -4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers
if (number < 0.0)
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i = 0; i < digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
{
n += print('.');
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)(remainder);
n += print(toPrint);
remainder -= toPrint;
}
return n;
}
int Print::printf (const char *__restrict __format, ...)
{
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;
}

109
cores/arduino/Print.h Normal file
View File

@@ -0,0 +1,109 @@
/*
Print.h - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
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
*/
#ifndef Print_h
#define Print_h
#include <inttypes.h>
#include <stdio.h> // for size_t
#include "WString.h"
#include "Printable.h"
#define DEC 10
#define HEX 16
#define OCT 8
#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar
#undef BIN
#endif
#define BIN 2
class Print
{
private:
int write_error;
size_t printNumber(unsigned long, uint8_t);
size_t printFloat(double, uint8_t);
protected:
void setWriteError(int err = 1)
{
write_error = err;
}
public:
Print() : write_error(0) {}
int getWriteError()
{
return write_error;
}
void clearWriteError()
{
setWriteError(0);
}
virtual size_t write(uint8_t) = 0;
size_t write(const char *str)
{
if (str == NULL) return 0;
return write((const uint8_t *)str, strlen(str));
}
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size)
{
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block"
// should be overridden by subclasses with buffering
virtual int availableForWrite()
{
return 0;
}
size_t print(const __FlashStringHelper *);
size_t print(const String &);
size_t print(const char[]);
size_t print(char);
size_t print(unsigned char, int = DEC);
size_t print(int, int = DEC);
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);
size_t println(const __FlashStringHelper *);
size_t println(const String &s);
size_t println(const char[]);
size_t println(char);
size_t println(unsigned char, int = DEC);
size_t println(int, int = DEC);
size_t println(unsigned int, int = DEC);
size_t println(long, int = DEC);
size_t println(unsigned long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
int printf(const char * format, ...);
virtual void flush() { /* Empty implementation for backward compatibility */ }
};
#endif

40
cores/arduino/Printable.h Normal file
View File

@@ -0,0 +1,40 @@
/*
Printable.h - Interface class that allows printing of complex types
Copyright (c) 2011 Adrian McEwen. All right reserved.
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
*/
#ifndef Printable_h
#define Printable_h
#include <stdlib.h>
class Print;
/** The Printable class provides a way for new classes to allow themselves to be printed.
By deriving from Printable and implementing the printTo method, it will then be possible
for users to print out instances of this class by passing them into the usual
Print::print and Print::println methods.
*/
class Printable
{
public:
virtual size_t printTo(Print& p) const = 0;
};
#endif

430
cores/arduino/SPI.cpp Normal file
View File

@@ -0,0 +1,430 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "SPI.h"
#define SPI1_CLOCK (F_CPU)
#define SPI2_CLOCK (F_CPU)
#define SPI3_CLOCK (F_CPU)
SPIClass::SPIClass(spi_type* spix)
: SPIx(spix)
, SPI_Clock(0)
{
memset(&spi_init_struct, 0, sizeof(spi_init_struct));
}
void SPIClass::SPI_Settings(
spi_master_slave_mode_type master_slave_mode,
spi_frame_bit_num_type frame_bit_num,
uint16_t SPI_MODEx,
spi_cs_mode_type cs_mode,
spi_mclk_freq_div_type mclk_freq_div,
spi_first_bit_type first_bit)
{
spi_clock_polarity_type clock_polarity;
spi_clock_phase_type clock_phase;
spi_enable(SPIx, FALSE);
switch(SPI_MODEx)
{
case 0:
clock_polarity = SPI_CLOCK_POLARITY_LOW;
clock_phase = SPI_CLOCK_PHASE_1EDGE;
break;
case 1:
clock_polarity = SPI_CLOCK_POLARITY_LOW;
clock_phase = SPI_CLOCK_PHASE_2EDGE;
break;
case 2:
clock_polarity = SPI_CLOCK_POLARITY_HIGH;
clock_phase = SPI_CLOCK_PHASE_1EDGE;
break;
case 3:
clock_polarity = SPI_CLOCK_POLARITY_HIGH;
clock_phase = SPI_CLOCK_PHASE_2EDGE;
break;
default:
return;
}
spi_default_para_init(&spi_init_struct);
spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX;
spi_init_struct.master_slave_mode = master_slave_mode;
spi_init_struct.frame_bit_num = frame_bit_num;
spi_init_struct.clock_polarity = clock_polarity;
spi_init_struct.clock_phase = clock_phase;
spi_init_struct.cs_mode_selection = cs_mode;
spi_init_struct.mclk_freq_division = mclk_freq_div;
spi_init_struct.first_bit_transmission = first_bit;
spi_init(SPIx, &spi_init_struct);
spi_enable(SPIx, TRUE);
}
void SPIClass::begin(void)
{
spi_i2s_reset(SPIx);
if(SPIx == SPI1)
{
SPI_Clock = SPI1_CLOCK;
crm_periph_clock_enable(CRM_SPI1_PERIPH_CLOCK, TRUE);
pinMode(PA5, OUTPUT_AF_PP);
pinMode(PA6, OUTPUT_AF_PP);
pinMode(PA7, OUTPUT_AF_PP);
}
else if(SPIx == SPI2)
{
SPI_Clock = SPI2_CLOCK;
crm_periph_clock_enable(CRM_SPI2_PERIPH_CLOCK, TRUE);
pinMode(PB13, OUTPUT_AF_PP);
pinMode(PB14, OUTPUT_AF_PP);
pinMode(PB15, OUTPUT_AF_PP);
}
else if(SPIx == SPI3)
{
SPI_Clock = SPI3_CLOCK;
crm_periph_clock_enable(CRM_SPI3_PERIPH_CLOCK, TRUE);
pinMode(PB3, OUTPUT_AF_PP);
pinMode(PB4, OUTPUT_AF_PP);
pinMode(PB5, OUTPUT_AF_PP);
}
else
{
return;
}
SPI_Settings(
SPI_MODE_MASTER,
SPI_FRAME_8BIT,
SPI_MODE0,
SPI_CS_SOFTWARE_MODE,
SPI_MCLK_DIV_8,
SPI_FIRST_BIT_MSB
);
}
void SPIClass::begin(uint32_t clock, uint16_t dataOrder, uint16_t dataMode)
{
begin();
setClock(clock);
setBitOrder(dataOrder);
setDataMode(dataMode);
spi_enable(SPIx, TRUE);
}
void SPIClass::begin(SPISettings settings)
{
begin();
setClock(settings.clock);
setBitOrder(settings.bitOrder);
setDataMode(settings.dataMode);
spi_enable(SPIx, TRUE);
}
void SPIClass::beginSlave(void)
{
begin();
SPI_Settings(
SPI_MODE_SLAVE,
SPI_FRAME_8BIT,
SPI_MODE0,
SPI_CS_SOFTWARE_MODE,
SPI_MCLK_DIV_16,
SPI_FIRST_BIT_MSB
);
spi_enable(SPIx, TRUE);
}
void SPIClass::end(void)
{
spi_enable(SPIx, FALSE);
}
void SPIClass::setClock(uint32_t clock)
{
if(clock == 0)
{
return;
}
static const spi_mclk_freq_div_type mclk_freq_div_map[] =
{
SPI_MCLK_DIV_2,
SPI_MCLK_DIV_2,
SPI_MCLK_DIV_4,
SPI_MCLK_DIV_8,
SPI_MCLK_DIV_16,
SPI_MCLK_DIV_32,
SPI_MCLK_DIV_64,
SPI_MCLK_DIV_128,
SPI_MCLK_DIV_256,
SPI_MCLK_DIV_512,
SPI_MCLK_DIV_1024,
};
const uint8_t mapSize = sizeof(mclk_freq_div_map) / sizeof(mclk_freq_div_map[0]);
uint32_t clockDiv = SPI_Clock / clock;
uint8_t mapIndex = 0;
while(clockDiv > 1)
{
clockDiv = clockDiv >> 1;
mapIndex++;
}
if(mapIndex >= mapSize)
{
mapIndex = mapSize - 1;
}
spi_init_struct.mclk_freq_division = mclk_freq_div_map[mapIndex];
spi_init(SPIx, &spi_init_struct);
spi_enable(SPIx, TRUE);
}
void SPIClass::setClockDivider(uint32_t Div)
{
if(Div == 0)
{
Div = 1;
}
#if SPI_CLASS_AVR_COMPATIBILITY_MODE
setClock(16000000 / Div); // AVR:16MHz
#else
setClock(SPI_Clock / Div);
#endif
}
void SPIClass::setBitOrder(uint16_t bitOrder)
{
spi_init_struct.first_bit_transmission = (bitOrder == MSBFIRST) ? SPI_FIRST_BIT_MSB : SPI_FIRST_BIT_LSB;
spi_init(SPIx, &spi_init_struct);
spi_enable(SPIx, TRUE);
}
/* Victor Perez. Added to test changing datasize from 8 to 16 bit modes on the fly.
* Input parameter should be SPI_CR1_DFF set to 0 or 1 on a 32bit word.
*
*/
void SPIClass::setDataSize(uint32_t datasize)
{
spi_init_struct.frame_bit_num = (spi_frame_bit_num_type)datasize;
spi_init(SPIx, &spi_init_struct);
spi_enable(SPIx, TRUE);
}
void SPIClass::setDataMode(uint8_t dataMode)
{
/* Notes. As far as I can tell, the AVR numbers for dataMode appear to match the numbers required by the STM32
From the AVR doc http://www.atmel.com/images/doc2585.pdf section 2.4
SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge
0 0 0 Falling Rising
1 0 1 Rising Falling
2 1 0 Rising Falling
3 1 1 Falling Rising
On the STM32 it appears to be
bit 1 - CPOL : Clock polarity
(This bit should not be changed when communication is ongoing)
0 : CLK to 0 when idle
1 : CLK to 1 when idle
bit 0 - CPHA : Clock phase
(This bit should not be changed when communication is ongoing)
0 : The first clock transition is the first data capture edge
1 : The second clock transition is the first data capture edge
If someone finds this is not the case or sees a logic error with this let me know ;-)
*/
spi_clock_polarity_type clock_polarity;
spi_clock_phase_type clock_phase;
spi_enable(SPIx, FALSE);
switch(dataMode)
{
case 0:
clock_polarity = SPI_CLOCK_POLARITY_LOW;
clock_phase = SPI_CLOCK_PHASE_1EDGE;
break;
case 1:
clock_polarity = SPI_CLOCK_POLARITY_LOW;
clock_phase = SPI_CLOCK_PHASE_2EDGE;
break;
case 2:
clock_polarity = SPI_CLOCK_POLARITY_HIGH;
clock_phase = SPI_CLOCK_PHASE_1EDGE;
break;
case 3:
clock_polarity = SPI_CLOCK_POLARITY_HIGH;
clock_phase = SPI_CLOCK_PHASE_2EDGE;
break;
default:
return;
}
spi_init_struct.clock_polarity = clock_polarity;
spi_init_struct.clock_phase = clock_phase;
spi_init(SPIx, &spi_init_struct);
spi_enable(SPIx, TRUE);
}
void SPIClass::beginTransaction(SPISettings settings)
{
SPISettings(settings.clock, settings.bitOrder, settings.dataMode);
setClock(settings.clock);
setBitOrder(settings.bitOrder);
setDataMode(settings.dataMode);
setDataSize(settings.dataSize);
spi_enable(SPIx, TRUE);
}
void SPIClass::beginTransactionSlave(void)
{
beginSlave();
}
void SPIClass::endTransaction(void)
{
spi_enable(SPIx, FALSE);
}
uint16_t SPIClass::read(void)
{
SPI_I2S_WAIT_RX(SPIx);
return (uint16_t)(SPI_I2S_RXDATA(SPIx));
}
void SPIClass::read(uint8_t *buf, uint32_t len)
{
if (len == 0)
return;
SPI_I2S_RXDATA_VOLATILE(SPIx);
SPI_I2S_TXDATA(SPIx, 0x00FF);
while((--len))
{
SPI_I2S_WAIT_TX(SPIx);
noInterrupts();
SPI_I2S_TXDATA(SPIx, 0x00FF);
SPI_I2S_WAIT_RX(SPIx);
*buf++ = (uint8_t)SPI_I2S_RXDATA(SPIx);
interrupts();
}
SPI_I2S_WAIT_RX(SPIx);
*buf++ = (uint8_t)SPI_I2S_RXDATA(SPIx);
}
void SPIClass::write(uint16_t data)
{
SPI_I2S_TXDATA(SPIx, data);
SPI_I2S_WAIT_TX(SPIx);
SPI_I2S_WAIT_BUSY(SPIx);
}
void SPIClass::write(uint16_t data, uint32_t n)
{
while ((n--) > 0)
{
SPI_I2S_TXDATA(SPIx, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
SPI_I2S_WAIT_TX(SPIx); // wait till Tx empty
}
SPI_I2S_WAIT_BUSY(SPIx); // wait until BSY=0 before returning
}
void SPIClass::write(const uint8_t *data, uint32_t length)
{
while (length--)
{
SPI_I2S_WAIT_TX(SPIx);
SPI_I2S_TXDATA(SPIx, *data++);
}
SPI_I2S_WAIT_TX(SPIx);
SPI_I2S_WAIT_BUSY(SPIx);
}
void SPIClass::write(const uint16_t *data, uint32_t length)
{
while (length--)
{
SPI_I2S_WAIT_TX(SPIx);
SPI_I2S_TXDATA(SPIx, *data++);
}
SPI_I2S_WAIT_TX(SPIx);
SPI_I2S_WAIT_BUSY(SPIx);
}
uint8_t SPIClass::transfer(uint8_t wr_data) const
{
SPI_I2S_RXDATA_VOLATILE(SPIx);
SPI_I2S_TXDATA(SPIx, wr_data);
SPI_I2S_WAIT_TX(SPIx);
SPI_I2S_WAIT_BUSY(SPIx);
return (uint8_t)SPI_I2S_RXDATA(SPIx);
}
uint16_t SPIClass::transfer16(uint16_t wr_data) const
{
SPI_I2S_RXDATA_VOLATILE(SPIx);
SPI_I2S_TXDATA(SPIx, wr_data);
SPI_I2S_WAIT_TX(SPIx);
SPI_I2S_WAIT_BUSY(SPIx);
return (uint16_t)SPI_I2S_RXDATA(SPIx);
}
uint8_t SPIClass::send(uint8_t data)
{
this->write(data);
return 1;
}
uint8_t SPIClass::send(uint8_t *buf, uint32_t len)
{
this->write(buf, len);
return len;
}
uint8_t SPIClass::recv(void)
{
return this->read();
}
#if SPI_CLASS_1_ENABLE
SPIClass SPI(SPI_CLASS_1_SPI);
#endif
#if SPI_CLASS_2_ENABLE
SPIClass SPI_2(SPI_CLASS_2_SPI);
#endif
#if SPI_CLASS_3_ENABLE
SPIClass SPI_3(SPI_CLASS_3_SPI);
#endif

173
cores/arduino/SPI.h Normal file
View File

@@ -0,0 +1,173 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __SPI_H
#define __SPI_H
#include "Arduino.h"
#ifndef LSBFIRST
# define LSBFIRST 0
#endif
#ifndef MSBFIRST
# define MSBFIRST 1
#endif
#if SPI_CLASS_PIN_DEFINE_ENABLE
# define SS PA4
# define SCK PA5
# define MISO PA6
# define MOSI PA7
#endif
#define DATA_SIZE_8BIT SPI_FRAME_8BIT
#define DATA_SIZE_16BIT SPI_FRAME_16BIT
#define SPI_I2S_GET_FLAG(spix, SPI_I2S_FLAG) (spix->sts & SPI_I2S_FLAG)
#define SPI_I2S_RXDATA(spix) (spix->dt)
#define SPI_I2S_RXDATA_VOLATILE(spix) do{ volatile uint16_t vn = SPI_I2S_RXDATA(spix); vn = vn; } while(0)
#define SPI_I2S_TXDATA(spix, data) (spix->dt = (data))
#define SPI_I2S_WAIT_RX(spix) do{ while (!SPI_I2S_GET_FLAG(spix, SPI_I2S_RDBF_FLAG)); } while(0)
#define SPI_I2S_WAIT_TX(spix) do{ while (!SPI_I2S_GET_FLAG(spix, SPI_I2S_TDBE_FLAG)); } while(0)
#define SPI_I2S_WAIT_BUSY(spix) do{ while (SPI_I2S_GET_FLAG(spix, SPI_I2S_BF_FLAG)); } while(0)
typedef enum
{
SPI_MODE0,
SPI_MODE1,
SPI_MODE2,
SPI_MODE3
} SPI_MODE_TypeDef;
typedef enum
{
SPI_STATE_IDLE,
SPI_STATE_READY,
SPI_STATE_RECEIVE,
SPI_STATE_TRANSMIT,
SPI_STATE_TRANSFER
} spi_mode_t;
class SPISettings
{
public:
SPISettings(uint32_t clock, uint16_t bitOrder, uint8_t dataMode)
{
init_AlwaysInline(clock, bitOrder, dataMode, DATA_SIZE_8BIT);
}
SPISettings(uint32_t clock, uint16_t bitOrder, uint8_t dataMode, uint32_t dataSize)
{
init_AlwaysInline(clock, bitOrder, dataMode, dataSize);
}
SPISettings(uint32_t clock)
{
init_AlwaysInline(clock, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
}
SPISettings()
{
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
}
private:
void init_MightInline(uint32_t clock, uint16_t bitOrder, uint8_t dataMode, uint32_t dataSize)
{
init_AlwaysInline(clock, bitOrder, dataMode, dataSize);
}
void init_AlwaysInline(uint32_t clock, uint16_t bitOrder, uint8_t dataMode, uint32_t dataSize) __attribute__((__always_inline__))
{
this->clock = clock;
this->bitOrder = bitOrder;
this->dataMode = dataMode;
this->dataSize = dataSize;
}
uint32_t clock;
uint16_t bitOrder;
uint8_t dataMode;
uint32_t dataSize;
friend class SPIClass;
};
class SPIClass
{
public:
SPIClass(spi_type* spix);
void SPI_Settings(
spi_master_slave_mode_type master_slave_mode,
spi_frame_bit_num_type frame_bit_num,
uint16_t SPI_MODEx,
spi_cs_mode_type cs_mode,
spi_mclk_freq_div_type mclk_freq_div,
spi_first_bit_type first_bit
);
void begin(void);
void begin(uint32_t clock, uint16_t dataOrder, uint16_t dataMode);
void begin(SPISettings settings);
void beginSlave(uint32_t bitOrder, uint32_t mode);
void beginSlave(void);
void beginTransactionSlave(void);
void beginTransaction(SPISettings settings);
void endTransaction(void);
void end(void);
void setClock(uint32_t clock);
void setClockDivider(uint32_t Div);
void setBitOrder(uint16_t bitOrder);
void setDataMode(uint8_t dataMode);
void setDataSize(uint32_t datasize);
uint16_t read(void);
void read(uint8_t *buffer, uint32_t length);
void write(uint16_t data);
void write(uint16_t data, uint32_t n);
void write(const uint8_t *data, uint32_t length);
void write(const uint16_t *data, uint32_t length);
uint8_t transfer(uint8_t data) const;
uint16_t transfer16(uint16_t data) const;
uint8_t send(uint8_t data);
uint8_t send(uint8_t *data, uint32_t length);
uint8_t recv(void);
spi_type* getSPI()
{
return SPIx;
}
private:
spi_type* SPIx;
spi_init_type spi_init_struct;
uint32_t SPI_Clock;
};
#if SPI_CLASS_1_ENABLE
extern SPIClass SPI;
#endif
#if SPI_CLASS_2_ENABLE
extern SPIClass SPI_2;
#endif
#if SPI_CLASS_3_ENABLE
extern SPIClass SPI_3;
#endif
#endif

346
cores/arduino/Stream.cpp Normal file
View File

@@ -0,0 +1,346 @@
/*
Stream.cpp - adds parsing methods to Stream class
Copyright (c) 2008 David A. Mellis. All right reserved.
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
Created July 2011
parsing functions based on TextFinder library by Michael Margolis
findMulti/findUntil routines written by Jim Leonard/Xuth
*/
#include "Arduino.h"
#include "Stream.h"
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
// protected method to read stream with timeout
int Stream::timedRead()
{
int c;
_startMillis = millis();
do
{
c = read();
if (c >= 0) return c;
}
while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
// protected method to peek stream with timeout
int Stream::timedPeek()
{
int c;
_startMillis = millis();
do
{
c = peek();
if (c >= 0) return c;
}
while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
// returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters
int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal)
{
int c;
while (1)
{
c = timedPeek();
if( c < 0 ||
c == '-' ||
(c >= '0' && c <= '9') ||
(detectDecimal && c == '.')) return c;
switch( lookahead )
{
case SKIP_NONE:
return -1; // Fail code.
case SKIP_WHITESPACE:
switch( c )
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
default:
return -1; // Fail code.
}
case SKIP_ALL:
break;
}
read(); // discard non-numeric
}
}
// Public Methods
//////////////////////////////////////////////////////////////
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{
_timeout = timeout;
}
// find returns true if the target string is found
bool Stream::find(char *target)
{
return findUntil(target, strlen(target), NULL, 0);
}
// reads data from the stream until the target string of given length is found
// returns true if target string is found, false if timed out
bool Stream::find(char *target, size_t length)
{
return findUntil(target, length, NULL, 0);
}
// as find but search ends if the terminator string is found
bool Stream::findUntil(char *target, char *terminator)
{
return findUntil(target, strlen(target), terminator, strlen(terminator));
}
// reads data from the stream until the target string of the given length is found
// search terminated if the terminator string is found
// returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
{
if (terminator == NULL)
{
MultiTarget t[1] = {{target, targetLen, 0}};
return findMulti(t, 1) == 0 ? true : false;
}
else
{
MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}};
return findMulti(t, 2) == 0 ? true : false;
}
}
// returns the first valid (long) integer value from the current position.
// lookahead determines how parseInt looks ahead in the stream.
// See LookaheadMode enumeration at the top of the file.
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream.
long Stream::parseInt(LookaheadMode lookahead, char ignore)
{
bool isNegative = false;
long value = 0;
int c;
c = peekNextDigit(lookahead, false);
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do
{
if(c == ignore)
; // ignore this character
else if(c == '-')
isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0';
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == ignore );
if(isNegative)
value = -value;
return value;
}
// as parseInt but returns a floating point value
float Stream::parseFloat(LookaheadMode lookahead, char ignore)
{
bool isNegative = false;
bool isFraction = false;
long value = 0;
int c;
float fraction = 1.0;
c = peekNextDigit(lookahead, true);
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do
{
if(c == ignore)
; // ignore
else if(c == '-')
isNegative = true;
else if (c == '.')
isFraction = true;
else if(c >= '0' && c <= '9') // is c a digit?
{
value = value * 10 + c - '0';
if(isFraction)
fraction *= 0.1f;
}
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore );
if(isNegative)
value = -value;
if(isFraction)
return value * fraction;
else
return value;
}
// read characters from stream into buffer
// terminates if length characters have been read, or timeout (see setTimeout)
// returns the number of characters placed in the buffer
// the buffer is NOT null terminated.
//
size_t Stream::readBytes(char *buffer, size_t length)
{
size_t count = 0;
while (count < length)
{
int c = timedRead();
if (c < 0) break;
*buffer++ = (char)c;
count++;
}
return count;
}
// as readBytes with terminator character
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
{
size_t index = 0;
while (index < length)
{
int c = timedRead();
if (c < 0 || c == terminator) break;
*buffer++ = (char)c;
index++;
}
return index; // return number of characters, not including null terminator
}
String Stream::readString()
{
String ret;
int c = timedRead();
while (c >= 0)
{
ret += (char)c;
c = timedRead();
}
return ret;
}
String Stream::readStringUntil(char terminator)
{
String ret;
int c = timedRead();
while (c >= 0 && c != terminator)
{
ret += (char)c;
c = timedRead();
}
return ret;
}
int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount)
{
// any zero length target string automatically matches and would make
// a mess of the rest of the algorithm.
for (struct MultiTarget *t = targets; t < targets + tCount; ++t)
{
if (t->len <= 0)
return t - targets;
}
while (1)
{
int c = timedRead();
if (c < 0)
return -1;
for (struct MultiTarget *t = targets; t < targets + tCount; ++t)
{
// the simple case is if we match, deal with that first.
if (c == t->str[t->index])
{
if (++t->index == t->len)
return t - targets;
else
continue;
}
// if not we need to walk back and see if we could have matched further
// down the stream (ie '1112' doesn't match the first position in '11112'
// but it will match the second position so we can't just reset the current
// index to 0 when we find a mismatch.
if (t->index == 0)
continue;
int origIndex = t->index;
do
{
--t->index;
// first check if current char works against the new current index
if (c != t->str[t->index])
continue;
// if it's the only char then we're good, nothing more to check
if (t->index == 0)
{
t->index++;
break;
}
// otherwise we need to check the rest of the found string
int diff = origIndex - t->index;
size_t i;
for (i = 0; i < t->index; ++i)
{
if (t->str[i] != t->str[i + diff])
break;
}
// if we successfully got through the previous loop then our current
// index is good.
if (i == t->index)
{
t->index++;
break;
}
// otherwise we just try the next index
}
while (t->index);
}
}
// unreachable
//return -1;
}

165
cores/arduino/Stream.h Normal file
View File

@@ -0,0 +1,165 @@
/*
Stream.h - base class for character-based streams.
Copyright (c) 2010 David A. Mellis. All right reserved.
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
parsing functions based on TextFinder library by Michael Margolis
*/
#ifndef Stream_h
#define Stream_h
#include <inttypes.h>
#include "Print.h"
// compatibility macros for testing
/*
#define getInt() parseInt()
#define getInt(ignore) parseInt(ignore)
#define getFloat() parseFloat()
#define getFloat(ignore) parseFloat(ignore)
#define getString( pre_string, post_string, buffer, length)
readBytesBetween( pre_string, terminator, buffer, length)
*/
// This enumeration provides the lookahead options for parseInt(), parseFloat()
// The rules set out here are used until either the first valid character is found
// or a time out occurs due to lack of input.
enum LookaheadMode
{
SKIP_ALL, // All invalid characters are ignored.
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
};
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
class Stream : public Print
{
protected:
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
unsigned long _startMillis; // used for timeout measurement
int timedRead(); // read stream with timeout
int timedPeek(); // peek stream with timeout
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
public:
virtual int available() = 0;
virtual int read() = 0;
virtual int peek() = 0;
Stream()
: _timeout(1000)
, _startMillis(0)
{
}
// parsing methods
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
unsigned long getTimeout(void)
{
return _timeout;
}
bool find(char *target); // reads data from the stream until the target string is found
bool find(uint8_t *target)
{
return find ((char *)target);
}
// returns true if target string is found, false if timed out (see setTimeout)
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
bool find(uint8_t *target, size_t length)
{
return find ((char *)target, length);
}
// returns true if target string is found, false if timed out
bool find(char target)
{
return find (&target, 1);
}
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
bool findUntil(uint8_t *target, char *terminator)
{
return findUntil((char *)target, terminator);
}
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen)
{
return findUntil((char *)target, targetLen, terminate, termLen);
}
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// returns the first valid (long) integer value from the current position.
// lookahead determines how parseInt looks ahead in the stream.
// See LookaheadMode enumeration at the top of the file.
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream.
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// float version of parseInt
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
size_t readBytes( uint8_t *buffer, size_t length)
{
return readBytes((char *)buffer, length);
}
// terminates if length characters have been read or timeout (see setTimeout)
// returns the number of characters placed in the buffer (0 means no valid data found)
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length)
{
return readBytesUntil(terminator, (char *)buffer, length);
}
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
// Arduino String functions to be added here
String readString();
String readStringUntil(char terminator);
protected:
long parseInt(char ignore)
{
return parseInt(SKIP_ALL, ignore);
}
float parseFloat(char ignore)
{
return parseFloat(SKIP_ALL, ignore);
}
// These overload exists for compatibility with any class that has derived
// Stream and used parseFloat/Int with a custom ignore character. To keep
// the public API simple, these overload remains protected.
struct MultiTarget
{
const char *str; // string you're searching for
size_t len; // length of string you're searching for
size_t index; // index used by the search routine.
};
// This allows you to search for an arbitrary number of strings.
// Returns index of the target that is found first or -1 if timeout occurs.
int findMulti(struct MultiTarget *targets, int tCount);
};
#undef NO_IGNORE_CHAR
#endif

128
cores/arduino/Tone.cpp Normal file
View File

@@ -0,0 +1,128 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "Tone.h"
#include "Arduino.h"
#define TONE_FREQ_MAX 500000U
static tmr_type* Tone_Timer = NULL;
static bool Tone_IsContinuousModeEnable = false;
static uint8_t Tone_Pin = NOT_A_PIN;
static uint32_t Tone_ToggleCounter = 0;
/**
* @brief tone中断入口被定时中断调用
* @param 无
* @retval 无
*/
static void Tone_TimerHandler()
{
if(!Tone_IsContinuousModeEnable)
{
if(Tone_ToggleCounter == 0)
{
noTone(Tone_Pin);
return;
}
Tone_ToggleCounter--;
}
togglePin(Tone_Pin);
}
/**
* @brief 改变tone所使用的定时器
* @param TIMx: 定时器地址
* @retval 无
*/
void toneSetTimer(tmr_type* TIMx)
{
Timer_SetInterruptBase(
TIMx,
0xFF,
0xFF,
Tone_TimerHandler,
TONE_PREEMPTIONPRIORITY_DEFAULT,
TONE_SUBPRIORITY_DEFAULT
);
Tone_Timer = TIMx;
}
/**
* @brief 在Pin上生成指定频率 (50%占空比的方波)
* @param pin: 产生音调的 Pin
* @param freq: 频率(Hz)
* @param duration: 音调的持续时间 (以毫秒为单位)
* @retval 无
*/
void tone(uint8_t pin, uint32_t freq, uint32_t duration)
{
noTone(pin);
if(duration == 0 || freq == 0 || freq > TONE_FREQ_MAX)
{
return;
}
Tone_Pin = pin;
Tone_IsContinuousModeEnable = (duration == TONE_DURATION_INFINITE) ? true : false;
if(!Tone_IsContinuousModeEnable)
{
Tone_ToggleCounter = freq * duration / 1000 * 2;
if(Tone_ToggleCounter == 0)
{
return;
}
Tone_ToggleCounter--;
}
if(Tone_Timer == NULL)
{
toneSetTimer(TONE_TIMER_DEFAULT);
}
Timer_SetInterruptTimeUpdate(Tone_Timer, TONE_FREQ_MAX / freq);
Timer_SetEnable(Tone_Timer, true);
}
/**
* @brief 关闭声音
* @param Pin: 产生音调的引脚编号
* @retval 无
*/
void noTone(uint8_t pin)
{
if(Tone_Timer)
{
Timer_SetEnable(Tone_Timer, false);
}
digitalWrite(pin, LOW);
Tone_IsContinuousModeEnable = false;
Tone_Pin = NOT_A_PIN;
Tone_ToggleCounter = 0;
}

34
cores/arduino/Tone.h Normal file
View File

@@ -0,0 +1,34 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __TONE_H
#define __TONE_H
#include "libcore/timer.h"
#define TONE_DURATION_INFINITE 0xFFFFFFFFU
void toneSetTimer(tmr_type* TIMx);
void tone(uint8_t pin, uint32_t freq, uint32_t duration = TONE_DURATION_INFINITE);
void noTone(uint8_t pin);
#endif

171
cores/arduino/WCharacter.h Normal file
View File

@@ -0,0 +1,171 @@
/*
WCharacter.h - Character utility functions for Wiring & Arduino
Copyright (c) 2010 Hernando Barragan. All right reserved.
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
*/
#ifndef Character_h
#define Character_h
#include <ctype.h>
// #define isascii(c) ((unsigned int)c < 0x7F)
// #define toascii(c) ((unsigned char)c)
// WCharacter.h prototypes
inline bool isAlphaNumeric(int c) __attribute__((always_inline));
inline bool isAlpha(int c) __attribute__((always_inline));
inline bool isAscii(int c) __attribute__((always_inline));
inline bool isWhitespace(int c) __attribute__((always_inline));
inline bool isControl(int c) __attribute__((always_inline));
inline bool isDigit(int c) __attribute__((always_inline));
inline bool isGraph(int c) __attribute__((always_inline));
inline bool isLowerCase(int c) __attribute__((always_inline));
inline bool isPrintable(int c) __attribute__((always_inline));
inline bool isPunct(int c) __attribute__((always_inline));
inline bool isSpace(int c) __attribute__((always_inline));
inline bool isUpperCase(int c) __attribute__((always_inline));
inline bool isHexadecimalDigit(int c) __attribute__((always_inline));
inline int toAscii(int c) __attribute__((always_inline));
inline int toLowerCase(int c) __attribute__((always_inline));
inline int toUpperCase(int c)__attribute__((always_inline));
// Checks for an alphanumeric character.
// It is equivalent to (isalpha(c) || isdigit(c)).
inline bool isAlphaNumeric(int c)
{
return ( isalnum(c) == 0 ? false : true);
}
// Checks for an alphabetic character.
// It is equivalent to (isupper(c) || islower(c)).
inline bool isAlpha(int c)
{
return ( isalpha(c) == 0 ? false : true);
}
// Checks whether c is a 7-bit unsigned char value
// that fits into the ASCII character set.
inline bool isAscii(int c)
{
return ( isascii (c) == 0 ? false : true);
}
// Checks for a blank character, that is, a space or a tab.
inline bool isWhitespace(int c)
{
return ( isblank (c) == 0 ? false : true);
}
// Checks for a control character.
inline bool isControl(int c)
{
return ( iscntrl (c) == 0 ? false : true);
}
// Checks for a digit (0 through 9).
inline bool isDigit(int c)
{
return ( isdigit (c) == 0 ? false : true);
}
// Checks for any printable character except space.
inline bool isGraph(int c)
{
return ( isgraph (c) == 0 ? false : true);
}
// Checks for a lower-case character.
inline bool isLowerCase(int c)
{
return (islower (c) == 0 ? false : true);
}
// Checks for any printable character including space.
inline bool isPrintable(int c)
{
return ( isprint (c) == 0 ? false : true);
}
// Checks for any printable character which is not a space
// or an alphanumeric character.
inline bool isPunct(int c)
{
return ( ispunct (c) == 0 ? false : true);
}
// Checks for white-space characters. For the avr-libc library,
// these are: space, formfeed ('\f'), newline ('\n'), carriage
// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
inline bool isSpace(int c)
{
return ( isspace (c) == 0 ? false : true);
}
// Checks for an uppercase letter.
inline bool isUpperCase(int c)
{
return ( isupper (c) == 0 ? false : true);
}
// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
// 8 9 a b c d e f A B C D E F.
inline bool isHexadecimalDigit(int c)
{
return ( isxdigit (c) == 0 ? false : true);
}
// Converts c to a 7-bit unsigned char value that fits into the
// ASCII character set, by clearing the high-order bits.
inline int toAscii(int c)
{
return toascii (c);
}
// Warning:
// Many people will be unhappy if you use this function.
// This function will convert accented letters into random
// characters.
// Converts the letter c to lower case, if possible.
inline int toLowerCase(int c)
{
return tolower (c);
}
// Converts the letter c to upper case, if possible.
inline int toUpperCase(int c)
{
return toupper (c);
}
#endif

60
cores/arduino/WMath.cpp Normal file
View File

@@ -0,0 +1,60 @@
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Wiring project - http://wiring.org.co
Copyright (c) 2004-06 Hernando Barragan
Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/
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., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
#include "WMath.h"
void randomSeed(unsigned long seed)
{
if (seed != 0)
{
srand(seed);
}
}
long random(long howbig)
{
if (howbig == 0)
{
return 0;
}
return rand() % howbig;
}
long random(long howsmall, long howbig)
{
if (howsmall >= howbig)
{
return howsmall;
}
long diff = howbig - howsmall;
return random(diff) + howsmall;
}
unsigned int makeWord(unsigned int w)
{
return w;
}
unsigned int makeWord(unsigned char h, unsigned char l)
{
return (h << 8) | l;
}

12
cores/arduino/WMath.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef __WMATH_H
#define __WMATH_H
extern "C" {
#include "stdlib.h"
}
void randomSeed(unsigned long seed);
long random(long howbig);
long random(long howsmall, long howbig);
#endif

6
cores/arduino/WProgram.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef __WPROGRAM_H
#define __WPROGRAM_H
#include "Arduino.h"
#endif

791
cores/arduino/WString.cpp Normal file
View File

@@ -0,0 +1,791 @@
/*
WString.cpp - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.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
*/
#include "WString.h"
#include "itoa.h"
#include "dtostrf.h"
#include "libcore/config/mcu_config.h"
#include WSTRING_MEM_INCLUDE
/*********************************************/
/* Constructors */
/*********************************************/
String::String(const char *cstr)
{
init();
if (cstr) copy(cstr, strlen(cstr));
}
String::String(const String &value)
{
init();
*this = value;
}
String::String(const __FlashStringHelper *pstr)
{
init();
*this = pstr;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String::String(String &&rval)
{
init();
move(rval);
}
String::String(StringSumHelper &&rval)
{
init();
move(rval);
}
#endif
String::String(char c)
{
init();
char buf[2];
buf[0] = c;
buf[1] = 0;
*this = buf;
}
String::String(unsigned char value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned char)];
utoa(value, buf, base);
*this = buf;
}
String::String(int value, unsigned char base)
{
init();
char buf[2 + 8 * sizeof(int)];
itoa(value, buf, base);
*this = buf;
}
String::String(unsigned int value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned int)];
utoa(value, buf, base);
*this = buf;
}
String::String(long value, unsigned char base)
{
init();
char buf[2 + 8 * sizeof(long)];
ltoa(value, buf, base);
*this = buf;
}
String::String(unsigned long value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned long)];
ultoa(value, buf, base);
*this = buf;
}
String::String(float value, unsigned char decimalPlaces)
{
init();
char buf[33];
*this = dtostrnf(value, (decimalPlaces + 2), decimalPlaces, buf, sizeof(buf));
}
String::String(double value, unsigned char decimalPlaces)
{
init();
char buf[33];
*this = dtostrnf(value, (decimalPlaces + 2), decimalPlaces, buf, sizeof(buf));
}
String::~String()
{
if (buffer) WSTRING_MEM_FREE(buffer);
}
/*********************************************/
/* Memory Management */
/*********************************************/
inline void String::init(void)
{
buffer = NULL;
capacity = 0;
len = 0;
}
void String::invalidate(void)
{
if (buffer) WSTRING_MEM_FREE(buffer);
buffer = NULL;
capacity = len = 0;
}
unsigned char String::reserve(unsigned int size)
{
if (buffer && capacity >= size) return 1;
if (changeBuffer(size))
{
if (len == 0) buffer[0] = 0;
return 1;
}
return 0;
}
unsigned char String::changeBuffer(unsigned int maxStrLen)
{
char *newbuffer = (char *)WSTRING_MEM_REALLOC(buffer, maxStrLen + 1);
if (newbuffer)
{
buffer = newbuffer;
capacity = maxStrLen;
return 1;
}
return 0;
}
/*********************************************/
/* Copy and Move */
/*********************************************/
String & String::copy(const char *cstr, unsigned int length)
{
if (!reserve(length))
{
invalidate();
return *this;
}
len = length;
strcpy(buffer, cstr);
return *this;
}
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
{
if (!reserve(length))
{
invalidate();
return *this;
}
len = length;
strcpy(buffer, (PGM_P)pstr);
return *this;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
void String::move(String &rhs)
{
if (buffer)
{
if (rhs && capacity >= rhs.len)
{
strcpy(buffer, rhs.buffer);
len = rhs.len;
rhs.len = 0;
return;
}
else
{
WSTRING_MEM_FREE(buffer);
}
}
buffer = rhs.buffer;
capacity = rhs.capacity;
len = rhs.len;
rhs.buffer = NULL;
rhs.capacity = 0;
rhs.len = 0;
}
#endif
String & String::operator = (const String &rhs)
{
if (this == &rhs) return *this;
if (rhs.buffer) copy(rhs.buffer, rhs.len);
else invalidate();
return *this;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String & String::operator = (String &&rval)
{
if (this != &rval) move(rval);
return *this;
}
String & String::operator = (StringSumHelper &&rval)
{
if (this != &rval) move(rval);
return *this;
}
#endif
String & String::operator = (const char *cstr)
{
if (cstr) copy(cstr, strlen(cstr));
else invalidate();
return *this;
}
String & String::operator = (const __FlashStringHelper *pstr)
{
if (pstr) copy(pstr, strlen((PGM_P)pstr));
else invalidate();
return *this;
}
/*********************************************/
/* concat */
/*********************************************/
unsigned char String::concat(const String &s)
{
return concat(s.buffer, s.len);
}
unsigned char String::concat(const char *cstr, unsigned int length)
{
unsigned int newlen = len + length;
if (!cstr) return 0;
if (length == 0) return 1;
if (!reserve(newlen)) return 0;
strcpy(buffer + len, cstr);
len = newlen;
return 1;
}
unsigned char String::concat(const char *cstr)
{
if (!cstr) return 0;
return concat(cstr, strlen(cstr));
}
unsigned char String::concat(char c)
{
char buf[2];
buf[0] = c;
buf[1] = 0;
return concat(buf, 1);
}
unsigned char String::concat(unsigned char num)
{
char buf[1 + 3 * sizeof(unsigned char)];
itoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(int num)
{
char buf[2 + 3 * sizeof(int)];
itoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned int num)
{
char buf[1 + 3 * sizeof(unsigned int)];
utoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(long num)
{
char buf[2 + 3 * sizeof(long)];
ltoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned long num)
{
char buf[1 + 3 * sizeof(unsigned long)];
ultoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(float num)
{
char buf[20];
char* string = dtostrnf(num, 4, 2, buf, sizeof(buf));
return concat(string, strlen(string));
}
unsigned char String::concat(double num)
{
char buf[20];
char* string = dtostrnf(num, 4, 2, buf, sizeof(buf));
return concat(string, strlen(string));
}
unsigned char String::concat(const __FlashStringHelper * str)
{
if (!str) return 0;
int length = strlen((const char *) str);
if (length == 0) return 1;
unsigned int newlen = len + length;
if (!reserve(newlen)) return 0;
strcpy(buffer + len, (const char *) str);
len = newlen;
return 1;
}
/*********************************************/
/* Concatenate */
/*********************************************/
StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(c)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, float num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, double num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs)) a.invalidate();
return a;
}
/*********************************************/
/* Comparison */
/*********************************************/
int String::compareTo(const String &s) const
{
if (!buffer || !s.buffer)
{
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
if (buffer && len > 0) return *(unsigned char *)buffer;
return 0;
}
return strcmp(buffer, s.buffer);
}
unsigned char String::equals(const String &s2) const
{
return (len == s2.len && compareTo(s2) == 0);
}
unsigned char String::equals(const char *cstr) const
{
if (len == 0) return (cstr == NULL || *cstr == 0);
if (cstr == NULL) return buffer[0] == 0;
return strcmp(buffer, cstr) == 0;
}
unsigned char String::operator<(const String &rhs) const
{
return compareTo(rhs) < 0;
}
unsigned char String::operator>(const String &rhs) const
{
return compareTo(rhs) > 0;
}
unsigned char String::operator<=(const String &rhs) const
{
return compareTo(rhs) <= 0;
}
unsigned char String::operator>=(const String &rhs) const
{
return compareTo(rhs) >= 0;
}
unsigned char String::equalsIgnoreCase( const String &s2 ) const
{
if (this == &s2) return 1;
if (len != s2.len) return 0;
if (len == 0) return 1;
const char *p1 = buffer;
const char *p2 = s2.buffer;
while (*p1)
{
if (tolower(*p1++) != tolower(*p2++)) return 0;
}
return 1;
}
unsigned char String::startsWith( const String &s2 ) const
{
if (len < s2.len) return 0;
return startsWith(s2, 0);
}
unsigned char String::startsWith( const String &s2, unsigned int offset ) const
{
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
}
unsigned char String::endsWith( const String &s2 ) const
{
if ( len < s2.len || !buffer || !s2.buffer) return 0;
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
}
/*********************************************/
/* Character Access */
/*********************************************/
char String::charAt(unsigned int loc) const
{
return operator[](loc);
}
void String::setCharAt(unsigned int loc, char c)
{
if (loc < len) buffer[loc] = c;
}
char & String::operator[](unsigned int index)
{
static char dummy_writable_char;
if (index >= len || !buffer)
{
dummy_writable_char = 0;
return dummy_writable_char;
}
return buffer[index];
}
char String::operator[]( unsigned int index ) const
{
if (index >= len || !buffer) return 0;
return buffer[index];
}
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
{
if (!bufsize || !buf) return;
if (index >= len)
{
buf[0] = 0;
return;
}
unsigned int n = bufsize - 1;
if (n > len - index) n = len - index;
strncpy((char *)buf, buffer + index, n);
buf[n] = 0;
}
/*********************************************/
/* Search */
/*********************************************/
int String::indexOf(char c) const
{
return indexOf(c, 0);
}
int String::indexOf( char ch, unsigned int fromIndex ) const
{
if (fromIndex >= len) return -1;
const char* temp = strchr(buffer + fromIndex, ch);
if (temp == NULL) return -1;
return temp - buffer;
}
int String::indexOf(const String &s2) const
{
return indexOf(s2, 0);
}
int String::indexOf(const String &s2, unsigned int fromIndex) const
{
if (fromIndex >= len) return -1;
const char *found = strstr(buffer + fromIndex, s2.buffer);
if (found == NULL) return -1;
return found - buffer;
}
int String::lastIndexOf( char theChar ) const
{
return lastIndexOf(theChar, len - 1);
}
int String::lastIndexOf(char ch, unsigned int fromIndex) const
{
if (fromIndex >= len) return -1;
char tempchar = buffer[fromIndex + 1];
buffer[fromIndex + 1] = '\0';
char* temp = strrchr( buffer, ch );
buffer[fromIndex + 1] = tempchar;
if (temp == NULL) return -1;
return temp - buffer;
}
int String::lastIndexOf(const String &s2) const
{
return lastIndexOf(s2, len - s2.len);
}
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
{
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
if (fromIndex >= len) fromIndex = len - 1;
int found = -1;
for (char *p = buffer; p <= buffer + fromIndex; p++)
{
p = strstr(p, s2.buffer);
if (!p) break;
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
}
return found;
}
String String::substring(unsigned int left, unsigned int right) const
{
if (left > right)
{
unsigned int temp = right;
right = left;
left = temp;
}
String out;
if (left >= len) return out;
if (right > len) right = len;
char temp = buffer[right]; // save the replaced character
buffer[right] = '\0';
out = buffer + left; // pointer arithmetic
buffer[right] = temp; //restore character
return out;
}
/*********************************************/
/* Modification */
/*********************************************/
void String::replace(char find, char replace)
{
if (!buffer) return;
for (char *p = buffer; *p; p++)
{
if (*p == find) *p = replace;
}
}
void String::replace(const String& find, const String& replace)
{
if (len == 0 || find.len == 0) return;
int diff = replace.len - find.len;
char *readFrom = buffer;
char *foundAt;
if (diff == 0)
{
while ((foundAt = strstr(readFrom, find.buffer)) != NULL)
{
memcpy(foundAt, replace.buffer, replace.len);
readFrom = foundAt + replace.len;
}
}
else if (diff < 0)
{
char *writeTo = buffer;
while ((foundAt = strstr(readFrom, find.buffer)) != NULL)
{
unsigned int n = foundAt - readFrom;
memcpy(writeTo, readFrom, n);
writeTo += n;
memcpy(writeTo, replace.buffer, replace.len);
writeTo += replace.len;
readFrom = foundAt + find.len;
len += diff;
}
strcpy(writeTo, readFrom);
}
else
{
unsigned int size = len; // compute size needed for result
while ((foundAt = strstr(readFrom, find.buffer)) != NULL)
{
readFrom = foundAt + find.len;
size += diff;
}
if (size == len) return;
if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
int index = len - 1;
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0)
{
readFrom = buffer + index + find.len;
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
len += diff;
buffer[len] = 0;
memcpy(buffer + index, replace.buffer, replace.len);
index--;
}
}
}
void String::remove(unsigned int index)
{
// Pass the biggest integer as the count. The remove method
// below will take care of truncating it at the end of the
// string.
remove(index, (unsigned int) -1);
}
void String::remove(unsigned int index, unsigned int count)
{
if (index >= len)
{
return;
}
if (count == 0)
{
return;
}
if (count > len - index)
{
count = len - index;
}
char *writeTo = buffer + index;
len = len - count;
strncpy(writeTo, buffer + index + count, len - index);
buffer[len] = 0;
}
void String::toLowerCase(void)
{
if (!buffer) return;
for (char *p = buffer; *p; p++)
{
*p = tolower(*p);
}
}
void String::toUpperCase(void)
{
if (!buffer) return;
for (char *p = buffer; *p; p++)
{
*p = toupper(*p);
}
}
void String::trim(void)
{
if (!buffer || len == 0) return;
char *begin = buffer;
while (isspace(*begin)) begin++;
char *end = buffer + len - 1;
while (isspace(*end) && end >= begin) end--;
len = end + 1 - begin;
if (begin > buffer) memcpy(buffer, begin, len);
buffer[len] = 0;
}
/*********************************************/
/* Parsing / Conversion */
/*********************************************/
long String::toInt(void) const
{
if (buffer) return atol(buffer);
return 0;
}
float String::toFloat(void) const
{
return float(toDouble());
}
double String::toDouble(void) const
{
if (buffer) return atof(buffer);
return 0;
}

311
cores/arduino/WString.h Normal file
View File

@@ -0,0 +1,311 @@
/*
WString.h - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.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
*/
#ifndef String_class_h
#define String_class_h
#ifdef __cplusplus
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <avr/pgmspace.h>
// When compiling programs with this class, the following gcc parameters
// dramatically increase performance and memory (RAM) efficiency, typically
// with little or no increase in code size.
// -felide-constructors
// -std=c++0x
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
// An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations.
class StringSumHelper;
// The string class
class String
{
// use a function pointer to allow for "if (s)" without the
// complications of an operator bool(). for more information, see:
// http://www.artima.com/cppsource/safebool.html
typedef void (String::*StringIfHelperType)() const;
void StringIfHelper() const {}
public:
// constructors
// creates a copy of the initial value.
// if the initial value is null or invalid, or if memory allocation
// fails, the string will be marked as invalid (i.e. "if (s)" will
// be false).
String(const char *cstr = "");
String(const String &str);
String(const __FlashStringHelper *str);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String(String &&rval);
String(StringSumHelper &&rval);
#endif
explicit String(char c);
explicit String(unsigned char, unsigned char base = 10);
explicit String(int, unsigned char base = 10);
explicit String(unsigned int, unsigned char base = 10);
explicit String(long, unsigned char base = 10);
explicit String(unsigned long, unsigned char base = 10);
explicit String(float, unsigned char decimalPlaces = 2);
explicit String(double, unsigned char decimalPlaces = 2);
~String(void);
// memory management
// return true on success, false on failure (in which case, the string
// is left unchanged). reserve(0), if successful, will validate an
// invalid string (i.e., "if (s)" will be true afterwards)
unsigned char reserve(unsigned int size);
inline unsigned int length(void) const
{
return len;
}
// creates a copy of the assigned value. if the value is null or
// invalid, or if the memory allocation fails, the string will be
// marked as invalid ("if (s)" will be false).
String & operator = (const String &rhs);
String & operator = (const char *cstr);
String & operator = (const __FlashStringHelper *str);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String & operator = (String &&rval);
String & operator = (StringSumHelper &&rval);
#endif
// concatenate (works w/ built-in types)
// returns true on success, false on failure (in which case, the string
// is left unchanged). if the argument is null or invalid, the
// concatenation is considered unsuccessful.
unsigned char concat(const String &str);
unsigned char concat(const char *cstr);
unsigned char concat(char c);
unsigned char concat(unsigned char c);
unsigned char concat(int num);
unsigned char concat(unsigned int num);
unsigned char concat(long num);
unsigned char concat(unsigned long num);
unsigned char concat(float num);
unsigned char concat(double num);
unsigned char concat(const __FlashStringHelper * str);
// if there's not enough memory for the concatenated value, the string
// will be left unchanged (but this isn't signalled in any way)
String & operator += (const String &rhs)
{
concat(rhs);
return (*this);
}
String & operator += (const char *cstr)
{
concat(cstr);
return (*this);
}
String & operator += (char c)
{
concat(c);
return (*this);
}
String & operator += (unsigned char num)
{
concat(num);
return (*this);
}
String & operator += (int num)
{
concat(num);
return (*this);
}
String & operator += (unsigned int num)
{
concat(num);
return (*this);
}
String & operator += (long num)
{
concat(num);
return (*this);
}
String & operator += (unsigned long num)
{
concat(num);
return (*this);
}
String & operator += (float num)
{
concat(num);
return (*this);
}
String & operator += (double num)
{
concat(num);
return (*this);
}
String & operator += (const __FlashStringHelper *str)
{
concat(str);
return (*this);
}
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
// comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const
{
return buffer ? &String::StringIfHelper : 0;
}
int compareTo(const String &s) const;
unsigned char equals(const String &s) const;
unsigned char equals(const char *cstr) const;
unsigned char operator == (const String &rhs) const
{
return equals(rhs);
}
unsigned char operator == (const char *cstr) const
{
return equals(cstr);
}
unsigned char operator != (const String &rhs) const
{
return !equals(rhs);
}
unsigned char operator != (const char *cstr) const
{
return !equals(cstr);
}
unsigned char operator < (const String &rhs) const;
unsigned char operator > (const String &rhs) const;
unsigned char operator <= (const String &rhs) const;
unsigned char operator >= (const String &rhs) const;
unsigned char equalsIgnoreCase(const String &s) const;
unsigned char startsWith( const String &prefix) const;
unsigned char startsWith(const String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const;
// character access
char charAt(unsigned int index) const;
void setCharAt(unsigned int index, char c);
char operator [] (unsigned int index) const;
char& operator [] (unsigned int index);
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index = 0) const;
void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const
{
getBytes((unsigned char *)buf, bufsize, index);
}
const char* c_str() const
{
return buffer;
}
char* begin()
{
return buffer;
}
char* end()
{
return buffer + length();
}
const char* begin() const
{
return c_str();
}
const char* end() const
{
return c_str() + length();
}
// search
int indexOf( char ch ) const;
int indexOf( char ch, unsigned int fromIndex ) const;
int indexOf( const String &str ) const;
int indexOf( const String &str, unsigned int fromIndex ) const;
int lastIndexOf( char ch ) const;
int lastIndexOf( char ch, unsigned int fromIndex ) const;
int lastIndexOf( const String &str ) const;
int lastIndexOf( const String &str, unsigned int fromIndex ) const;
String substring( unsigned int beginIndex ) const
{
return substring(beginIndex, len);
};
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
// modification
void replace(char find, char replace);
void replace(const String& find, const String& replace);
void remove(unsigned int index);
void remove(unsigned int index, unsigned int count);
void toLowerCase(void);
void toUpperCase(void);
void trim(void);
// parsing/conversion
long toInt(void) const;
float toFloat(void) const;
double toDouble(void) const;
protected:
char *buffer; // the actual char array
unsigned int capacity; // the array length minus one (for the '\0')
unsigned int len; // the String length (not counting the '\0')
protected:
void init(void);
void invalidate(void);
unsigned char changeBuffer(unsigned int maxStrLen);
unsigned char concat(const char *cstr, unsigned int length);
// copy and move
String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *pstr, unsigned int length);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
void move(String &rhs);
#endif
};
class StringSumHelper : public String
{
public:
StringSumHelper(const String &s) : String(s) {}
StringSumHelper(const char *p) : String(p) {}
StringSumHelper(char c) : String(c) {}
StringSumHelper(unsigned char num) : String(num) {}
StringSumHelper(int num) : String(num) {}
StringSumHelper(unsigned int num) : String(num) {}
StringSumHelper(long num) : String(num) {}
StringSumHelper(unsigned long num) : String(num) {}
StringSumHelper(float num) : String(num) {}
StringSumHelper(double num) : String(num) {}
};
#endif // __cplusplus
#endif // String_class_h

242
cores/arduino/Wire.cpp Normal file
View File

@@ -0,0 +1,242 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file Wire.cpp
* @author Trystan Jones <crenn6977@gmail.com>
* @brief Wire library, uses the WireBase to create the primary interface
* while keeping low level interactions invisible to the user.
*/
/*
* Library updated by crenn to follow new Wire system.
* Code was derived from the original Wire for maple code by leaflabs and the
* modifications by gke and ala42.
*/
/*
* Updated by Roger Clark. 20141111. Fixed issue when process() returned because of missing ACK (often caused by invalid device address being used), caused SCL to be left
* LOW so that in the next call to process() , the first clock pulse was not sent, because SCL was LOW when it should have been high.
*/
#include "Wire.h"
#if WIRE_USE_FULL_SPEED_I2C
# define I2C_DELAY(x)
# define SET_SDA(state) digitalWrite_##state(this->sda_pin)
# define SET_SCL(state) digitalWrite_##state(this->scl_pin)
#else
# define I2C_DELAY(x) delayMicroseconds(x)
# define SET_SDA(state) set_sda(state)
# define SET_SCL(state) set_scl(state)
#endif
#define I2C_WRITE 0
#define I2C_READ 1
// TODO: Add in Error Handling if pins is out of range for other Maples
// TODO: Make delays more capable
TwoWire::TwoWire(uint8_t scl, uint8_t sda, uint8_t delay) : i2c_delay(delay)
{
this->scl_pin = scl;
this->sda_pin = sda;
}
TwoWire::~TwoWire()
{
}
bool TwoWire::begin(uint8_t self_addr)
{
WireBase::begin(self_addr);
pinMode(this->scl_pin, OUTPUT_OPEN_DRAIN);
pinMode(this->sda_pin, OUTPUT_OPEN_DRAIN);
bool success = set_scl(HIGH, WIRE_BEGIN_TIMEOUT);
set_sda(HIGH);
return success;
}
/* low level conventions:
* - SDA/SCL idle high (expected high)
* - always start with i2c_delay rather than end
*/
void TwoWire::set_scl(bool state)
{
I2C_DELAY(this->i2c_delay);
digitalWrite(this->scl_pin, state);
//Allow for clock stretching - dangerous currently
if (state == HIGH)
{
while(digitalRead(this->scl_pin) == 0);
}
}
bool TwoWire::set_scl(bool state, uint32_t timeout)
{
I2C_DELAY(this->i2c_delay);
digitalWrite(this->scl_pin, state);
uint32_t start = millis();
if (state == HIGH)
{
while(digitalRead(this->scl_pin) == LOW)
{
if(millis() - start >= timeout)
{
return false;
}
}
}
return true;
}
void TwoWire::set_sda(bool state)
{
I2C_DELAY(this->i2c_delay);
digitalWrite(this->sda_pin, state);
}
void TwoWire::i2c_start()
{
SET_SDA(LOW);
SET_SCL(LOW);
}
void TwoWire::i2c_stop()
{
SET_SDA(LOW);
SET_SCL(HIGH);
SET_SDA(HIGH);
}
bool TwoWire::i2c_get_ack()
{
SET_SCL(LOW);
SET_SDA(HIGH);
SET_SCL(HIGH);
bool ret = !digitalRead(this->sda_pin);
SET_SCL(LOW);
return ret;
}
void TwoWire::i2c_send_ack()
{
SET_SDA(LOW);
SET_SCL(HIGH);
SET_SCL(LOW);
}
void TwoWire::i2c_send_nack()
{
SET_SDA(HIGH);
SET_SCL(HIGH);
SET_SCL(LOW);
}
uint8_t TwoWire::i2c_shift_in()
{
uint8_t data = 0;
SET_SDA(HIGH);
int i;
for (i = 0; i < 8; i++)
{
SET_SCL(HIGH);
data |= digitalRead(this->sda_pin) << (7 - i);
SET_SCL(LOW);
}
return data;
}
void TwoWire::i2c_shift_out(uint8_t val)
{
int i;
for (i = 0; i < 8; i++)
{
set_sda(!!(val & (1 << (7 - i)) ) );
SET_SCL(HIGH);
SET_SCL(LOW);
}
}
uint8_t TwoWire::process(void)
{
itc_msg.xferred = 0;
uint8_t sla_addr = (itc_msg.addr << 1);
if (itc_msg.flags == I2C_MSG_READ)
{
sla_addr |= I2C_READ;
}
i2c_start();
// shift out the address we're transmitting to
i2c_shift_out(sla_addr);
if (!i2c_get_ack())
{
i2c_stop();// Roger Clark. 20141110 added to set clock high again, as it will be left in a low state otherwise
return ENACKADDR;
}
// Recieving
if (itc_msg.flags == I2C_MSG_READ)
{
while (itc_msg.xferred < itc_msg.length)
{
itc_msg.data[itc_msg.xferred++] = i2c_shift_in();
if (itc_msg.xferred < itc_msg.length)
{
i2c_send_ack();
}
else
{
i2c_send_nack();
}
}
}
// Sending
else
{
for (uint8_t i = 0; i < itc_msg.length; i++)
{
i2c_shift_out(itc_msg.data[i]);
if (!i2c_get_ack())
{
i2c_stop();// Roger Clark. 20141110 added to set clock high again, as it will be left in a low state otherwise
return ENACKTRNS;
}
itc_msg.xferred++;
}
}
i2c_stop();
return SUCCESS;
}
// Declare the instance that the users of the library can use
TwoWire Wire(WIRE_SCL_PIN, WIRE_SDA_PIN, WIRE_DELAY);

131
cores/arduino/Wire.h Normal file
View File

@@ -0,0 +1,131 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file Wire.h
* @author Trystan Jones <crenn6977@gmail.com>
* @brief Wire library, uses the WireBase to create the primary interface
* while keeping low level interactions invisible to the user.
*/
/*
* Library updated by crenn to follow new Wire system.
* Code was derived from the original Wire for maple code by leaflabs and the
* modifications by gke and ala42.
*/
#ifndef _WIRE_H_
#define _WIRE_H_
#include "WireBase.h"
/*
* On the Maple, let the default pins be in the same location as the Arduino
* pins
*/
class TwoWire : public WireBase
{
public:
/*
* Accept pin numbers for SCL and SDA lines. Set the delay needed
* to create the timing for I2C's Standard Mode and Fast Mode.
*/
TwoWire(uint8_t scl, uint8_t sda, uint8_t delay);
/*
* If object is destroyed, set pin numbers to 0.
*/
virtual ~TwoWire();
/*
* Sets pins SDA and SCL to OUPTUT_OPEN_DRAIN, joining I2C bus as
* master. This function overwrites the default behaviour of
* .begin(uint8_t) in WireBase
*/
bool begin(uint8_t self_addr = 0x00);
public:
uint8_t i2c_delay;
uint8_t scl_pin;
uint8_t sda_pin;
/*
* Sets the SCL line to HIGH/LOW and allow for clock stretching by slave
* devices
*/
void set_scl(bool state);
bool set_scl(bool state, uint32_t timeout);
/*
* Sets the SDA line to HIGH/LOW
*/
void set_sda(bool state);
/*
* Creates a Start condition on the bus
*/
void i2c_start();
/*
* Creates a Stop condition on the bus
*/
void i2c_stop();
/*
* Gets an ACK condition from a slave device on the bus
*/
bool i2c_get_ack();
/*
* Creates a ACK condition on the bus
*/
void i2c_send_ack();
/*
* Creates a NACK condition on the bus
*/
void i2c_send_nack();
/*
* Shifts in the data through SDA and clocks SCL for the slave device
*/
uint8_t i2c_shift_in();
/*
* Shifts out the data through SDA and clocks SCL for the slave device
*/
void i2c_shift_out(uint8_t val);
protected:
/*
* Processes the incoming I2C message defined by WireBase
*/
virtual uint8_t process();
};
extern TwoWire Wire;
#endif // _WIRE_H_

166
cores/arduino/WireBase.cpp Normal file
View File

@@ -0,0 +1,166 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file WireBase.cpp
* @author Trystan Jones <crenn6977@gmail.com>
* @brief Wire library, following the majority of the interface from Arduino.
* Provides a 'standard' interface to I2C (two-wire) communication for
* derived classes.
*/
/*
* Library created by crenn to allow a system which would provide users the
* 'standardised' Arduino method for interfacing with I2C devices regardless of
* whether it is I2C hardware or emulating software.
*/
#include "WireBase.h"
void WireBase::begin(uint8_t self_addr)
{
tx_buf_idx = 0;
tx_buf_overflow = false;
rx_buf_idx = 0;
rx_buf_len = 0;
}
void WireBase::setClock(uint32_t clock)
{
}
void WireBase::beginTransmission(uint8_t slave_address)
{
itc_msg.addr = slave_address;
itc_msg.data = &tx_buf[tx_buf_idx];
itc_msg.length = 0;
itc_msg.flags = 0;
}
void WireBase::beginTransmission(int slave_address)
{
beginTransmission((uint8_t)slave_address);
}
uint8_t WireBase::endTransmission(void)
{
uint8_t retVal;
if (tx_buf_overflow)
{
return EDATA;
}
retVal = process();// Changed so that the return value from process is returned by this function see also the return line below
tx_buf_idx = 0;
tx_buf_overflow = false;
return retVal;//SUCCESS;
}
//TODO: Add the ability to queue messages (adding a boolean to end of function
// call, allows for the Arduino style to stay while also giving the flexibility
// to bulk send
uint8_t WireBase::requestFrom(uint8_t address, int num_bytes)
{
if (num_bytes > WIRE_BUFF_SIZE)
{
num_bytes = WIRE_BUFF_SIZE;
}
itc_msg.addr = address;
itc_msg.flags = I2C_MSG_READ;
itc_msg.length = num_bytes;
itc_msg.data = &rx_buf[rx_buf_idx];
process();
rx_buf_len += itc_msg.xferred;
itc_msg.flags = 0;
return rx_buf_len;
}
uint8_t WireBase::requestFrom(int address, int numBytes)
{
return WireBase::requestFrom((uint8_t)address, numBytes);
}
void WireBase::write(uint8_t value)
{
if (tx_buf_idx == WIRE_BUFF_SIZE)
{
tx_buf_overflow = true;
return;
}
tx_buf[tx_buf_idx++] = value;
itc_msg.length++;
}
void WireBase::write(uint8_t* buf, int len)
{
for (int i = 0; i < len; i++)
{
write(buf[i]);
}
}
void WireBase::write(int value)
{
write((uint8_t)value);
}
void WireBase::write(int* buf, int len)
{
write((uint8_t*)buf, (uint8_t)len);
}
void WireBase::write(char* buf)
{
uint8_t *ptr = (uint8_t*)buf;
while (*ptr)
{
write(*ptr);
ptr++;
}
}
uint8_t WireBase::available()
{
return rx_buf_len - rx_buf_idx;
}
uint8_t WireBase::read()
{
if (rx_buf_idx == rx_buf_len)
{
rx_buf_idx = 0;
rx_buf_len = 0;
return 0;
}
else if (rx_buf_idx == (rx_buf_len - 1))
{
uint8_t temp = rx_buf[rx_buf_idx];
rx_buf_idx = 0;
rx_buf_len = 0;
return temp;
}
return rx_buf[rx_buf_idx++];
}

172
cores/arduino/WireBase.h Normal file
View File

@@ -0,0 +1,172 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file WireBase.h
* @author Trystan Jones <crenn6977@gmail.com>
* @brief Wire library, following the majority of the interface from Arduino.
* Provides a 'standard' interface to I2C (two-wire) communication for
* derived classes.
*/
/*
* Library created by crenn to allow a system which would provide users the
* 'standardised' Arduino method for interfacing with I2C devices regardless of
* whether it is I2C hardware or emulating software.
*/
#ifndef _WIREBASE_H_
#define _WIREBASE_H_
#include "Arduino.h"
#ifndef WIRE_BUFF_SIZE
# define WIRE_BUFF_SIZE 32
#endif
/* return codes from endTransmission() */
#define SUCCESS 0 /* transmission was successful */
#define EDATA 1 /* too much data */
#define ENACKADDR 2 /* received nack on transmit of address */
#define ENACKTRNS 3 /* received nack on transmit of data */
#define EOTHER 4 /* other error */
struct i2c_msg;
typedef struct i2c_msg
{
uint16_t addr; /**< Address */
#define I2C_MSG_READ 0x1
#define I2C_MSG_10BIT_ADDR 0x2
/**
* Bitwise OR of:
* - I2C_MSG_READ (write is default)
* - I2C_MSG_10BIT_ADDR (7-bit is default) */
uint16_t flags;
uint16_t length; /**< Message length */
uint16_t xferred; /**< Messages transferred */
uint8_t *data; /**< Data */
} i2c_msg;
class WireBase // Abstraction is awesome!
{
protected:
i2c_msg itc_msg;
uint8_t rx_buf[WIRE_BUFF_SIZE]; /* receive buffer */
uint8_t rx_buf_idx; /* first unread idx in rx_buf */
uint8_t rx_buf_len; /* number of bytes read */
uint8_t tx_buf[WIRE_BUFF_SIZE]; /* transmit buffer */
uint8_t tx_buf_idx; // next idx available in tx_buf, -1 overflow
boolean tx_buf_overflow;
// Force derived classes to define process function
virtual uint8_t process() = 0;
public:
WireBase() {}
virtual ~WireBase() {}
/*
* Initialises the class interface
*/
// Allow derived classes to overwrite begin function
void begin(uint8_t = 0x00);
void setClock(uint32_t);
/*
* Sets up the transmission message to be processed
*/
void beginTransmission(uint8_t);
/*
* Allow only 8 bit addresses to be used
*/
void beginTransmission(int);
/*
* Call the process function to process the message if the TX
* buffer has not overflowed.
*/
uint8_t endTransmission(void);
inline uint8_t endTransmission(uint8_t)
{
return endTransmission();
}
/*
* Request bytes from a slave device and process the request,
* storing into the receiving buffer.
*/
uint8_t requestFrom(uint8_t, int);
/*
* Allow only 8 bit addresses to be used when requesting bytes
*/
uint8_t requestFrom(int, int);
/*
* Stack up bytes to be sent when transmitting
*/
void write(uint8_t);
/*
* Stack up bytes from the array to be sent when transmitting
*/
void write(uint8_t*, int);
/*
* Ensure that a sending data will only be 8-bit bytes
*/
void write(int);
/*
* Ensure that an array sending data will only be 8-bit bytes
*/
void write(int*, int);
/*
* Stack up bytes from a string to be sent when transmitting
*/
void write(char*);
/*
* Return the amount of bytes that is currently in the receiving buffer
*/
uint8_t available();
/*
* Return the value of byte in the receiving buffer that is currently being
* pointed to
*/
uint8_t read();
};
#endif // _WIREBASE_H_

View File

View File

@@ -0,0 +1,44 @@
#ifndef __PGMSPACE_H_
#define __PGMSPACE_H_ 1
#include <inttypes.h>
#define PROGMEM
#define PGM_P const char *
#define PSTR(str) (str)
#define _SFR_BYTE(n) (n)
typedef void prog_void;
typedef char prog_char;
typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t;
#define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
#define strcpy_P(dest, src) strcpy((dest), (src))
#define strcat_P(dest, src) strcat((dest), (src))
#define strcmp_P(a, b) strcmp((a), (b))
#define strstr_P(a, b) strstr((a), (b))
#define strlen_P(a) strlen((a))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr)
#endif

534
cores/arduino/binary.h Normal file
View File

@@ -0,0 +1,534 @@
/*
binary.h - Definitions for binary constants
Copyright (c) 2006 David A. Mellis. All right reserved.
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
*/
#ifndef Binary_h
#define Binary_h
#define B0 0
#define B00 0
#define B000 0
#define B0000 0
#define B00000 0
#define B000000 0
#define B0000000 0
#define B00000000 0
#define B1 1
#define B01 1
#define B001 1
#define B0001 1
#define B00001 1
#define B000001 1
#define B0000001 1
#define B00000001 1
#define B10 2
#define B010 2
#define B0010 2
#define B00010 2
#define B000010 2
#define B0000010 2
#define B00000010 2
#define B11 3
#define B011 3
#define B0011 3
#define B00011 3
#define B000011 3
#define B0000011 3
#define B00000011 3
#define B100 4
#define B0100 4
#define B00100 4
#define B000100 4
#define B0000100 4
#define B00000100 4
#define B101 5
#define B0101 5
#define B00101 5
#define B000101 5
#define B0000101 5
#define B00000101 5
#define B110 6
#define B0110 6
#define B00110 6
#define B000110 6
#define B0000110 6
#define B00000110 6
#define B111 7
#define B0111 7
#define B00111 7
#define B000111 7
#define B0000111 7
#define B00000111 7
#define B1000 8
#define B01000 8
#define B001000 8
#define B0001000 8
#define B00001000 8
#define B1001 9
#define B01001 9
#define B001001 9
#define B0001001 9
#define B00001001 9
#define B1010 10
#define B01010 10
#define B001010 10
#define B0001010 10
#define B00001010 10
#define B1011 11
#define B01011 11
#define B001011 11
#define B0001011 11
#define B00001011 11
#define B1100 12
#define B01100 12
#define B001100 12
#define B0001100 12
#define B00001100 12
#define B1101 13
#define B01101 13
#define B001101 13
#define B0001101 13
#define B00001101 13
#define B1110 14
#define B01110 14
#define B001110 14
#define B0001110 14
#define B00001110 14
#define B1111 15
#define B01111 15
#define B001111 15
#define B0001111 15
#define B00001111 15
#define B10000 16
#define B010000 16
#define B0010000 16
#define B00010000 16
#define B10001 17
#define B010001 17
#define B0010001 17
#define B00010001 17
#define B10010 18
#define B010010 18
#define B0010010 18
#define B00010010 18
#define B10011 19
#define B010011 19
#define B0010011 19
#define B00010011 19
#define B10100 20
#define B010100 20
#define B0010100 20
#define B00010100 20
#define B10101 21
#define B010101 21
#define B0010101 21
#define B00010101 21
#define B10110 22
#define B010110 22
#define B0010110 22
#define B00010110 22
#define B10111 23
#define B010111 23
#define B0010111 23
#define B00010111 23
#define B11000 24
#define B011000 24
#define B0011000 24
#define B00011000 24
#define B11001 25
#define B011001 25
#define B0011001 25
#define B00011001 25
#define B11010 26
#define B011010 26
#define B0011010 26
#define B00011010 26
#define B11011 27
#define B011011 27
#define B0011011 27
#define B00011011 27
#define B11100 28
#define B011100 28
#define B0011100 28
#define B00011100 28
#define B11101 29
#define B011101 29
#define B0011101 29
#define B00011101 29
#define B11110 30
#define B011110 30
#define B0011110 30
#define B00011110 30
#define B11111 31
#define B011111 31
#define B0011111 31
#define B00011111 31
#define B100000 32
#define B0100000 32
#define B00100000 32
#define B100001 33
#define B0100001 33
#define B00100001 33
#define B100010 34
#define B0100010 34
#define B00100010 34
#define B100011 35
#define B0100011 35
#define B00100011 35
#define B100100 36
#define B0100100 36
#define B00100100 36
#define B100101 37
#define B0100101 37
#define B00100101 37
#define B100110 38
#define B0100110 38
#define B00100110 38
#define B100111 39
#define B0100111 39
#define B00100111 39
#define B101000 40
#define B0101000 40
#define B00101000 40
#define B101001 41
#define B0101001 41
#define B00101001 41
#define B101010 42
#define B0101010 42
#define B00101010 42
#define B101011 43
#define B0101011 43
#define B00101011 43
#define B101100 44
#define B0101100 44
#define B00101100 44
#define B101101 45
#define B0101101 45
#define B00101101 45
#define B101110 46
#define B0101110 46
#define B00101110 46
#define B101111 47
#define B0101111 47
#define B00101111 47
#define B110000 48
#define B0110000 48
#define B00110000 48
#define B110001 49
#define B0110001 49
#define B00110001 49
#define B110010 50
#define B0110010 50
#define B00110010 50
#define B110011 51
#define B0110011 51
#define B00110011 51
#define B110100 52
#define B0110100 52
#define B00110100 52
#define B110101 53
#define B0110101 53
#define B00110101 53
#define B110110 54
#define B0110110 54
#define B00110110 54
#define B110111 55
#define B0110111 55
#define B00110111 55
#define B111000 56
#define B0111000 56
#define B00111000 56
#define B111001 57
#define B0111001 57
#define B00111001 57
#define B111010 58
#define B0111010 58
#define B00111010 58
#define B111011 59
#define B0111011 59
#define B00111011 59
#define B111100 60
#define B0111100 60
#define B00111100 60
#define B111101 61
#define B0111101 61
#define B00111101 61
#define B111110 62
#define B0111110 62
#define B00111110 62
#define B111111 63
#define B0111111 63
#define B00111111 63
#define B1000000 64
#define B01000000 64
#define B1000001 65
#define B01000001 65
#define B1000010 66
#define B01000010 66
#define B1000011 67
#define B01000011 67
#define B1000100 68
#define B01000100 68
#define B1000101 69
#define B01000101 69
#define B1000110 70
#define B01000110 70
#define B1000111 71
#define B01000111 71
#define B1001000 72
#define B01001000 72
#define B1001001 73
#define B01001001 73
#define B1001010 74
#define B01001010 74
#define B1001011 75
#define B01001011 75
#define B1001100 76
#define B01001100 76
#define B1001101 77
#define B01001101 77
#define B1001110 78
#define B01001110 78
#define B1001111 79
#define B01001111 79
#define B1010000 80
#define B01010000 80
#define B1010001 81
#define B01010001 81
#define B1010010 82
#define B01010010 82
#define B1010011 83
#define B01010011 83
#define B1010100 84
#define B01010100 84
#define B1010101 85
#define B01010101 85
#define B1010110 86
#define B01010110 86
#define B1010111 87
#define B01010111 87
#define B1011000 88
#define B01011000 88
#define B1011001 89
#define B01011001 89
#define B1011010 90
#define B01011010 90
#define B1011011 91
#define B01011011 91
#define B1011100 92
#define B01011100 92
#define B1011101 93
#define B01011101 93
#define B1011110 94
#define B01011110 94
#define B1011111 95
#define B01011111 95
#define B1100000 96
#define B01100000 96
#define B1100001 97
#define B01100001 97
#define B1100010 98
#define B01100010 98
#define B1100011 99
#define B01100011 99
#define B1100100 100
#define B01100100 100
#define B1100101 101
#define B01100101 101
#define B1100110 102
#define B01100110 102
#define B1100111 103
#define B01100111 103
#define B1101000 104
#define B01101000 104
#define B1101001 105
#define B01101001 105
#define B1101010 106
#define B01101010 106
#define B1101011 107
#define B01101011 107
#define B1101100 108
#define B01101100 108
#define B1101101 109
#define B01101101 109
#define B1101110 110
#define B01101110 110
#define B1101111 111
#define B01101111 111
#define B1110000 112
#define B01110000 112
#define B1110001 113
#define B01110001 113
#define B1110010 114
#define B01110010 114
#define B1110011 115
#define B01110011 115
#define B1110100 116
#define B01110100 116
#define B1110101 117
#define B01110101 117
#define B1110110 118
#define B01110110 118
#define B1110111 119
#define B01110111 119
#define B1111000 120
#define B01111000 120
#define B1111001 121
#define B01111001 121
#define B1111010 122
#define B01111010 122
#define B1111011 123
#define B01111011 123
#define B1111100 124
#define B01111100 124
#define B1111101 125
#define B01111101 125
#define B1111110 126
#define B01111110 126
#define B1111111 127
#define B01111111 127
#define B10000000 128
#define B10000001 129
#define B10000010 130
#define B10000011 131
#define B10000100 132
#define B10000101 133
#define B10000110 134
#define B10000111 135
#define B10001000 136
#define B10001001 137
#define B10001010 138
#define B10001011 139
#define B10001100 140
#define B10001101 141
#define B10001110 142
#define B10001111 143
#define B10010000 144
#define B10010001 145
#define B10010010 146
#define B10010011 147
#define B10010100 148
#define B10010101 149
#define B10010110 150
#define B10010111 151
#define B10011000 152
#define B10011001 153
#define B10011010 154
#define B10011011 155
#define B10011100 156
#define B10011101 157
#define B10011110 158
#define B10011111 159
#define B10100000 160
#define B10100001 161
#define B10100010 162
#define B10100011 163
#define B10100100 164
#define B10100101 165
#define B10100110 166
#define B10100111 167
#define B10101000 168
#define B10101001 169
#define B10101010 170
#define B10101011 171
#define B10101100 172
#define B10101101 173
#define B10101110 174
#define B10101111 175
#define B10110000 176
#define B10110001 177
#define B10110010 178
#define B10110011 179
#define B10110100 180
#define B10110101 181
#define B10110110 182
#define B10110111 183
#define B10111000 184
#define B10111001 185
#define B10111010 186
#define B10111011 187
#define B10111100 188
#define B10111101 189
#define B10111110 190
#define B10111111 191
#define B11000000 192
#define B11000001 193
#define B11000010 194
#define B11000011 195
#define B11000100 196
#define B11000101 197
#define B11000110 198
#define B11000111 199
#define B11001000 200
#define B11001001 201
#define B11001010 202
#define B11001011 203
#define B11001100 204
#define B11001101 205
#define B11001110 206
#define B11001111 207
#define B11010000 208
#define B11010001 209
#define B11010010 210
#define B11010011 211
#define B11010100 212
#define B11010101 213
#define B11010110 214
#define B11010111 215
#define B11011000 216
#define B11011001 217
#define B11011010 218
#define B11011011 219
#define B11011100 220
#define B11011101 221
#define B11011110 222
#define B11011111 223
#define B11100000 224
#define B11100001 225
#define B11100010 226
#define B11100011 227
#define B11100100 228
#define B11100101 229
#define B11100110 230
#define B11100111 231
#define B11101000 232
#define B11101001 233
#define B11101010 234
#define B11101011 235
#define B11101100 236
#define B11101101 237
#define B11101110 238
#define B11101111 239
#define B11110000 240
#define B11110001 241
#define B11110010 242
#define B11110011 243
#define B11110100 244
#define B11110101 245
#define B11110110 246
#define B11110111 247
#define B11111000 248
#define B11111001 249
#define B11111010 250
#define B11111011 251
#define B11111100 252
#define B11111101 253
#define B11111110 254
#define B11111111 255
#endif

37
cores/arduino/dtostrf.c Normal file
View File

@@ -0,0 +1,37 @@
/*
dtostrf - Emulation for dtostrf function from avr-libc
Copyright (c) 2013 Arduino. All rights reserved.
Written by Cristian Maglie <c.maglie@bug.st>
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
*/
#include "dtostrf.h"
char *dtostrf(double val, signed char width, unsigned char prec, char *sout)
{
char fmt[20];
snprintf(fmt, sizeof(fmt), "%%%d.%df", width, prec);
sprintf(sout, fmt, val);
return sout;
}
char *dtostrnf(double val, signed char width, unsigned char prec, char *sout, size_t sout_size)
{
char fmt[20];
snprintf(fmt, sizeof(fmt), "%%%d.%df", width, prec);
snprintf(sout, sout_size, fmt, val);
return sout;
}

37
cores/arduino/dtostrf.h Normal file
View File

@@ -0,0 +1,37 @@
/*
dtostrf - Emulation for dtostrf function from avr-libc
Copyright (c) 2013 Arduino. All rights reserved.
Written by Cristian Maglie <c.maglie@bug.st>
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
*/
#ifndef __DTOSTRF_H
#define __DTOSTRF_H
#include "stdio.h"
#ifdef __cplusplus
extern "C" {
#endif
char *dtostrf(double val, signed char width, unsigned char prec, char *sout);
char *dtostrnf(double val, signed char width, unsigned char prec, char *sout, size_t sout_size);
#ifdef __cplusplus
}
#endif
#endif

164
cores/arduino/itoa.c Normal file
View File

@@ -0,0 +1,164 @@
/*
Copyright (c) 2011 Arduino. All right reserved.
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
*/
#include "itoa.h"
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#if 0
/* reverse: reverse string s in place */
static void reverse(char s[])
{
int i, j ;
char c ;
for (i = 0, j = strlen(s) - 1 ; i < j ; i++, j--) {
c = s[i] ;
s[i] = s[j] ;
s[j] = c ;
}
}
/* itoa: convert n to characters in s */
extern void itoa(int n, char s[])
{
int i, sign ;
if ((sign = n) < 0) { /* record sign */
n = -n; /* make n positive */
}
i = 0;
do {
/* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0) ; /* delete it */
if (sign < 0) {
s[i++] = '-';
}
s[i] = '\0';
reverse(s) ;
}
#else
extern char *itoa(int value, char *string, int radix)
{
return ltoa(value, string, radix) ;
}
extern char *ltoa(long value, char *string, int radix)
{
char tmp[33];
char *tp = tmp;
long i;
unsigned long v;
int sign;
char *sp;
if (string == NULL) {
return 0 ;
}
if (radix > 36 || radix <= 1) {
return 0 ;
}
sign = (radix == 10 && value < 0);
if (sign) {
v = -value;
} else {
v = (unsigned long)value;
}
while (v || tp == tmp) {
i = v % radix;
v = v / radix;
if (i < 10) {
*tp++ = i + '0';
} else {
*tp++ = i + 'a' - 10;
}
}
sp = string;
if (sign) {
*sp++ = '-';
}
while (tp > tmp) {
*sp++ = *--tp;
}
*sp = 0;
return string;
}
#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 9 || \
(__GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ > 2)))
extern char *utoa(unsigned value, char *string, int radix)
#else
extern char *utoa(unsigned long value, char *string, int radix)
#endif
{
return ultoa(value, string, radix) ;
}
extern char *ultoa(unsigned long value, char *string, int radix)
{
char tmp[33];
char *tp = tmp;
long i;
unsigned long v = value;
char *sp;
if (string == NULL) {
return 0;
}
if (radix > 36 || radix <= 1) {
return 0;
}
while (v || tp == tmp) {
i = v % radix;
v = v / radix;
if (i < 10) {
*tp++ = i + '0';
} else {
*tp++ = i + 'a' - 10;
}
}
sp = string;
while (tp > tmp) {
*sp++ = *--tp;
}
*sp = 0;
return string;
}
#endif /* 0 */
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

44
cores/arduino/itoa.h Normal file
View File

@@ -0,0 +1,44 @@
/*
Copyright (c) 2011 Arduino. All right reserved.
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
*/
#ifndef _ITOA_
#define _ITOA_
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#if 0
extern void itoa(int n, char s[]) ;
#else
extern char *itoa(int value, char *string, int radix) ;
extern char *ltoa(long value, char *string, int radix) ;
#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 9 || \
(__GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ > 2)))
extern char *utoa(unsigned value, char *string, int radix) ;
#else
extern char *utoa(unsigned long value, char *string, int radix) ;
#endif
extern char *ultoa(unsigned long value, char *string, int radix) ;
#endif /* 0 */
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // _ITOA_

View File

@@ -0,0 +1,294 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "Arduino.h"
/**
* @brief 配置引脚输入输出模式
* @param pin: 引脚编号
* @param PinMode_x: 模式
* @retval 无
*/
void pinMode(uint8_t pin, PinMode_TypeDef mode)
{
if(!IS_PIN(pin))
{
return;
}
if(mode == INPUT_ANALOG_DMA)
{
if(!IS_ADC_PIN(pin))
{
return;
}
pinMode(pin, INPUT_ANALOG);
ADC_DMA_Register(PIN_MAP[pin].ADC_Channel);
}
else if(mode == PWM)
{
PWM_Init(pin, PWM_RESOLUTION_DEFAULT, PWM_FREQUENCY_DEFAULT);
}
else
{
GPIOx_Init(
PIN_MAP[pin].GPIOx,
PIN_MAP[pin].GPIO_Pin_x,
mode,
GPIO_DRIVE_DEFAULT
);
}
}
/**
* @brief 将数字HIGH(1)或LOW(0)值写入数字引脚
* @param pin:引脚编号
* @param value: 写入值
* @retval 无
*/
void digitalWrite(uint8_t pin, uint8_t value)
{
if(!IS_PIN(pin))
{
return;
}
value ? digitalWrite_HIGH(pin) : digitalWrite_LOW(pin);
}
/**
* @brief 读取引脚电平
* @param pin: 引脚编号
* @retval 引脚电平
*/
uint8_t digitalRead(uint8_t pin)
{
if(!IS_PIN(pin))
{
return 0;
}
return digitalRead_FAST(pin);
}
/**
* @brief 将模拟值(PWM占空比)写入引脚
* @param pin: 引脚编号
* @param value: PWM占空比
* @retval 无
*/
void analogWrite(uint8_t pin, uint16_t value)
{
if(!IS_PWM_PIN(pin))
{
return;
}
PWM_Write(pin, value);
}
/**
* @brief 从指定的模拟引脚读取值
* @param pin: 引脚编号
* @retval ADC值0~4095
*/
uint16_t analogRead(uint8_t pin)
{
if(!IS_ADC_PIN(pin))
{
return 0;
}
return ADCx_GetValue(PIN_MAP[pin].ADCx, PIN_MAP[pin].ADC_Channel);
}
/**
* @brief 从指定的引脚读取值(DMA方式)
* @param pin: 引脚编号
* @retval ADC值0~4095
*/
uint16_t analogRead_DMA(uint8_t pin)
{
if(!IS_ADC_PIN(pin))
{
return 0;
}
return ADC_DMA_GetValue(PIN_MAP[pin].ADC_Channel);
}
/**
* @brief 一次移出一个字节的数据,从最左端或最小(最右边)开始
* @param dataPin: 输出每个位的 pin
* @param clockPin: 将 dataPin 设置为正确值后要切换的 pin (int)
* @param bitOrder: MSBFIRST / LSBFIRST
* @param value: 要移出的数据(字节)
* @retval 无
*/
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value)
{
uint8_t i;
if(!(IS_PIN(dataPin) && IS_PIN(clockPin)))
{
return;
}
digitalWrite_LOW(clockPin);
for (i = 0; i < 8; i++)
{
int bit = bitOrder == LSBFIRST ? i : (7 - i);
digitalWrite(dataPin, (value >> bit) & 0x1);
togglePin(clockPin);
togglePin(clockPin);
}
}
/**
* @brief 一次将一个字节的数据移位,从最左端或最小 (最右边) 开始
* @param dataPin: 输入每个位的 pin
* @param clockPin: 要切换到的 pin 信号从dataPin读取
* @param bitOrder: MSBFIRST/LSBFIRST
* @retval 读取的值 (字节)
*/
uint32_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint32_t bitOrder)
{
uint8_t value = 0;
uint8_t i;
if(!(IS_PIN(dataPin) && IS_PIN(clockPin)))
{
return 0;
}
for (i = 0; i < 8; ++i)
{
digitalWrite_HIGH(clockPin);
if (bitOrder == LSBFIRST )
{
value |= digitalRead(dataPin) << i;
}
else
{
value |= digitalRead(dataPin) << (7 - i);
}
digitalWrite_LOW(clockPin);
}
return value;
}
/**
* @brief 在引脚上读取脉冲
* @param pin: 要读取脉冲的引脚编号
* @param value: 脉冲类型:高或低
* @param timeout: 等待脉冲开始的微秒数
* @retval 脉冲的长度(以微秒计)或0, 如果没有脉冲在超时之前开始
*/
uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout)
{
// cache the IDR address and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling
// digitalRead() instead yields much coarser resolution.
volatile uint32_t *idr = portInputRegister(digitalPinToPort(pin));
const uint32_t bit = digitalPinToBitMask(pin);
const uint32_t stateMask = (state ? bit : 0);
uint32_t width = 0; // keep initialization out of time critical area
// convert the timeout from microseconds to a number of times through
// the initial loop; it takes 16 clock cycles per iteration.
uint32_t numloops = 0;
uint32_t maxloops = timeout * ( F_CPU / 16000000);
volatile uint32_t dummyWidth = 0;
if(!IS_PIN(pin))
return 0;
// wait for any previous pulse to end
while ((*idr & bit) == stateMask)
{
if (numloops++ == maxloops)
{
return 0;
}
dummyWidth++;
}
// wait for the pulse to start
while ((*idr & bit) != stateMask)
{
if (numloops++ == maxloops)
{
return 0;
}
dummyWidth++;
}
// wait for the pulse to stop
while ((*idr & bit) == stateMask)
{
if (numloops++ == maxloops)
{
return 0;
}
width++;
}
// Excluding time taking up by the interrupts, it needs 16 clock cycles to look through the last while loop
// 5 is added as a fiddle factor to correct for interrupts etc. But ultimately this would only be accurate if it was done ona hardware timer
return (uint32_t)( ( (unsigned long long)(width + 5) * (unsigned long long) 16000000.0) / (unsigned long long)F_CPU );
}
/**
* @brief 将一个数字(整形)从一个范围重新映射到另一个区域
* @param x: 要映射的数字
* @param in_min: 值的当前范围的下界
* @param in_max: 值的当前范围的上界
* @param out_min: 值的目标范围的下界
* @param out_max: 值目标范围的上界
* @retval 映射的值(long)
*/
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
/**
* @brief 将一个数字(浮点型)从一个范围重新映射到另一个区域
* @param x: 要映射的数字
* @param in_min: 值的当前范围的下界
* @param in_max: 值的当前范围的上界
* @param out_min: 值的目标范围的下界
* @param out_max: 值目标范围的上界
* @retval 映射的值(double)
*/
float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void yield(void)
{
}

255
cores/arduino/libcore/adc.c Normal file
View File

@@ -0,0 +1,255 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "adc.h"
#include <stdbool.h>
#define ADC_DMA_REGMAX 18
#define IS_ADC_CHANNEL(channel) (channel <= ADC_CHANNEL_17)
/*引脚注册个数*/
static uint8_t ADC_DMA_RegCnt = 0;
/*ADC通道注册列表*/
static uint8_t ADC_DMA_RegChannelList[ADC_DMA_REGMAX] = {0};
/*ADC DMA缓存数组*/
static uint16_t ADC_DMA_ConvertedValue[ADC_DMA_REGMAX] = {0};
/**
* @brief 搜索注册列表找出ADC通道对应的索引号
* @param ADC_Channel:ADC通道号
* @retval ADC通道注册列表对应索引号-1:未找到对应通道号
*/
static int16_t ADC_DMA_SearchChannel(uint16_t ADC_Channel)
{
uint8_t index;
for(index = 0; index < ADC_DMA_RegCnt; index++)
{
if(ADC_Channel == ADC_DMA_RegChannelList[index])
{
return index;
}
}
return -1;
}
/**
* @brief ADC 配置
* @param ADCx: ADC地址
* @retval 无
*/
void ADCx_Init(adc_type* ADCx)
{
adc_base_config_type adc_base_struct;
if(ADCx == ADC1)
{
crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
}
else if(ADCx == ADC2)
{
crm_periph_clock_enable(CRM_ADC2_PERIPH_CLOCK, TRUE);
}
#ifdef ADC3
else if(ADCx == ADC3)
{
crm_periph_clock_enable(CRM_ADC3_PERIPH_CLOCK, TRUE);
}
#endif
else
{
return;
}
crm_adc_clock_div_set(CRM_ADC_DIV_8);
adc_combine_mode_select(ADC_INDEPENDENT_MODE);
adc_base_default_para_init(&adc_base_struct);
adc_base_struct.sequence_mode = FALSE;
adc_base_struct.repeat_mode = FALSE;
adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
adc_base_struct.ordinary_channel_length = 1;
adc_base_config(ADCx, &adc_base_struct);
if (ADCx != ADC3)
adc_ordinary_conversion_trigger_set(ADCx, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
else
adc_ordinary_conversion_trigger_set(ADCx, ADC3_ORDINARY_TRIG_SOFTWARE, TRUE);
adc_enable(ADCx, TRUE);
adc_calibration_init(ADCx);
while(adc_calibration_init_status_get(ADCx));
adc_calibration_start(ADCx);
while(adc_calibration_status_get(ADCx));
}
/**
* @brief 获取 ADC 值
* @param ADCx: ADC地址
* @param ADC_Channel: ADC通道
* @retval 无
*/
uint16_t ADCx_GetValue(adc_type* ADCx, uint16_t ADC_Channel)
{
adc_ordinary_channel_set(ADCx, (adc_channel_select_type)ADC_Channel, 1, ADC_SAMPLETIME_41_5);
adc_ordinary_software_trigger_enable(ADCx, TRUE);
while(!adc_flag_get(ADCx, ADC_CCE_FLAG));
return adc_ordinary_conversion_data_get(ADCx);
}
/**
* @brief 注册需要DMA搬运的ADC通道
* @param ADC_Channel:ADC通道号
* @retval 见ADC_DMA_Res_Type
*/
ADC_DMA_Res_Type ADC_DMA_Register(uint8_t ADC_Channel)
{
/*初始化ADC通道列表*/
static bool isInit = false;
if(!isInit)
{
uint8_t i;
for(i = 0; i < ADC_DMA_REGMAX; i++)
{
ADC_DMA_RegChannelList[i] = 0xFF;
}
isInit = true;
}
/*是否是合法ADC通道*/
if(!IS_ADC_CHANNEL(ADC_Channel))
return ADC_DMA_RES_NOT_ADC_CHANNEL;
/*是否已在引脚列表重复注册*/
if(ADC_DMA_SearchChannel(ADC_Channel) != -1)
return ADC_DMA_RES_DUPLICATE_REGISTRATION;
/*是否超出最大注册个数*/
if(ADC_DMA_RegCnt >= ADC_DMA_REGMAX)
return ADC_DMA_RES_MAX_NUM_OF_REGISTRATIONS_EXCEEDED;
/*写入注册列表*/
ADC_DMA_RegChannelList[ADC_DMA_RegCnt] = ADC_Channel;
/*注册个数+1*/
ADC_DMA_RegCnt++;
return ADC_DMA_RES_OK;
}
/**
* @brief 获取已注册的ADC DMA通道数量
* @param 无
* @retval ADC DMA通道数量
*/
uint8_t ADC_DMA_GetRegisterCount(void)
{
return ADC_DMA_RegCnt;
}
/**
* @brief ADC DMA 配置
* @param 无
* @retval 无
*/
void ADC_DMA_Init(void)
{
dma_init_type dma_init_structure;
adc_base_config_type adc_base_struct;
uint8_t index;
crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
dma_reset(DMA1_CHANNEL1);
dma_default_para_init(&dma_init_structure);
dma_init_structure.buffer_size = ADC_DMA_RegCnt;
dma_init_structure.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
dma_init_structure.memory_base_addr = (uint32_t)ADC_DMA_ConvertedValue;
dma_init_structure.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD;
dma_init_structure.memory_inc_enable = TRUE;
dma_init_structure.peripheral_base_addr = (uint32_t) (&(ADC1->odt));
dma_init_structure.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
dma_init_structure.peripheral_inc_enable = FALSE;
dma_init_structure.priority = DMA_PRIORITY_HIGH;
dma_init_structure.loop_mode_enable = TRUE;
dma_init(DMA1_CHANNEL1, &dma_init_structure);
adc_combine_mode_select(ADC_INDEPENDENT_MODE);
adc_base_default_para_init(&adc_base_struct);
adc_base_struct.sequence_mode = FALSE;
adc_base_struct.repeat_mode = FALSE;
adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
adc_base_struct.ordinary_channel_length = 1;
adc_base_config(ADC1, &adc_base_struct);
adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
crm_adc_clock_div_set(CRM_ADC_DIV_8);
for(index = 0; index < ADC_DMA_RegCnt; index++)
{
adc_ordinary_channel_set(
ADC1,
ADC_DMA_RegChannelList[index],
index + 1,
ADC_SAMPLETIME_41_5
);
if(ADC_DMA_RegChannelList[index] == ADC_CHANNEL_16)
{
adc_tempersensor_vintrv_enable(true);
}
}
adc_dma_mode_enable(ADC1, TRUE);
adc_enable(ADC1, TRUE);
adc_calibration_init(ADC1);
while(adc_calibration_init_status_get(ADC1));
adc_calibration_start(ADC1);
while(adc_calibration_status_get(ADC1));
}
/**
* @brief 获取DMA搬运的ADC值
* @param ADC_Channel:ADC通道号
* @retval ADC值
*/
uint16_t ADC_DMA_GetValue(uint8_t ADC_Channel)
{
int16_t index;
if(!IS_ADC_CHANNEL(ADC_Channel))
return 0;
index = ADC_DMA_SearchChannel(ADC_Channel);
if(index == -1)
return 0;
return ADC_DMA_ConvertedValue[index];
}

View File

@@ -0,0 +1,51 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __ADC_H
#define __ADC_H
#include "mcu_type.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
ADC_DMA_RES_OK = 0,
ADC_DMA_RES_NOT_ADC_CHANNEL = -1,
ADC_DMA_RES_DUPLICATE_REGISTRATION = -2,
ADC_DMA_RES_MAX_NUM_OF_REGISTRATIONS_EXCEEDED = -3,
} ADC_DMA_Res_Type;
void ADCx_Init(adc_type* ADCx);
uint16_t ADCx_GetValue(adc_type* ADCx, uint16_t ADC_Channel);
void ADC_DMA_Init(void);
ADC_DMA_Res_Type ADC_DMA_Register(uint8_t ADC_Channel);
uint16_t ADC_DMA_GetValue(uint8_t ADC_Channel);
uint8_t ADC_DMA_GetRegisterCount(void);
#ifdef __cplusplus
}
#endif
#endif /* __ADC_H */

View File

@@ -0,0 +1,105 @@
/**
**************************************************************************
* @file at32f403a_407_clock.c
* @version v2.0.9
* @date 2022-04-25
* @brief system clock config program
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
/* includes ------------------------------------------------------------------*/
#include "at32f403a_407_clock.h"
/**
* @brief system clock config program
* @note the system clock is configured as follow:
* - system clock = hext / 2 * pll_mult
* - system clock source = pll (hext)
* - hext = 8000000
* - sclk = 240000000
* - ahbdiv = 1
* - ahbclk = 240000000
* - apb2div = 2
* - apb2clk = 120000000
* - apb1div = 2
* - apb1clk = 120000000
* - pll_mult = 60
* - pll_range = GT72MHZ (greater than 72 mhz)
* @param none
* @retval none
*/
void system_clock_config(void)
{
/* reset crm */
crm_reset();
#if F_PLL_CLOCK_SOURCE != 0
crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);
/* wait till hext is ready */
while(crm_hext_stable_wait() == ERROR)
{
}
#endif
/* config pll clock resource */
crm_pll_config(F_PLL_CLOCK_SOURCE, F_PLL_MULT, F_PLL_OUTPUT_RANGE);
#if F_PLL_CLOCK_SOURCE == 2
/* config hext division */
crm_hext_clock_div_set(F_HEXT_DIV);
#elif F_PLL_CLOCK_SOURCE == 1
crm_hick_divider_select(F_HSI_DIV);
#endif
/* enable pll */
crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
/* wait till pll is ready */
while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
{
}
/* config ahbclk */
crm_ahb_div_set(CRM_AHB_DIV_1);
/* config apb2clk */
crm_apb2_div_set(CRM_APB2_DIV_2);
/* config apb1clk */
crm_apb1_div_set(CRM_APB1_DIV_2);
/* enable auto step mode */
crm_auto_step_mode_enable(TRUE);
/* select pll as system clock source */
crm_sysclk_switch(CRM_SCLK_PLL);
/* wait till pll is used as system clock source */
while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
{
}
/* disable auto step mode */
crm_auto_step_mode_enable(FALSE);
/* update system_core_clock global variable */
system_core_clock_update();
}

View File

@@ -0,0 +1,46 @@
/**
**************************************************************************
* @file at32f403a_407_clock.h
* @version v2.0.9
* @date 2022-04-25
* @brief header file of clock program
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __AT32F403A_407_CLOCK_H
#define __AT32F403A_407_CLOCK_H
#ifdef __cplusplus
extern "C" {
#endif
/* includes ------------------------------------------------------------------*/
#include "at32f403a_407.h"
/* exported functions ------------------------------------------------------- */
void system_clock_config(void);
#ifdef __cplusplus
}
#endif
#endif /* __AT32F403A_407_CLOCK_H */

View File

@@ -0,0 +1,112 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __MCU_CONFIG_H
#define __MCU_CONFIG_H
/*=========================
MCU configuration
*=========================*/
/* System tick */
#define SYSTICK_TICK_FREQ 1000 // Hz
#define SYSTICK_PRIORITY 0
/* Hardware Serial */
#define SERIAL_RX_BUFFER_SIZE 128
#define SERIAL_PREEMPTIONPRIORITY_DEFAULT 1
#define SERIAL_SUBPRIORITY_DEFAULT 3
#define SERIAL_CONFIG_DEFAULT SERIAL_8N1
#define SERIAL_1_ENABLE 1
#if SERIAL_1_ENABLE
# define SERIAL_1_USART USART1
# define SERIAL_1_IRQ_HANDLER_DEF() void USART1_IRQHandler(void)
#endif
#define SERIAL_2_ENABLE 1
#if SERIAL_2_ENABLE
# define SERIAL_2_USART USART2
# define SERIAL_2_IRQ_HANDLER_DEF() void USART2_IRQHandler(void)
#endif
#define SERIAL_3_ENABLE 1
#if SERIAL_3_ENABLE
# define SERIAL_3_USART USART3
# define SERIAL_3_IRQ_HANDLER_DEF() void USART3_IRQHandler(void)
#endif
/* Wire (Software I2C) */
#define WIRE_USE_FULL_SPEED_I2C 0
#define WIRE_SDA_PIN PB7
#define WIRE_SCL_PIN PB6
#define WIRE_DELAY 0
#define WIRE_BEGIN_TIMEOUT 100 // ms
#define WIRE_BUFF_SIZE 32
/* SPI Class */
#define SPI_CLASS_AVR_COMPATIBILITY_MODE 1
#define SPI_CLASS_PIN_DEFINE_ENABLE 1
#define SPI_CLASS_1_ENABLE 1
#if SPI_CLASS_1_ENABLE
# define SPI_CLASS_1_SPI SPI1
#endif
#define SPI_CLASS_2_ENABLE 1
#if SPI_CLASS_2_ENABLE
# define SPI_CLASS_2_SPI SPI2
#endif
#define SPI_CLASS_3_ENABLE 1
#if SPI_CLASS_3_ENABLE
# define SPI_CLASS_3_SPI SPI3
#endif
/* WString */
#define WSTRING_MEM_INCLUDE <stdlib.h>
#define WSTRING_MEM_REALLOC realloc
#define WSTRING_MEM_FREE free
/* Print */
#define PRINT_PRINTF_BUFFER_LENGTH 128
/* GPIO */
#define GPIO_DRIVE_DEFAULT GPIO_DRIVE_STRENGTH_STRONGER
/* External Interrupt */
#define EXTI_PREEMPTIONPRIORITY_DEFAULT 2
#define EXTI_SUBPRIORITY_DEFAULT 1
/* Timer Interrupt */
#define TIMER_PREEMPTIONPRIORITY_DEFAULT 0
#define TIMER_SUBPRIORITY_DEFAULT 3
/* Tone */
#define TONE_TIMER_DEFAULT TIM1
#define TONE_PREEMPTIONPRIORITY_DEFAULT 0
#define TONE_SUBPRIORITY_DEFAULT 1
/* PWM */
#define PWM_RESOLUTION_DEFAULT 1000
#define PWM_FREQUENCY_DEFAULT 10000
#endif

View File

@@ -0,0 +1,121 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "delay.h"
#ifndef SYSTICK_TICK_FREQ
# define SYSTICK_TICK_FREQ 1000 // Hz
#endif
#define SYSTICK_TICK_INTERVAL (1000 / SYSTICK_TICK_FREQ)
#define SYSTICK_LOAD_VALUE (system_core_clock / SYSTICK_TICK_FREQ)
#define SYSTICK_MILLIS (SystemTickCount * SYSTICK_TICK_INTERVAL)
static volatile uint32_t SystemTickCount = 0;
/**
* @brief 系统滴答定时器初始化定时1ms
* @param 无
* @retval 无
*/
void Delay_Init(void)
{
system_core_clock_update();
SysTick_Config(SYSTICK_LOAD_VALUE);
NVIC_SetPriority(SysTick_IRQn, SYSTICK_PRIORITY);
}
/**
* @brief 系统滴答定时器中断入口
* @param 无
* @retval 无
*/
void SysTick_Handler(void)
{
SystemTickCount++;
}
/**
* @brief 获取单片机自上电以来经过的毫秒数
* @param 无
* @retval 当前系统时钟毫秒数
*/
uint32_t millis(void)
{
return SYSTICK_MILLIS;
}
/**
* @brief 获取单片机自上电以来经过的微秒数
* @param 无
* @retval 当前系统时钟微秒数
*/
uint32_t micros(void)
{
return (SYSTICK_MILLIS * 1000 + (SYSTICK_LOAD_VALUE - SysTick->VAL) / CYCLES_PER_MICROSECOND);
}
/**
* @brief 毫秒级延时
* @param ms: 要延时的毫秒数
* @retval 无
*/
void delay_ms(uint32_t ms)
{
uint32_t tickstart = SystemTickCount;
uint32_t wait = ms / SYSTICK_TICK_INTERVAL;
while((SystemTickCount - tickstart) < wait)
{
}
}
/**
* @brief 微秒级延时
* @param us: 要延时的微秒数
* @retval 无
*/
void delay_us(uint32_t us)
{
uint32_t total = 0;
uint32_t target = CYCLES_PER_MICROSECOND * us;
int last = SysTick->VAL;
int now = last;
int diff = 0;
start:
now = SysTick->VAL;
diff = last - now;
if(diff > 0)
{
total += diff;
}
else
{
total += diff + SYSTICK_LOAD_VALUE;
}
if(total > target)
{
return;
}
last = now;
goto start;
}

View File

@@ -0,0 +1,42 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __DELAY_H
#define __DELAY_H
#include "mcu_type.h"
#ifdef __cplusplus
extern "C" {
#endif
void Delay_Init(void);
uint32_t millis(void);
uint32_t micros(void);
void delay_ms(uint32_t ms);
void delay_us(uint32_t us);
#ifdef __cplusplus
}
#endif
#endif /* __DELAY_H */

View File

@@ -0,0 +1,103 @@
/**
******************************************************************************
* File : SRAM/extend_SRAM/EXTEND_SRAM/extend_SRAM.c
* Version: V1.2.7
* Date : 2020-11-10
* Brief : This file contains the function extend_SRAM_test used to extend SRAM size
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "extend_SRAM.h"
#include "at32f403a_407.h"
#define EXTEND_SRAM_224K
/* Copy to Startup file */
#if 0
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
IMPORT extend_SRAM
MOV32 R0, #0x20001000
MOV SP, R0
LDR R0, =extend_SRAM
BLX R0
MOV32 R0, #0x08000000
LDR SP, [R0]
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
#endif
/** @addtogroup AT32F403A_StdPeriph_Examples
* @{
*/
/** @addtogroup SRAM_Extended_SRAM
* @{
*/
/* Private typedef -----------------------------------------------------------*/
#define TEST_RAM_SIZE 0x800
/* Private variables ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief To extend SRAM size
* @param None
* @retval None
*/
void extend_sram(void)
{
/* Target set_SRAM_96K is selected */
#ifdef EXTEND_SRAM_96K
/* check if RAM has been set to 96K, if not, change EOPB0 */
if(((UOPTB->EOPB0)&0xFF)!=0xFF)
{
/* Unlock Option Bytes Program Erase controller */
FLASH_Unlock();
/* Erase Option Bytes */
FLASH_EraseUserOptionBytes();
/* Change SRAM size to 96KB */
FLASH_ProgramUserOptionByteData((uint32_t)&UOPTB->EOPB0,0xFF);
NVIC_SystemReset();
}
#endif
/* Target set_SRAM_224K is selected */
#ifdef EXTEND_SRAM_224K
/* check if ram has been set to expectant size, if not, change eopb0 */
if(((USD->eopb0) & 0xFF) != 0xFE)
{
flash_unlock();
/* erase user system data bytes */
flash_user_system_data_erase();
/* change sram size */
flash_user_system_data_program((uint32_t)&USD->eopb0, 0xFE);
/* system reset */
nvic_system_reset();
}
#endif
}
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,18 @@
/**
******************************************************************************
* File : SRAM/extend_SRAM/EXTEND_SRAM/extend_SRAM.h
* Version: V1.2.7
* Date : 2020-11-10
* Brief : This file contains all the macros used in extend_SRAM.c
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __EXTEND_SRAM_H
#define __EXTEND_SRAM_H
/* Exported functions ------------------------------------------------------- */
void extend_sram(void);
#endif /* __EXTEND_SRAM_H */

View File

@@ -0,0 +1,235 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "exti.h"
#include "gpio.h"
#define EXTI_GetPortSourceGPIOx(Pin) GPIO_GetPortNum(Pin)
#define EXTI_GetPinSourcex(Pin) GPIO_GetPinNum(Pin)
static EXTI_CallbackFunction_t EXTI_Function[16] = {0};
/**
* @brief 获取外部中断的中断通道
* @param Pin: 引脚编号
* @retval 通道编号
*/
static IRQn_Type EXTI_GetIRQn(uint8_t Pin)
{
IRQn_Type EXINTx_IRQn = EXINT0_IRQn;
uint8_t Pinx = GPIO_GetPinNum(Pin);
if(Pinx <= 4)
{
switch(Pinx)
{
case 0:
EXINTx_IRQn = EXINT0_IRQn;
break;
case 1:
EXINTx_IRQn = EXINT1_IRQn;
break;
case 2:
EXINTx_IRQn = EXINT2_IRQn;
break;
case 3:
EXINTx_IRQn = EXINT3_IRQn;
break;
case 4:
EXINTx_IRQn = EXINT4_IRQn;
break;
}
}
else if(Pinx >= 5 && Pinx <= 9)
{
EXINTx_IRQn = EXINT9_5_IRQn;
}
else if(Pinx >= 10 && Pinx <= 15)
{
EXINTx_IRQn = EXINT15_10_IRQn;
}
return EXINTx_IRQn;
}
/**
* @brief 外部中断初始化
* @param Pin: 引脚编号
* @param Function: 回调函数
* @param Trigger_Mode: 触发方式
* @param PreemptionPriority: 抢占优先级
* @param SubPriority: 子优先级
* @retval 无
*/
void EXTIx_Init(
uint8_t Pin,
EXTI_CallbackFunction_t Function,
exint_polarity_config_type line_polarity,
uint8_t PreemptionPriority,
uint8_t SubPriority
)
{
exint_init_type exint_init_struct;
uint8_t Pinx;
if(!IS_PIN(Pin))
return;
Pinx = GPIO_GetPinNum(Pin);
if(Pinx > 15)
return;
EXTI_Function[Pinx] = Function;
crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
gpio_exint_line_config(GPIO_GetPortNum(Pin), (gpio_pins_source_type)Pinx);
exint_default_para_init(&exint_init_struct);
exint_init_struct.line_select = 1 << Pinx;
exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
exint_init_struct.line_polarity = line_polarity;
exint_init_struct.line_enable = TRUE;
exint_init(&exint_init_struct);
nvic_irq_enable(EXTI_GetIRQn(Pin), PreemptionPriority, SubPriority);
}
/**
* @brief 外部中断初始化 (Arduino)
* @param Pin: 引脚编号
* @param function: 回调函数
* @param Trigger_Mode: 触发方式
* @retval 无
*/
void attachInterrupt(uint8_t Pin, EXTI_CallbackFunction_t Function, exint_polarity_config_type line_polarity)
{
EXTIx_Init(
Pin,
Function,
line_polarity,
EXTI_PREEMPTIONPRIORITY_DEFAULT,
EXTI_SUBPRIORITY_DEFAULT
);
}
/**
* @brief 关闭给定的中断 (Arduino)
* @param Pin: 引脚编号
* @retval 无
*/
void detachInterrupt(uint8_t Pin)
{
if(!IS_PIN(Pin))
return;
nvic_irq_disable(EXTI_GetIRQn(Pin));
}
#define EXTIx_IRQHANDLER(n) \
do{\
if(exint_flag_get(EXINT_LINE_##n) != RESET)\
{\
if(EXTI_Function[n]) EXTI_Function[n]();\
exint_flag_clear(EXINT_LINE_##n);\
}\
}while(0)
/**
* @brief 外部中断入口通道0
* @param 无
* @retval 无
*/
void EXTI0_IRQHandler(void)
{
EXTIx_IRQHANDLER(0);
}
/**
* @brief 外部中断入口通道1
* @param 无
* @retval 无
*/
void EXTI1_IRQHandler(void)
{
EXTIx_IRQHANDLER(1);
}
/**
* @brief 外部中断入口通道2
* @param 无
* @retval 无
*/
void EXTI2_IRQHandler(void)
{
EXTIx_IRQHANDLER(2);
}
/**
* @brief 外部中断入口通道3
* @param 无
* @retval 无
*/
void EXTI3_IRQHandler(void)
{
EXTIx_IRQHANDLER(3);
}
/**
* @brief 外部中断入口通道4
* @param 无
* @retval 无
*/
void EXTI4_IRQHandler(void)
{
EXTIx_IRQHANDLER(4);
}
/**
* @brief 外部中断入口通道9~5
* @param 无
* @retval 无
*/
void EXTI9_5_IRQHandler(void)
{
EXTIx_IRQHANDLER(5);
EXTIx_IRQHANDLER(6);
EXTIx_IRQHANDLER(7);
EXTIx_IRQHANDLER(8);
EXTIx_IRQHANDLER(9);
}
/**
* @brief 外部中断入口通道15~10
* @param 无
* @retval 无
*/
void EXTI15_10_IRQHandler(void)
{
EXTIx_IRQHANDLER(10);
EXTIx_IRQHANDLER(11);
EXTIx_IRQHANDLER(12);
EXTIx_IRQHANDLER(13);
EXTIx_IRQHANDLER(14);
EXTIx_IRQHANDLER(15);
}

View File

@@ -0,0 +1,56 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __EXTI_H
#define __EXTI_H
#include "mcu_type.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CHANGE EXINT_TRIGGER_BOTH_EDGE
#define FALLING EXINT_TRIGGER_FALLING_EDGE
#define RISING EXINT_TRIGGER_RISING_EDGE
typedef void(*EXTI_CallbackFunction_t)(void);
void EXTIx_Init(
uint8_t Pin,
EXTI_CallbackFunction_t Function,
exint_polarity_config_type line_polarity,
uint8_t PreemptionPriority,
uint8_t SubPriority
);
void attachInterrupt(
uint8_t Pin,
EXTI_CallbackFunction_t Function,
exint_polarity_config_type polarity_config
);
void detachInterrupt(uint8_t Pin);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,341 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "gpio.h"
const PinInfo_TypeDef PIN_MAP[PIN_MAX] =
{
/*GPIO_Type* GPIOx; //对应GPIOx地址
TIM_Type* TIMx; //对应TIMx地址
ADC_Type* ADCx; //对应ADCx地址
uint16_t GPIO_Pin_x; //对应GPIO_Pin位
uint8_t TimerChannel; //对应定时器通道
uint8_t ADC_CHANNEL;*/ //对应ADC通道
{GPIOA, TIM2, ADC1, GPIO_Pin_0, 1, ADC_CHANNEL_0}, /* PA0 */
{GPIOA, TIM2, ADC1, GPIO_Pin_1, 2, ADC_CHANNEL_1}, /* PA1 */
{GPIOA, TIM2, ADC1, GPIO_Pin_2, 3, ADC_CHANNEL_2}, /* PA2 */
{GPIOA, TIM2, ADC1, GPIO_Pin_3, 4, ADC_CHANNEL_3}, /* PA3 */
{GPIOA, NULL, ADC1, GPIO_Pin_4, 0, ADC_CHANNEL_4}, /* PA4 */
{GPIOA, NULL, ADC1, GPIO_Pin_5, 0, ADC_CHANNEL_5}, /* PA5 */
{GPIOA, TIM3, ADC1, GPIO_Pin_6, 1, ADC_CHANNEL_6}, /* PA6 */
{GPIOA, TIM3, ADC1, GPIO_Pin_7, 2, ADC_CHANNEL_7}, /* PA7 */
{GPIOA, TIM1, NULL, GPIO_Pin_8, 1, ADC_CHANNEL_X}, /* PA8 */
{GPIOA, TIM1, NULL, GPIO_Pin_9, 2, ADC_CHANNEL_X}, /* PA9 */
{GPIOA, TIM1, NULL, GPIO_Pin_10, 3, ADC_CHANNEL_X}, /* PA10 */
{GPIOA, TIM1, NULL, GPIO_Pin_11, 4, ADC_CHANNEL_X}, /* PA11 */
{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 */
{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, 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_12, 0, ADC_CHANNEL_X}, /* PB12 */
{GPIOB, NULL, NULL, GPIO_Pin_13, 0, ADC_CHANNEL_X}, /* PB13 */
#ifdef TMR12
{GPIOB, TIM12, NULL, GPIO_Pin_14, 1, ADC_CHANNEL_X},/* PB14 */
#else
{GPIOB, NULL, NULL, GPIO_Pin_14, 0, ADC_Channel_X},/* PB14 */
#endif /*TMR12*/
{GPIOB, NULL, NULL, GPIO_Pin_15, 0, ADC_CHANNEL_X}, /* PB15 */
{GPIOC, NULL, ADC1, GPIO_Pin_0, 0, ADC_CHANNEL_10},/* PC0 */
{GPIOC, NULL, ADC1, GPIO_Pin_1, 0, ADC_CHANNEL_11},/* PC1 */
{GPIOC, NULL, ADC1, GPIO_Pin_2, 0, ADC_CHANNEL_12},/* PC2 */
{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_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 */
{GPIOC, NULL, NULL, GPIO_Pin_13, 0, ADC_CHANNEL_X}, /* PC13 */
{GPIOC, NULL, NULL, GPIO_Pin_14, 0, ADC_CHANNEL_X}, /* PC14 */
{GPIOC, NULL, NULL, GPIO_Pin_15, 0, ADC_CHANNEL_X}, /* PC15 */
{GPIOD, NULL, NULL, GPIO_Pin_0, 0, ADC_CHANNEL_X}, /* PD0 */
{GPIOD, NULL, NULL, GPIO_Pin_1, 0, ADC_CHANNEL_X}, /* PD1 */
{GPIOD, NULL, NULL, GPIO_Pin_2, 0, ADC_CHANNEL_X}, /* PD2 */
{GPIOD, NULL, NULL, GPIO_Pin_3, 0, ADC_CHANNEL_X}, /* PD3 */
{GPIOD, NULL, NULL, GPIO_Pin_4, 0, ADC_CHANNEL_X}, /* PD4 */
{GPIOD, NULL, NULL, GPIO_Pin_5, 0, ADC_CHANNEL_X}, /* PD5 */
{GPIOD, NULL, NULL, GPIO_Pin_6, 0, ADC_CHANNEL_X}, /* PD6 */
{GPIOD, NULL, NULL, GPIO_Pin_7, 0, ADC_CHANNEL_X}, /* PD7 */
{GPIOD, NULL, NULL, GPIO_Pin_8, 0, ADC_CHANNEL_X}, /* PD8 */
{GPIOD, NULL, NULL, GPIO_Pin_9, 0, ADC_CHANNEL_X}, /* PD9 */
{GPIOD, NULL, NULL, GPIO_Pin_10, 0, ADC_CHANNEL_X}, /* PD10 */
{GPIOD, NULL, NULL, GPIO_Pin_11, 0, ADC_CHANNEL_X}, /* PD11 */
{GPIOD, TIM4, NULL, GPIO_Pin_12, 1, ADC_CHANNEL_X}, /* PD12 */
{GPIOD, TIM4, NULL, GPIO_Pin_13, 2, ADC_CHANNEL_X}, /* PD13 */
{GPIOD, TIM4, NULL, GPIO_Pin_14, 3, ADC_CHANNEL_X}, /* PD14 */
{GPIOD, TIM4, NULL, GPIO_Pin_15, 4, ADC_CHANNEL_X}, /* PD15 */
#ifdef GPIOE
{GPIOE, NULL, NULL, GPIO_Pin_0, 0, ADC_CHANNEL_X}, /* PE0 */
{GPIOE, NULL, NULL, GPIO_Pin_1, 0, ADC_CHANNEL_X}, /* PE1 */
{GPIOE, NULL, NULL, GPIO_Pin_2, 0, ADC_CHANNEL_X}, /* PE2 */
{GPIOE, NULL, NULL, GPIO_Pin_3, 0, ADC_CHANNEL_X}, /* PE3 */
{GPIOE, NULL, NULL, GPIO_Pin_4, 0, ADC_CHANNEL_X}, /* PE4 */
{GPIOE, TIM9, NULL, GPIO_Pin_5, 1, ADC_CHANNEL_X}, /* PE5 */
{GPIOE, TIM9, NULL, GPIO_Pin_6, 2, ADC_CHANNEL_X}, /* PE6 */
{GPIOE, NULL, NULL, GPIO_Pin_7, 0, ADC_CHANNEL_X}, /* PE7 */
{GPIOE, NULL, NULL, GPIO_Pin_8, 0, ADC_CHANNEL_X}, /* PE8 */
{GPIOE, TIM1, NULL, GPIO_Pin_9, 1, ADC_CHANNEL_X}, /* PE9 */
{GPIOE, NULL, NULL, GPIO_Pin_10, 0, ADC_CHANNEL_X}, /* PE10 */
{GPIOE, TIM1, NULL, GPIO_Pin_11, 2, ADC_CHANNEL_X}, /* PE11 */
{GPIOE, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PE12 */
{GPIOE, TIM1, NULL, GPIO_Pin_13, 3, ADC_CHANNEL_X}, /* PE13 */
{GPIOE, TIM1, NULL, GPIO_Pin_14, 4, ADC_CHANNEL_X}, /* PE14 */
{GPIOE, NULL, NULL, GPIO_Pin_15, 0, ADC_CHANNEL_X}, /* PE15 */
#endif /*GPIOE*/
#ifdef GPIOF
{GPIOF, NULL, NULL, GPIO_Pin_0, 0, ADC_CHANNEL_X}, /* PF0 */
{GPIOF, NULL, NULL, GPIO_Pin_1, 0, ADC_CHANNEL_X}, /* PF1 */
{GPIOF, NULL, NULL, GPIO_Pin_2, 0, ADC_CHANNEL_X}, /* PF2 */
#ifdef ADC3
{GPIOF, NULL, ADC3, GPIO_Pin_3, 0, ADC_CHANNEL_9}, /* PF3 */
{GPIOF, NULL, ADC3, GPIO_Pin_4, 0, ADC_CHANNEL_14},/* PF4 */
{GPIOF, NULL, ADC3, GPIO_Pin_5, 0, ADC_CHANNEL_15},/* PF5 */
{GPIOF, TIM10, ADC3, GPIO_Pin_6, 1, ADC_CHANNEL_4}, /* PF6 */
{GPIOF, TIM11, ADC3, GPIO_Pin_7, 1, ADC_CHANNEL_5}, /* PF7 */
{GPIOF, TIM13, ADC3, GPIO_Pin_8, 1, ADC_CHANNEL_6}, /* PF8 */
{GPIOF, TIM14, ADC3, GPIO_Pin_9, 1, ADC_CHANNEL_7}, /* PF9 */
{GPIOF, NULL, ADC3, GPIO_Pin_10, 0, ADC_CHANNEL_8}, /* PF10 */
#else
{GPIOF, NULL, NULL, GPIO_Pin_3, 0, ADC_CHANNEL_X}, /* PF3 */
{GPIOF, NULL, NULL, GPIO_Pin_4, 0, ADC_CHANNEL_X},/* PF4 */
{GPIOF, NULL, NULL, GPIO_Pin_5, 0, ADC_CHANNEL_X},/* PF5 */
{GPIOF, TIM10, NULL, GPIO_Pin_6, 1, ADC_CHANNEL_X}, /* PF6 */
{GPIOF, TIM11, NULL, GPIO_Pin_7, 1, ADC_CHANNEL_X}, /* PF7 */
{GPIOF, NULL, NULL, GPIO_Pin_8, 0, ADC_CHANNEL_X}, /* PF8 */
{GPIOF, NULL, NULL, GPIO_Pin_9, 0, ADC_CHANNEL_X}, /* PF9 */
{GPIOF, NULL, NULL, GPIO_Pin_10, 0, ADC_CHANNEL_X}, /* PF10 */
#endif /*ADC3*/
{GPIOF, NULL, NULL, GPIO_Pin_11, 0, ADC_CHANNEL_X}, /* PF11 */
{GPIOF, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PF12 */
{GPIOF, NULL, NULL, GPIO_Pin_13, 0, ADC_CHANNEL_X}, /* PF13 */
{GPIOF, NULL, NULL, GPIO_Pin_14, 0, ADC_CHANNEL_X}, /* PF14 */
{GPIOF, NULL, NULL, GPIO_Pin_15, 0, ADC_CHANNEL_X}, /* PF15 */
#endif /*GPIOF*/
#ifdef GPIOG
{GPIOG, NULL, NULL, GPIO_Pin_0, 0, ADC_CHANNEL_X}, /* PG0 */
{GPIOG, NULL, NULL, GPIO_Pin_1, 0, ADC_CHANNEL_X}, /* PG1 */
{GPIOG, NULL, NULL, GPIO_Pin_2, 0, ADC_CHANNEL_X}, /* PG2 */
{GPIOG, NULL, NULL, GPIO_Pin_3, 0, ADC_CHANNEL_X}, /* PG3 */
{GPIOG, NULL, NULL, GPIO_Pin_4, 0, ADC_CHANNEL_X}, /* PG4 */
{GPIOG, NULL, NULL, GPIO_Pin_5, 0, ADC_CHANNEL_X}, /* PG5 */
{GPIOG, NULL, NULL, GPIO_Pin_6, 0, ADC_CHANNEL_X}, /* PG6 */
{GPIOG, NULL, NULL, GPIO_Pin_7, 0, ADC_CHANNEL_X}, /* PG7 */
{GPIOG, NULL, NULL, GPIO_Pin_8, 0, ADC_CHANNEL_X}, /* PG8 */
{GPIOG, NULL, NULL, GPIO_Pin_9, 0, ADC_CHANNEL_X}, /* PG9 */
{GPIOG, NULL, NULL, GPIO_Pin_10, 0, ADC_CHANNEL_X}, /* PG10 */
{GPIOG, NULL, NULL, GPIO_Pin_11, 0, ADC_CHANNEL_X}, /* PG11 */
{GPIOG, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PG12 */
{GPIOG, NULL, NULL, GPIO_Pin_13, 0, ADC_CHANNEL_X}, /* PG13 */
{GPIOG, NULL, NULL, GPIO_Pin_14, 0, ADC_CHANNEL_X}, /* PG14 */
{GPIOG, NULL, NULL, GPIO_Pin_15, 0, ADC_CHANNEL_X}, /* PG15 */
#endif /*GPIOG*/
};
/**
* @brief GPIO初始化
* @param GPIOx: GPIO地址
* @param GPIO_Pin_x: GPIO对应位
* @param GPIO_Mode_x: GPIO模式
* @param GPIO_Speed_x: GPIO速度
* @retval 无
*/
void GPIOx_Init(
gpio_type* GPIOx,
uint16_t GPIO_Pin_x,
PinMode_TypeDef Mode,
gpio_drive_type GPIO_Drive_x
)
{
gpio_init_type gpio_init_struct;
crm_periph_clock_type CRM_GPIOx_PERIPH_CLOCK;
if(GPIOx == GPIOA) CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOA_PERIPH_CLOCK;
else if(GPIOx == GPIOB)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOB_PERIPH_CLOCK;
else if(GPIOx == GPIOC)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOC_PERIPH_CLOCK;
else if(GPIOx == GPIOD)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOD_PERIPH_CLOCK;
#ifdef GPIOE
else if(GPIOx == GPIOE)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOE_PERIPH_CLOCK;
#endif /*GPIOE*/
#ifdef GPIOF
else if(GPIOx == GPIOF)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOF_PERIPH_CLOCK;
#endif /*GPIOF*/
#ifdef GPIOG
else if(GPIOx == GPIOG)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOG_PERIPH_CLOCK;
#endif /*GPIOG*/
else return;
gpio_default_para_init(&gpio_init_struct);
gpio_init_struct.gpio_pins = GPIO_Pin_x;
gpio_init_struct.gpio_drive_strength = GPIO_Drive_x;
if(Mode == INPUT)
{
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
}
else if(Mode == INPUT_PULLUP)
{
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
}
else if(Mode == INPUT_PULLDOWN)
{
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
}
else if(Mode == INPUT_ANALOG)
{
gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
}
else if(Mode == OUTPUT)
{
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
}
else if(Mode == OUTPUT_OPEN_DRAIN)
{
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
}
else if(Mode == OUTPUT_AF_PP)
{
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
}
else if(Mode == OUTPUT_AF_OD)
{
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
}
else
{
return;
}
crm_periph_clock_enable(CRM_GPIOx_PERIPH_CLOCK, TRUE);
gpio_init(GPIOx, &gpio_init_struct);
}
/**
* @brief 禁用JTAG引脚
* @param 无
* @retval 无
*/
void GPIO_JTAG_Disable(void)
{
// RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_AFIO, ENABLE);
// GPIO_PinsRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
}
/**
* @brief 获取当前引脚对应的GPIOx编号
* @param Pin: 引脚编号
* @retval 无
*/
uint8_t GPIO_GetPortNum(uint8_t Pin)
{
uint8_t retval = 0xFF;
uint8_t index;
gpio_type* GPIOx = PIN_MAP[Pin].GPIOx;
gpio_type* GPIO_Map[] =
{
GPIOA,
GPIOB,
GPIOC,
GPIOD,
#ifdef GPIOE
GPIOE,
#endif
#ifdef GPIOF
GPIOF,
#endif
#ifdef GPIOG
GPIOG
#endif
};
for(index = 0; index < sizeof(GPIO_Map) / sizeof(GPIO_Map[0]); index++)
{
if(GPIOx == GPIO_Map[index])
{
retval = index;
break;
}
}
return retval;
}
/**
* @brief 获取当前引脚对应的 PinSource
* @param GPIO_Pin_x: GPIO对应位
* @retval 无
*/
uint8_t GPIO_GetPinSource(uint16_t GPIO_Pin_x)
{
uint8_t PinSource = 0;
while(GPIO_Pin_x > 1)
{
GPIO_Pin_x >>= 1;
PinSource++;
}
return PinSource;
}
/**
* @brief 获取当前引脚对应的编号
* @param Pin: 引脚编号
* @retval 无
*/
uint8_t GPIO_GetPinNum(uint8_t Pin)
{
return GPIO_GetPinSource(PIN_MAP[Pin].GPIO_Pin_x);
}

View File

@@ -0,0 +1,121 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __GPIO_H
#define __GPIO_H
#include "mcu_type.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NULL
# define NULL ((void*)0)
#endif
#define ADC_CHANNEL_X ((uint8_t)0xFF)
#define IS_PIN(Pin) (Pin < PIN_MAX)
#define IS_ADC_PIN(Pin) (IS_PIN(Pin) && PIN_MAP[Pin].ADCx != NULL && PIN_MAP[Pin].ADC_Channel != ADC_CHANNEL_X)
#define IS_PWM_PIN(Pin) (IS_PIN(Pin) && PIN_MAP[Pin].TIMx != NULL && PIN_MAP[Pin].TimerChannel != 0)
#define GPIO_HIGH(GPIOX,GPIO_PIN_X) ((GPIOX)->scr = (GPIO_PIN_X))
#define GPIO_LOW(GPIOX,GPIO_PIN_X) ((GPIOX)->clr = (GPIO_PIN_X))
#define GPIO_READ(GPIOX,GPIO_PIN_X) (((GPIOX)->idt & (GPIO_PIN_X))!=0)
#define GPIO_TOGGLE(GPIOX,GPIO_PIN_X) ((GPIOX)->odt ^= (GPIO_PIN_X))
#define portInputRegister(Port) (&(Port->idt))
#define portOutputRegister(Port) (&(Port->odt))
#define analogInPinToBit(Pin) (Pin)
#define digitalPinToInterrupt(Pin) (Pin)
#define digitalPinToPort(Pin) (PIN_MAP[Pin].GPIOx)
#define digitalPinToBitMask(Pin) (PIN_MAP[Pin].GPIO_Pin_x)
#define digitalWrite_HIGH(Pin) GPIO_HIGH (PIN_MAP[Pin].GPIOx, PIN_MAP[Pin].GPIO_Pin_x)
#define digitalWrite_LOW(Pin) GPIO_LOW (PIN_MAP[Pin].GPIOx, PIN_MAP[Pin].GPIO_Pin_x)
#define digitalRead_FAST(Pin) GPIO_READ (PIN_MAP[Pin].GPIOx, PIN_MAP[Pin].GPIO_Pin_x)
#define togglePin(Pin) GPIO_TOGGLE(PIN_MAP[Pin].GPIOx, PIN_MAP[Pin].GPIO_Pin_x)
#define LED_BUILTIN PC13
typedef enum
{
PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15,
PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15,
PC0, PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10, PC11, PC12, PC13, PC14, PC15,
PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15,
#ifdef GPIOE
PE0, PE1, PE2, PE3, PE4, PE5, PE6, PE7, PE8, PE9, PE10, PE11, PE12, PE13, PE14, PE15,
#endif
#ifdef GPIOF
PF0, PF1, PF2, PF3, PF4, PF5, PF6, PF7, PF8, PF9, PF10, PF11, PF12, PF13, PF14, PF15,
#endif
#ifdef GPIOG
PG0, PG1, PG2, PG3, PG4, PG5, PG6, PG7, PG8, PG9, PG10, PG11, PG12, PG13, PG14, PG15,
#endif
PIN_MAX
} Pin_TypeDef;
typedef struct
{
gpio_type* GPIOx;
tmr_type* TIMx;
adc_type* ADCx;
uint16_t GPIO_Pin_x;
uint8_t TimerChannel;
uint8_t ADC_Channel;
} PinInfo_TypeDef;
typedef enum
{
INPUT,
INPUT_PULLUP,
INPUT_PULLDOWN,
INPUT_ANALOG,
INPUT_ANALOG_DMA,
OUTPUT,
OUTPUT_OPEN_DRAIN,
OUTPUT_AF_OD,
OUTPUT_AF_PP,
PWM
} PinMode_TypeDef;
extern const PinInfo_TypeDef PIN_MAP[PIN_MAX];
void GPIOx_Init(
gpio_type* GPIOx,
uint16_t GPIO_Pin_x,
PinMode_TypeDef Mode,
gpio_drive_type GPIO_Drive_x
);
void GPIO_JTAG_Disable(void);
uint8_t GPIO_GetPortNum(uint8_t Pin);
uint8_t GPIO_GetPinNum(uint8_t Pin);
uint8_t GPIO_GetPinSource(uint16_t GPIO_Pin_x);
#ifdef __cplusplus
}// extern "C"
#endif
#endif

158
cores/arduino/libcore/i2c.c Normal file
View File

@@ -0,0 +1,158 @@
/*
* MIT License
* Copyright (c) 2019 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "Arduino.h"
#include "i2c.h"
void I2Cx_Init(i2c_type *I2Cx, uint32_t baudRate)
{
if(I2Cx == I2C1)
{
crm_periph_clock_enable(CRM_I2C1_PERIPH_CLOCK, TRUE);
pinMode(PB6, OUTPUT_AF_OD);
pinMode(PB7, OUTPUT_AF_OD);
}
#ifdef CRM_I2C2_PERIPH_CLOCK
else if(I2Cx == I2C2)
{
crm_periph_clock_enable(CRM_I2C2_PERIPH_CLOCK, TRUE);
pinMode(PB10, OUTPUT_AF_OD);
pinMode(PB11, OUTPUT_AF_OD);
}
#endif
#ifdef CRM_I2C3_PERIPH_CLOCK
else if(I2Cx == I2C3)
{
crm_periph_clock_enable(CRM_I2C3_PERIPH_CLOCK, TRUE);
pinMode(PA8, OUTPUT_AF_OD);
pinMode(PC9, OUTPUT_AF_OD);
}
#endif
else
{
return;
}
/* reset i2c peripheral */
i2c_reset(I2Cx);
/* i2c peripheral initialization */
i2c_init(I2Cx, I2C_FSMODE_DUTY_2_1, baudRate);
i2c_own_address1_set(I2Cx, I2C_ADDRESS_MODE_7BIT, 0);
i2c_ack_enable(I2Cx, TRUE);
i2c_master_receive_ack_set(I2Cx, I2C_MASTER_ACK_CURRENT);
/* i2c peripheral enable */
i2c_enable(I2Cx, TRUE);
}
void I2Cx_ClearADDRFlag(i2c_type* I2Cx)
{
__IO uint32_t tmpreg;
tmpreg = I2Cx->sts1;
tmpreg = I2Cx->sts2;
}
void I2Cx_Read(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, void *buf, uint32_t length)
{
uint8_t *dat = (uint8_t *)buf;
/* enable ack */
i2c_ack_enable(I2Cx, TRUE);
/* generate start condtion */
i2c_start_generate(I2Cx);
while(!i2c_flag_get(I2Cx, I2C_STARTF_FLAG));
while(I2Cx->ctrl1 & I2C_CTRL1_STARTGEN);
i2c_7bit_address_send(I2Cx, (slaveAddr << 1), I2C_DIRECTION_TRANSMIT);
while(!i2c_flag_get(I2Cx, I2C_ADDR7F_FLAG));
I2Cx_ClearADDRFlag(I2Cx);
i2c_data_send(I2Cx, regAddr);
while(!i2c_flag_get(I2Cx, I2C_TDC_FLAG));
i2c_flag_clear(I2Cx, I2C_TDC_FLAG);
i2c_start_generate(I2Cx);
while(!i2c_flag_get(I2Cx, I2C_STARTF_FLAG));
i2c_7bit_address_send(I2Cx, (slaveAddr << 1), I2C_DIRECTION_RECEIVE);
while(!i2c_flag_get(I2Cx, I2C_ADDR7F_FLAG));
I2Cx_ClearADDRFlag(I2Cx);
while(length --)
{
if(!length)
{
i2c_ack_enable(I2Cx, FALSE);
i2c_stop_generate(I2Cx);
}
while(!i2c_flag_get(I2Cx, I2C_RDBF_FLAG));
*dat++ = i2c_data_receive(I2Cx);
}
while(I2Cx->ctrl1 & I2C_CTRL1_STOPGEN);
}
void I2Cx_Write(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, void *buf, uint32_t length)
{
uint8_t *dat = (uint8_t *)buf;
i2c_start_generate(I2Cx);
while(!i2c_flag_get(I2Cx, I2C_STARTF_FLAG));
i2c_7bit_address_send(I2Cx, (slaveAddr << 1), I2C_DIRECTION_TRANSMIT);
while(!i2c_flag_get(I2Cx, I2C_ADDR7F_FLAG));
I2Cx_ClearADDRFlag(I2Cx);
i2c_data_send(I2Cx, regAddr);
while(!i2c_flag_get(I2Cx, I2C_TDC_FLAG));
i2c_flag_clear(I2Cx, I2C_TDC_FLAG);
while(length --)
{
i2c_data_send(I2Cx, *dat++);
while(!i2c_flag_get(I2Cx, I2C_TDC_FLAG));
i2c_flag_clear(I2Cx, I2C_TDC_FLAG);
}
i2c_stop_generate(I2Cx);
while(I2Cx->ctrl1 & I2C_CTRL1_STOPGEN);
// while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_TDE));
// while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTFF));
}
uint8_t I2Cx_ReadReg(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr)
{
uint8_t retval = 0;
I2Cx_Read(I2Cx, slaveAddr, regAddr, &retval, sizeof(uint8_t));
return retval;
}
void I2Cx_WriteReg(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, uint8_t value)
{
I2Cx_Write(I2Cx, slaveAddr, regAddr, &value, sizeof(uint8_t));
}

View File

@@ -0,0 +1,39 @@
/*
* MIT License
* Copyright (c) 2019 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __HARDWAREI2C_H
#define __HARDWAREI2C_H
#include <stdint.h>
#include "mcu_type.h"
/* I2C START mask */
#define I2C_CTRL1_STARTGEN ((uint16_t)0x0100)
/* I2C STOP mask */
#define I2C_CTRL1_STOPGEN ((uint16_t)0x0200)
void I2Cx_Init(i2c_type *I2Cx, uint32_t baudRate);
void I2Cx_Read(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, void *buf, uint32_t length);
void I2Cx_Write(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, void *buf, uint32_t length);
uint8_t I2Cx_ReadReg(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr);
void I2Cx_WriteReg(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, uint8_t value);
#endif

View File

@@ -0,0 +1,33 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "mcu_core.h"
void Core_Init(void)
{
system_clock_config();
nvic_priority_group_config(NVIC_PRIORITY_GROUP_2);
// GPIO_JTAG_Disable();
Delay_Init();
ADCx_Init(ADC1);
}

View File

@@ -0,0 +1,49 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __MCU_CORE_H
#define __MCU_CORE_H
#include "at32f403a_407_clock.h"
#define sei() __set_PRIMASK(0)
#define cli() __set_PRIMASK(1)
#include "adc.h"
#include "delay.h"
#include "exti.h"
#include "gpio.h"
#include "pwm.h"
#include "timer.h"
#include "wdg.h"
#ifdef __cplusplus
extern "C" {
#endif
void Core_Init(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,75 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __MCU_TYPE_H
#define __MCU_TYPE_H
#include "at32f403a_407.h"
#include "at32f403a_407_conf.h"
#include "config/mcu_config.h"
#define __AT32__
#define __AT32F4__
// #define F_CPU system_core_clock
// #define F_CPU 80000000L
#define CYCLES_PER_MICROSECOND (F_CPU / 1000000U)
typedef gpio_type GPIO_TypeDef;
typedef spi_type SPI_TypeDef;
typedef tmr_type TIM_TypeDef;
#define GPIO_Pin_0 GPIO_PINS_0
#define GPIO_Pin_1 GPIO_PINS_1
#define GPIO_Pin_2 GPIO_PINS_2
#define GPIO_Pin_3 GPIO_PINS_3
#define GPIO_Pin_4 GPIO_PINS_4
#define GPIO_Pin_5 GPIO_PINS_5
#define GPIO_Pin_6 GPIO_PINS_6
#define GPIO_Pin_7 GPIO_PINS_7
#define GPIO_Pin_8 GPIO_PINS_8
#define GPIO_Pin_9 GPIO_PINS_9
#define GPIO_Pin_10 GPIO_PINS_10
#define GPIO_Pin_11 GPIO_PINS_11
#define GPIO_Pin_12 GPIO_PINS_12
#define GPIO_Pin_13 GPIO_PINS_13
#define GPIO_Pin_14 GPIO_PINS_14
#define GPIO_Pin_15 GPIO_PINS_15
#define GPIO_Pin_All GPIO_PINS_All
#define TIM1 TMR1
#define TIM2 TMR2
#define TIM3 TMR3
#define TIM4 TMR4
#define TIM5 TMR5
#define TIM6 TMR6
#define TIM7 TMR7
#define TIM8 TMR8
#define TIM9 TMR9
#define TIM10 TMR10
#define TIM11 TMR11
#define TIM12 TMR12
#define TIM13 TMR13
#define TIM14 TMR14
#define TIM15 TMR15
#endif

115
cores/arduino/libcore/pwm.c Normal file
View File

@@ -0,0 +1,115 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "pwm.h"
#include "timer.h"
#include "Arduino.h"
/**
* @brief 定时器输出捕获初始化
* @param TIMx: 定时器地址
* @param arr: 自动重装值
* @param psc: 时钟预分频数
* @param TimerChannel: 定时器通道
* @retval 无
*/
static void TIMx_OCxInit(tmr_type* TIMx, uint32_t arr, uint16_t psc, uint8_t TimerChannel)
{
tmr_output_config_type tmr_output_struct;
Timer_ClockCmd(TIMx, true);
tmr_base_init(TIMx, arr, psc);
tmr_cnt_dir_set(TIMx, TMR_COUNT_UP);
tmr_output_default_para_init(&tmr_output_struct);
tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
tmr_output_struct.oc_idle_state = TRUE;
tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
tmr_output_struct.occ_idle_state = FALSE;
tmr_output_struct.oc_output_state = TRUE;
tmr_output_struct.occ_output_state = TRUE;
switch(TimerChannel)
{
case 1:
tmr_output_channel_config(TIMx, TMR_SELECT_CHANNEL_1, &tmr_output_struct);
break;
case 2:
tmr_output_channel_config(TIMx, TMR_SELECT_CHANNEL_2, &tmr_output_struct);
break;
case 3:
tmr_output_channel_config(TIMx, TMR_SELECT_CHANNEL_3, &tmr_output_struct);
break;
case 4:
tmr_output_channel_config(TIMx, TMR_SELECT_CHANNEL_4, &tmr_output_struct);
break;
default:
return;
}
tmr_output_enable(TIMx, TRUE);
tmr_counter_enable(TIMx, TRUE);
}
/**
* @brief PWM输出初始化
* @param Pin:引脚编号
* @param Resolution: PWM分辨率
* @param Frequency: PWM频率
* @retval 引脚对应的定时器通道
*/
uint8_t PWM_Init(uint8_t Pin, uint32_t Resolution, uint32_t Frequency)
{
uint32_t arr, psc;
if(!IS_PWM_PIN(Pin))
{
return 0;
}
if(Resolution == 0 || Frequency == 0 || (Resolution * Frequency) > F_CPU)
{
return 0;
}
pinMode(Pin, OUTPUT_AF_PP);
arr = Resolution;
psc = Timer_GetClockMax(PIN_MAP[Pin].TIMx) / Resolution / Frequency;
Timer_SetEnable(PIN_MAP[Pin].TIMx, false);
TIMx_OCxInit(PIN_MAP[Pin].TIMx, arr - 1, psc - 1, PIN_MAP[Pin].TimerChannel);
return PIN_MAP[Pin].TimerChannel;
}
/**
* @brief 输出PWM信号
* @param Pin: 引脚编号
* @param Value: PWM输出值
* @retval PWM占空比值
*/
void PWM_Write(uint8_t Pin, uint32_t Value)
{
Timer_SetCompare(PIN_MAP[Pin].TIMx, PIN_MAP[Pin].TimerChannel, Value);
}

View File

@@ -0,0 +1,41 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __PWM_H
#define __PWM_H
#include "mcu_type.h"
#ifdef __cplusplus
extern "C" {
#endif
#define pwmWrite(pin, value) PWM_Write(pin, value)
uint8_t PWM_Init(uint8_t Pin, uint32_t Resolution, uint32_t Frequency);
void PWM_Write(uint8_t Pin, uint32_t Value);
#ifdef __cplusplus
}
#endif
#endif

303
cores/arduino/libcore/rtc.c Normal file
View File

@@ -0,0 +1,303 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rtc.h"
static const uint8_t table_week[12] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5}; //Monthly correction data sheet.
static const uint8_t mon_table[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //Month data table of Pingnian
/**
* @brief RTC Init.
* @param None
* @retval None
*/
void RTC_Init(void)
{
/* enable pwc and bpr clocks */
crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);
/* allow access to bpr domain */
pwc_battery_powered_domain_access(TRUE);
/* Check Backup data registers is correct*/
if (bpr_data_read(BPR_DATA1) != 0x5051)
{
/* reset backup domain */
bpr_reset();
/* enable the lick osc */
crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);
/* wait till lick is ready */
while(crm_flag_get(CRM_LICK_STABLE_FLAG) == RESET);
/* select the rtc clock source */
crm_rtc_clock_select(CRM_RTC_CLOCK_LICK);
/* enable rtc clock */
crm_rtc_clock_enable(TRUE);
/* wait for rtc registers update */
rtc_wait_update_finish();
/* wait for the register write to complete */
rtc_wait_config_finish();
/* enable the rtc second */
rtc_interrupt_enable(RTC_TS_INT, TRUE);
/* wait for the register write to complete */
rtc_wait_config_finish();
/* set rtc divider: set rtc period to 1sec */
rtc_divider_set(40000);
/* wait for the register write to complete */
rtc_wait_config_finish();
/* Set the RTC time */
RTC_SetTime(2018, 8, 8, 8, 8, 0);
/* wait for the register write to complete */
rtc_wait_config_finish();
/* Writes data to Backup Register */
bpr_data_write(BPR_DATA1, 0x5051);
}
else
{
/* wait for rtc registers update */
rtc_wait_update_finish();
/* wait for the register write to complete */
rtc_wait_config_finish();
/* Clear RTC pending flag */
rtc_flag_clear(RTC_CFGF_FLAG);
/* wait for the register write to complete */
rtc_wait_config_finish();
}
}
/**
* @brief Judeg the Leap year or Pingnian.
* Month 1 2 3 4 5 6 7 8 9 10 11 12
* Leap year 31 29 31 30 31 30 31 31 30 31 30 31
* Pingnian 31 28 31 30 31 30 31 31 30 31 30 31
* @param year
* @retval 1: Leap year
2: Pingnian
*/
static uint8_t Is_Leap_Year(uint16_t year)
{
if(year % 4 == 0)
{
if(year % 100 == 0)
{
if(year % 400 == 0) return 1;
else return 0;
}
else return 1;
}
else return 0;
}
/**
* @brief Set time. Convert the input clock to a second.
* The time basic : 1970.1.1
* legitimate year: 1970 ~ 2099
* @param syear: Year
* smon : Month
* sday : Day
* hour
* min
* sec
* @retval 0: Set time right.
* 1: Set time failed.
*/
uint8_t RTC_SetTime(uint16_t syear, uint8_t smon, uint8_t sday, uint8_t hour, uint8_t min, uint8_t sec)
{
uint32_t t;
uint32_t seccount = 0;
if(syear < 1970 || syear > 2099)
return 1;
for(t = 1970; t < syear; t++)
{
if(Is_Leap_Year(t))seccount += 31622400;
else seccount += 31536000;
}
smon -= 1;
for(t = 0; t < smon; t++)
{
seccount += (uint8_t)mon_table[t] * 86400;
if(Is_Leap_Year(syear) && t == 1)seccount += 86400;
}
seccount += (uint8_t)(sday - 1) * 86400;
seccount += (uint8_t)hour * 3600;
seccount += (uint8_t)min * 60;
seccount += sec;
/* enable pwc and bpr clocks */
crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);
/* allow access to bpr domain */
pwc_battery_powered_domain_access(TRUE);
/* Set the RTC counter value */
rtc_counter_set(seccount);
/* wait for the register write to complete */
rtc_wait_config_finish();
return 0;
}
/**
* @brief Set RTC alarm.
* The time basic : 1970.1.1
* legitimate year: 1970 ~ 2099
* @param syear : Year
* smon : Month
* sday : Day
* hour
* min
* sec
* @retval 0: Set Alarm right.
* 1: Set Alarm failed.
*/
uint8_t RTC_SetAlarm(uint16_t syear, uint8_t smon, uint8_t sday, uint8_t hour, uint8_t min, uint8_t sec)
{
uint16_t t;
uint8_t seccount = 0;
if(syear < 1970 || syear > 2099)
return 1;
for(t = 1970; t < syear; t++)
{
if(Is_Leap_Year(t))seccount += 31622400;
else seccount += 31536000;
}
smon -= 1;
for(t = 0; t < smon; t++)
{
seccount += (uint8_t)mon_table[t] * 86400;
if(Is_Leap_Year(syear) && t == 1)seccount += 86400;
}
seccount += (uint8_t)(sday - 1) * 86400;
seccount += (uint8_t)hour * 3600;
seccount += (uint8_t)min * 60;
seccount += sec;
/* enable pwc and bpr clocks */
crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);
/* allow access to bpr domain */
pwc_battery_powered_domain_access(TRUE);
/* Set the RTC counter value */
rtc_alarm_set(seccount);
/* wait for the register write to complete */
rtc_wait_config_finish();
return 0;
}
/**
* @brief Get current time.
* @param None.
* @retval None.
*/
void RTC_GetCalendar(RTC_Calendar_TypeDef* calendar)
{
static RTC_Calendar_TypeDef _calendar;
static uint16_t daycnt = 0;
uint32_t timecount = 0;
uint32_t temp = 0;
uint32_t temp1 = 0;
timecount = rtc_counter_get();
temp = timecount / 86400;
if(daycnt != temp)
{
daycnt = temp;
temp1 = 1970;
while(temp >= 365)
{
if(Is_Leap_Year(temp1))
{
if(temp >= 366)temp -= 366;
else
{
temp1++;
break;
}
}
else temp -= 365;
temp1++;
}
_calendar.year = temp1;
temp1 = 0;
while(temp >= 28)
{
if(Is_Leap_Year(_calendar.year) && temp1 == 1)
{
if(temp >= 29)temp -= 29;
else break;
}
else
{
if(temp >= mon_table[temp1])temp -= mon_table[temp1];
else break;
}
temp1++;
}
_calendar.month = temp1 + 1;
_calendar.day = temp + 1;
}
temp = timecount % 86400;
_calendar.hour = temp / 3600;
_calendar.min = (temp % 3600) / 60;
_calendar.sec = (temp % 3600) % 60;
_calendar.week = RTC_GetWeek(_calendar.year, _calendar.month, _calendar.day);
*calendar = _calendar;
}
/**
* @brief Get current week by Input Leap year\mouth\day.
* @param syear : Year
* smon : Month
* sday : Day
* @retval week number.
*/
uint8_t RTC_GetWeek(uint16_t year, uint8_t month, uint8_t day)
{
uint16_t temp2;
uint8_t yearH, yearL;
yearH = year / 100;
yearL = year % 100;
if (yearH > 19)yearL += 100;
temp2 = yearL + yearL / 4;
temp2 = temp2 % 7;
temp2 = temp2 + day + table_week[month - 1];
if (yearL % 4 == 0 && month < 3)
temp2--;
return(temp2 % 7);
}

View File

@@ -0,0 +1,53 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RTC_H
#define __RTC_H
#include "mcu_type.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
uint8_t hour;
uint8_t min;
uint8_t sec;
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t week;
} RTC_Calendar_TypeDef;
void RTC_Init(void);
void RTC_GetCalendar(RTC_Calendar_TypeDef* calendar);
uint8_t RTC_SetAlarm(uint16_t syear, uint8_t smon, uint8_t sday, uint8_t hour, uint8_t min, uint8_t sec);
uint8_t RTC_GetWeek(uint16_t year, uint8_t month, uint8_t day);
uint8_t RTC_SetTime(uint16_t syear, uint8_t smon, uint8_t sday, uint8_t hour, uint8_t min, uint8_t sec);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,108 @@
/**
* \file syscalls_at32.c
*
* Implementation of newlib syscall.
*
*/
#include "at32f403a_407.h"
#include "at32f403a_407_conf.h"
#if defined ( __GNUC__ ) /* GCC CS3 */
#include <sys/stat.h>
#endif
#include <errno.h>
#undef errno
extern int errno;
extern size_t uart_debug_write(uint8_t *data, uint32_t size);
// Helper macro to mark unused parameters and prevent compiler warnings.
// Appends _UNUSED to the variable name to prevent accidentally using them.
#ifdef UNUSED
#undef UNUSED
#endif
#ifdef __GNUC__
#define UNUSED(x) x ## _UNUSED __attribute__((__unused__))
#else
#define UNUSED(x) x ## _UNUSED
#endif
__attribute__((weak))
caddr_t _sbrk(int incr)
{
extern char _estack; /* Defined in the linker script */
extern char _Min_Stack_Size; /* Defined in the linker script */
extern char _end; /* Defined by the linker */
static char *heap_end = &_end ;
char *prev_heap_end = heap_end;
if (heap_end + incr > (char *)__get_MSP()) {
/* Heap and stack collision */
errno = ENOMEM;
return (caddr_t) -1;
}
/* Ensure to keep minimum stack size defined in the linker script */
if (heap_end + incr >= (char *)(&_estack - &_Min_Stack_Size)) {
errno = ENOMEM;
return (caddr_t) -1;
}
heap_end += incr ;
return (caddr_t) prev_heap_end ;
}
__attribute__((weak))
int _close(UNUSED(int file))
{
return -1;
}
__attribute__((weak))
int _fstat(UNUSED(int file), struct stat *st)
{
st->st_mode = S_IFCHR ;
return 0;
}
__attribute__((weak))
int _isatty(UNUSED(int file))
{
return 1;
}
__attribute__((weak))
int _lseek(UNUSED(int file), UNUSED(int ptr), UNUSED(int dir))
{
return 0;
}
__attribute__((weak))
int _read(UNUSED(int file), UNUSED(char *ptr), UNUSED(int len))
{
return 0;
}
/* Moved to Print.cpp to support Print::printf()
__attribute__((weak))
int _write(UNUSED(int file), char *ptr, int len)
{
}
*/
__attribute__((weak))
void _exit(UNUSED(int status))
{
for (; ;) ;
}
__attribute__((weak))
int _kill(UNUSED(int pid), UNUSED(int sig))
{
errno = EINVAL;
return -1;
}
__attribute__((weak))
int _getpid(void)
{
return 1;
}

View File

@@ -0,0 +1,608 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "timer.h"
typedef enum
{
TIMER1, TIMER2, TIMER3, TIMER4, TIMER5, TIMER6, TIMER7, TIMER8,
TIMER9, TIMER10, TIMER11, TIMER12, TIMER13, TIMER14, TIMER15,
TIMER_MAX
} TIMER_Type;
static Timer_CallbackFunction_t Timer_CallbackFunction[TIMER_MAX] = { 0 };
/**
* @brief 启动或关闭指定定时器的时钟
* @param TIMx:定时器地址
* @param NewState: ENABLE启动DISABLE关闭
* @retval 无
*/
void Timer_ClockCmd(tmr_type* TIMx, bool Enable)
{
int index;
typedef struct
{
tmr_type* tmr;
crm_periph_clock_type crm_periph_clock;
} crm_tmr_clock_map_t;
# define CLOCK_MAP_DEF(n) {TMR##n, CRM_TMR##n##_PERIPH_CLOCK}
static const crm_tmr_clock_map_t clock_map[] =
{
CLOCK_MAP_DEF(1),
CLOCK_MAP_DEF(2),
CLOCK_MAP_DEF(3),
CLOCK_MAP_DEF(4),
CLOCK_MAP_DEF(5),
CLOCK_MAP_DEF(6),
CLOCK_MAP_DEF(7),
CLOCK_MAP_DEF(8),
CLOCK_MAP_DEF(9),
CLOCK_MAP_DEF(10),
CLOCK_MAP_DEF(11),
CLOCK_MAP_DEF(12),
CLOCK_MAP_DEF(13),
CLOCK_MAP_DEF(14)
};
for(index = 0; index < sizeof(clock_map) / sizeof(crm_tmr_clock_map_t); index++)
{
if(TIMx == clock_map[index].tmr)
{
crm_periph_clock_enable(clock_map[index].crm_periph_clock, Enable ? TRUE : FALSE);
}
}
}
static float Qsqrt(float number)
{
long i;
float x2, y;
const float threehalfs = 1.5f;
x2 = number * 0.5f;
y = number;
i = *(long*)&y;
i = 0x5f3759df - (i >> 1);
y = *(float*)&i;
y = y * (threehalfs - (x2 * y * y));
y = y * (threehalfs - (x2 * y * y));
return 1.0f / y;
}
/**
* @brief 频率因数分解,获取接近的值
* @param freq: 中断频率(Hz)
* @param clock: 定时器时钟
* @param *period: 重装值地址
* @param *prescaler: 时钟分频值地址
* @retval 误差值(Hz)
*/
static bool Timer_FreqFactorization(
uint32_t freq,
uint32_t clock,
uint16_t* factor1,
uint16_t* factor2,
int32_t* error
)
{
uint32_t targetProdect;
uint16_t fct1;
uint16_t fct2;
uint16_t fct1_save = 1;
uint16_t fct2_save = 1;
uint16_t fct_max;
uint16_t max_error = 0xFFFF;
if(freq == 0 || freq > clock)
{
return false;
}
/* 获取目标乘积 */
targetProdect = clock / freq;
/* 从targetProdect的平方根开始计算 */
fct1 = Qsqrt(targetProdect);
/* 计算因数最大值,减少遍历次数 */
fct_max = (targetProdect < 0xFFFF) ? targetProdect : 0xFFFF;
/* 遍历使两因数的乘积足够接近prodect */
for(; fct1 > 1; fct1--)
{
for(fct2 = fct1; fct2 < fct_max; fct2++)
{
/* 求误差 */
int32_t newerr = fct1 * fct2 - targetProdect;
if(newerr < 0)
{
newerr = -newerr;
}
if(newerr < max_error)
{
/* 保存最小误差 */
max_error = (uint16_t)newerr;
fct1_save = fct1;
fct2_save = fct2;
/* 最佳 */
if(max_error == 0)
{
break;
}
}
}
}
*factor1 = fct1_save;
*factor2 = fct2_save;
*error = (freq - clock / (fct1_save * fct2_save));
return true;
}
/**
* @brief 将定时中断时间转换为重装值和时钟分频值
* @param time: 中断时间(微秒)
* @param clock: 定时器时钟
* @param *period: 重装值地址
* @param *prescaler: 时钟分频值地址
* @retval 无
*/
static void Timer_TimeFactorization(
uint32_t time,
uint32_t clock,
uint16_t* factor1,
uint16_t* factor2
)
{
const uint32_t cyclesPerMicros = clock / 1000000U;
const uint32_t prodect = time * cyclesPerMicros;
uint16_t fct1, fct2;
if(prodect < cyclesPerMicros * 30)
{
fct1 = 10;
fct2 = prodect / 10;
}
else if(prodect < 65535 * 1000)
{
fct1 = prodect / 1000;
fct2 = prodect / fct1;
}
else
{
fct1 = prodect / 20000;
fct2 = prodect / fct1;
}
*factor1 = fct1;
*factor2 = fct2;
}
/**
* @brief 定时器使能
* @param TIMx: 定时器地址
* @param Enable: 使能
* @retval 无
*/
void Timer_SetEnable(tmr_type* TIMx, bool Enable)
{
tmr_counter_enable(TIMx, Enable ? TRUE : FALSE);
}
/**
* @brief 定时中断配置
* @param TIMx:定时器地址
* @param Time: 中断时间(微秒)
* @param Function: 定时中断回调函数
* @retval 无
*/
void Timer_SetInterrupt(tmr_type* TIMx, uint32_t Time, Timer_CallbackFunction_t Function)
{
uint16_t period = 0;
uint16_t prescaler = 0;
uint32_t clock = Timer_GetClockMax(TIMx);
if(Time == 0)
{
return;
}
/*将定时中断时间转换为重装值和时钟分频值*/
Timer_TimeFactorization(
Time,
clock,
&period,
&prescaler
);
/*定时中断配置*/
Timer_SetInterruptBase(
TIMx,
period,
prescaler,
Function,
TIMER_PREEMPTIONPRIORITY_DEFAULT,
TIMER_SUBPRIORITY_DEFAULT
);
}
/**
* @brief 更新定时中断频率
* @param TIMx:定时器地址
* @param Freq:中断频率
* @retval true: 设置成功
*/
bool Timer_SetInterruptFreqUpdate(tmr_type* TIMx, uint32_t Freq)
{
uint16_t period, prescaler;
uint32_t clock = Timer_GetClockMax(TIMx);
int32_t error;
if(Freq == 0)
return false;
bool success = Timer_FreqFactorization(
Freq,
clock,
&period,
&prescaler,
&error
);
if(!success)
{
return false;
}
tmr_base_init(TIMx, period - 1, prescaler - 1);
return true;
}
/**
* @brief 获取定时器最大频率
* @param TIMx:定时器地址
* @retval 最大频率
*/
uint32_t Timer_GetClockMax(tmr_type* TIMx)
{
static crm_clocks_freq_type crm_clocks_freq_struct = {0};
if(!crm_clocks_freq_struct.sclk_freq)
{
crm_clocks_freq_get(&crm_clocks_freq_struct);
}
return crm_clocks_freq_struct.apb1_freq * 2;
}
/**
* @brief 获取定时器中断频率
* @param TIMx:定时器地址
* @retval 中断频率
*/
uint32_t Timer_GetClockOut(tmr_type* TIMx)
{
uint32_t clock = Timer_GetClockMax(TIMx);
return (clock / ((TIMx->pr + 1) * (TIMx->div + 1)));
}
/**
* @brief 更新定时中断时间
* @param TIMx:定时器地址
* @param Time: 中断时间(微秒)
* @retval 无
*/
void Timer_SetInterruptTimeUpdate(TIM_TypeDef* TIMx, uint32_t Time)
{
uint16_t period, prescaler;
uint32_t clock = Timer_GetClockMax(TIMx);
Timer_TimeFactorization(
Time,
clock,
&period,
&prescaler
);
tmr_base_init(TIMx, period - 1, prescaler - 1);
}
/**
* @brief 定时中断基本配置
* @param TIMx:定时器地址
* @param Period:重装值
* @param Prescaler:时钟分频值
* @param Function: 定时中断回调函数
* @param PreemptionPriority: 抢占优先级
* @param SubPriority: 子优先级
* @retval 无
*/
void Timer_SetInterruptBase(
tmr_type* TIMx,
uint16_t Period,
uint16_t Prescaler,
Timer_CallbackFunction_t Function,
uint8_t PreemptionPriority,
uint8_t SubPriority
)
{
IRQn_Type TMRx_IRQn = (IRQn_Type)0;
TIMER_Type TIMERx = TIMER1;
#define TMRx_IRQ_DEF(n,x_IRQn)\
do{\
if(TIMx == TIM##n)\
{\
TIMERx = TIMER##n;\
TMRx_IRQn = x_IRQn;\
goto match;\
}\
}\
while(0)
/*如果编译器提示identifier "xxx_IRQn" is undefined
*把未定义的注释掉即可
*/
TMRx_IRQ_DEF(1, TMR1_OVF_TMR10_IRQn);
TMRx_IRQ_DEF(2, TMR2_GLOBAL_IRQn);
TMRx_IRQ_DEF(3, TMR3_GLOBAL_IRQn);
TMRx_IRQ_DEF(4, TMR4_GLOBAL_IRQn);
TMRx_IRQ_DEF(5, TMR5_GLOBAL_IRQn);
TMRx_IRQ_DEF(6, TMR6_GLOBAL_IRQn);
TMRx_IRQ_DEF(7, TMR7_GLOBAL_IRQn);
TMRx_IRQ_DEF(8, TMR8_OVF_TMR13_IRQn);
TMRx_IRQ_DEF(9, TMR1_BRK_TMR9_IRQn);
TMRx_IRQ_DEF(10, TMR1_OVF_TMR10_IRQn);
TMRx_IRQ_DEF(11, TMR1_TRG_HALL_TMR11_IRQn);
TMRx_IRQ_DEF(12, TMR8_BRK_TMR12_IRQn);
TMRx_IRQ_DEF(13, TMR8_OVF_TMR13_IRQn);
TMRx_IRQ_DEF(14, TMR8_TRG_HALL_TMR14_IRQn);
match:
if(TMRx_IRQn == 0)
{
return;
}
Timer_CallbackFunction[TIMERx] = Function;
tmr_reset(TIMx);
Timer_ClockCmd(TIMx, true);
tmr_repetition_counter_set(TIMx, 0);
tmr_cnt_dir_set(TIMx, TMR_COUNT_UP);
tmr_base_init(TIMx, Period - 1, Prescaler - 1);
nvic_irq_enable(TMRx_IRQn, PreemptionPriority, SubPriority);
tmr_flag_clear(TIMx, TMR_OVF_FLAG);
tmr_interrupt_enable(TIMx, TMR_OVF_INT, TRUE);
}
/**
* @brief 设置输出比较值
* @param TIMx: 定时器地址
* @param TimerChannel: 定时器通道
* @param Compare:输出比较值
* @retval 无
*/
void Timer_SetCompare(TIM_TypeDef* TIMx, uint8_t TimerChannel, uint32_t Compare)
{
switch(TimerChannel)
{
case 1:
tmr_channel_value_set(TIMx, TMR_SELECT_CHANNEL_1, Compare);
break;
case 2:
tmr_channel_value_set(TIMx, TMR_SELECT_CHANNEL_2, Compare);
break;
case 3:
tmr_channel_value_set(TIMx, TMR_SELECT_CHANNEL_3, Compare);
break;
case 4:
tmr_channel_value_set(TIMx, TMR_SELECT_CHANNEL_4, Compare);
break;
default:
break;
}
}
/**
* @brief 获取捕获值
* @param TIMx: 定时器地址
* @param TimerChannel: 定时器通道
* @retval 捕获值
*/
uint16_t Timer_GetCompare(TIM_TypeDef* TIMx, uint8_t TimerChannel)
{
uint16_t retval = 0;
switch(TimerChannel)
{
case 1:
retval = tmr_channel_value_get(TIMx, TMR_SELECT_CHANNEL_1);
break;
case 2:
retval = tmr_channel_value_get(TIMx, TMR_SELECT_CHANNEL_2);
break;
case 3:
retval = tmr_channel_value_get(TIMx, TMR_SELECT_CHANNEL_3);
break;
case 4:
retval = tmr_channel_value_get(TIMx, TMR_SELECT_CHANNEL_4);
break;
default:
break;
}
return retval;
}
/**
* @brief 更新定时器时钟预分频数
* @param TIMx: 定时器地址
* @param rescaler: 时钟预分频数
* @retval 无
*/
void Timer_SetPrescaler(tmr_type* TIMx, uint16_t rescaler)
{
TIMx->div = rescaler;
}
/**
* @brief 更新定时器自动重装值
* @param TIMx: 定时器地址
* @param Reload: 自动重装值
* @retval 无
*/
void Timer_SetReload(tmr_type* TIMx, uint16_t Reload)
{
TIMx->pr = Reload;
}
/**
* @brief 应用定时器更改
* @param TIMx: 定时器地址
* @retval 无
*/
void Timer_GenerateUpdate(tmr_type* TIMx)
{
TIMx->swevt_bit.ovfswtr = TRUE;
}
#define TMRx_IRQHANDLER(n) \
do{\
if (tmr_flag_get(TMR##n, TMR_OVF_FLAG) != RESET)\
{\
if(Timer_CallbackFunction[TIMER##n])\
{\
Timer_CallbackFunction[TIMER##n]();\
}\
tmr_flag_clear(TMR##n, TMR_OVF_FLAG);\
}\
}while(0)
/**
* @brief 定时中断入口定时器1、10
* @param 无
* @retval 无
*/
void TMR1_OV_TMR10_IRQHandler(void)
{
TMRx_IRQHANDLER(1);
TMRx_IRQHANDLER(10);
}
/**
* @brief 定时中断入口定时器2
* @param 无
* @retval 无
*/
void TMR2_GLOBAL_IRQHandler(void)
{
TMRx_IRQHANDLER(2);
}
/**
* @brief 定时中断入口定时器3
* @param 无
* @retval 无
*/
void TMR3_GLOBAL_IRQHandler(void)
{
TMRx_IRQHANDLER(3);
}
/**
* @brief 定时中断入口定时器4
* @param 无
* @retval 无
*/
void TMR4_GLOBAL_IRQHandler(void)
{
TMRx_IRQHANDLER(4);
}
/**
* @brief 定时中断入口定时器5
* @param 无
* @retval 无
*/
void TMR5_GLOBAL_IRQHandler(void)
{
TMRx_IRQHANDLER(5);
}
/**
* @brief 定时中断入口定时器6
* @param 无
* @retval 无
*/
void TMR6_GLOBAL_IRQHandler(void)
{
#ifdef TMR6
TMRx_IRQHANDLER(6);
#endif
}
/**
* @brief 定时中断入口定时器7
* @param 无
* @retval 无
*/
void TMR7_GLOBAL_IRQHandler(void)
{
#ifdef TMR7
TMRx_IRQHANDLER(7);
#endif
}
/**
* @brief 定时中断入口定时器8、13
* @param 无
* @retval 无
*/
void TMR8_OV_TMR13_IRQHandler(void)
{
TMRx_IRQHANDLER(8);
#ifdef TMR13
TMRx_IRQHANDLER(13);
#endif
}
/**
* @brief 定时中断入口定时器15
* @param 无
* @retval 无
*/
void TMR15_OV_IRQHandler(void)
{
#ifdef TMR15
TMRx_IRQHANDLER(15);
#endif
}

View File

@@ -0,0 +1,58 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __TIMER_H
#define __TIMER_H
#include <stdbool.h>
#include "mcu_type.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void(*Timer_CallbackFunction_t)(void);
void Timer_SetEnable(tmr_type* TIMx, bool Enable);
void Timer_SetInterrupt(tmr_type* TIMx, uint32_t time, Timer_CallbackFunction_t Function);
void Timer_SetInterruptTimeUpdate(tmr_type* TIMx, uint32_t Time);
bool Timer_SetInterruptFreqUpdate(tmr_type* TIMx, uint32_t Freq);
void Timer_SetInterruptBase(
tmr_type* TIMx,
uint16_t Period, uint16_t Prescaler,
Timer_CallbackFunction_t Function,
uint8_t PreemptionPriority, uint8_t SubPriority
);
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_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);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,96 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "wdg.h"
uint32_t WDG_Init(uint32_t timeout)
{
uint32_t reload_value;
uint32_t real_timeout = 0;
uint16_t division;
static const uint8_t div_map[] =
{
WDT_CLK_DIV_4, /*!< wdt clock divider value is 4 */
WDT_CLK_DIV_8, /*!< wdt clock divider value is 8 */
WDT_CLK_DIV_16, /*!< wdt clock divider value is 16 */
WDT_CLK_DIV_32, /*!< wdt clock divider value is 32 */
WDT_CLK_DIV_64, /*!< wdt clock divider value is 64 */
WDT_CLK_DIV_128, /*!< wdt clock divider value is 128 */
WDT_CLK_DIV_256 /*!< wdt clock divider value is 256 */
};
/* set reload value
* lick_freq = 40000
* timeout = reload_value * divider / lick_freq * 1000 (ms)
* timeout / divider * lick_freq / 1000 = reload_value
*/
const uint32_t lick_freq = 40000;
for(int i = 0; i < sizeof(div_map) / sizeof(uint8_t); i++)
{
int div = 4 << i;
reload_value = (uint64_t)timeout * lick_freq / div / 1000;
if(reload_value <= 0xFFF)
{
real_timeout = (uint64_t)reload_value * div * 1000 / lick_freq;
division = div_map[i];
break;
}
}
if(reload_value > 0xFFF)
{
return 0;
}
if(crm_flag_get(CRM_WDT_RESET_FLAG) != RESET)
{
/* reset from wdt */
crm_flag_clear(CRM_WDT_RESET_FLAG);
}
/* disable register write protection */
wdt_register_write_enable(TRUE);
/* set the wdt divider value */
wdt_divider_set(division);
/* Set counter reload value */
wdt_reload_value_set(3000 - 1);
/* Reload IWDG counter */
wdt_counter_reload();
/* Enable IWDG (the LSI oscillator will be enabled by hardware) */
wdt_enable();
return real_timeout;
}
void WDG_ReloadCounter(void)
{
wdt_counter_reload();
}

View File

@@ -0,0 +1,39 @@
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __WDT_H
#define __WDT_H
#include "mcu_type.h"
#ifdef __cplusplus
extern "C" {
#endif
uint32_t WDG_Init(uint32_t timeout);
void WDG_ReloadCounter(void);
#ifdef __cplusplus
}
#endif
#endif

45
cores/arduino/main.cpp Normal file
View File

@@ -0,0 +1,45 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
#include <Arduino.h>
#include "libcore/mcu_core.h"
extern void setup(void);
extern void loop(void);
// Force init to be called *first*, i.e. before static object allocation.
// Otherwise, statically allocated objects that need libmaple may fail.
__attribute__(( constructor (101))) void premain() {
}
int main(void) {
Core_Init();
setup();
while (1) {
loop();
}
return 0;
}