mirror of
https://github.com/WeActStudio/ArduinoCore-AT32F4.git
synced 2026-05-21 09:22:01 +00:00
support linux system
This commit is contained in:
118
cores/arduino/Arduino.h
Normal file
118
cores/arduino/Arduino.h
Normal 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
|
||||
292
cores/arduino/HardwareSerial.cpp
Normal file
292
cores/arduino/HardwareSerial.cpp
Normal 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
|
||||
142
cores/arduino/HardwareSerial.h
Normal file
142
cores/arduino/HardwareSerial.h
Normal 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
288
cores/arduino/Print.cpp
Normal 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
109
cores/arduino/Print.h
Normal 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
40
cores/arduino/Printable.h
Normal 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
430
cores/arduino/SPI.cpp
Normal 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
173
cores/arduino/SPI.h
Normal 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
346
cores/arduino/Stream.cpp
Normal 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
165
cores/arduino/Stream.h
Normal 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
128
cores/arduino/Tone.cpp
Normal 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
34
cores/arduino/Tone.h
Normal 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
171
cores/arduino/WCharacter.h
Normal 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
60
cores/arduino/WMath.cpp
Normal 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
12
cores/arduino/WMath.h
Normal 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
6
cores/arduino/WProgram.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef __WPROGRAM_H
|
||||
#define __WPROGRAM_H
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#endif
|
||||
791
cores/arduino/WString.cpp
Normal file
791
cores/arduino/WString.cpp
Normal 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
311
cores/arduino/WString.h
Normal 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
242
cores/arduino/Wire.cpp
Normal 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
131
cores/arduino/Wire.h
Normal 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
166
cores/arduino/WireBase.cpp
Normal 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
172
cores/arduino/WireBase.h
Normal 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_
|
||||
0
cores/arduino/avr/interrupt.h
Normal file
0
cores/arduino/avr/interrupt.h
Normal file
44
cores/arduino/avr/pgmspace.h
Normal file
44
cores/arduino/avr/pgmspace.h
Normal 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
534
cores/arduino/binary.h
Normal 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
37
cores/arduino/dtostrf.c
Normal 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
37
cores/arduino/dtostrf.h
Normal 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
164
cores/arduino/itoa.c
Normal 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
44
cores/arduino/itoa.h
Normal 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_
|
||||
294
cores/arduino/libcore/Arduino.c
Normal file
294
cores/arduino/libcore/Arduino.c
Normal 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
255
cores/arduino/libcore/adc.c
Normal 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];
|
||||
}
|
||||
51
cores/arduino/libcore/adc.h
Normal file
51
cores/arduino/libcore/adc.h
Normal 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 */
|
||||
105
cores/arduino/libcore/at32f403a_407_clock.c
Normal file
105
cores/arduino/libcore/at32f403a_407_clock.c
Normal 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();
|
||||
}
|
||||
46
cores/arduino/libcore/at32f403a_407_clock.h
Normal file
46
cores/arduino/libcore/at32f403a_407_clock.h
Normal 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 */
|
||||
|
||||
112
cores/arduino/libcore/config/mcu_config.h
Normal file
112
cores/arduino/libcore/config/mcu_config.h
Normal 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
|
||||
121
cores/arduino/libcore/delay.c
Normal file
121
cores/arduino/libcore/delay.c
Normal 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;
|
||||
}
|
||||
42
cores/arduino/libcore/delay.h
Normal file
42
cores/arduino/libcore/delay.h
Normal 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 */
|
||||
103
cores/arduino/libcore/extend_SRAM.c
Normal file
103
cores/arduino/libcore/extend_SRAM.c
Normal 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
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
18
cores/arduino/libcore/extend_SRAM.h
Normal file
18
cores/arduino/libcore/extend_SRAM.h
Normal 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 */
|
||||
|
||||
235
cores/arduino/libcore/exti.c
Normal file
235
cores/arduino/libcore/exti.c
Normal 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);
|
||||
}
|
||||
56
cores/arduino/libcore/exti.h
Normal file
56
cores/arduino/libcore/exti.h
Normal 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
|
||||
341
cores/arduino/libcore/gpio.c
Normal file
341
cores/arduino/libcore/gpio.c
Normal 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);
|
||||
}
|
||||
121
cores/arduino/libcore/gpio.h
Normal file
121
cores/arduino/libcore/gpio.h
Normal 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
158
cores/arduino/libcore/i2c.c
Normal 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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
39
cores/arduino/libcore/i2c.h
Normal file
39
cores/arduino/libcore/i2c.h
Normal 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
|
||||
|
||||
33
cores/arduino/libcore/mcu_core.c
Normal file
33
cores/arduino/libcore/mcu_core.c
Normal 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);
|
||||
}
|
||||
49
cores/arduino/libcore/mcu_core.h
Normal file
49
cores/arduino/libcore/mcu_core.h
Normal 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
|
||||
75
cores/arduino/libcore/mcu_type.h
Normal file
75
cores/arduino/libcore/mcu_type.h
Normal 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
115
cores/arduino/libcore/pwm.c
Normal 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);
|
||||
}
|
||||
41
cores/arduino/libcore/pwm.h
Normal file
41
cores/arduino/libcore/pwm.h
Normal 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
303
cores/arduino/libcore/rtc.c
Normal 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);
|
||||
}
|
||||
53
cores/arduino/libcore/rtc.h
Normal file
53
cores/arduino/libcore/rtc.h
Normal 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
|
||||
108
cores/arduino/libcore/syscall.c
Normal file
108
cores/arduino/libcore/syscall.c
Normal 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;
|
||||
}
|
||||
608
cores/arduino/libcore/timer.c
Normal file
608
cores/arduino/libcore/timer.c
Normal 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
|
||||
}
|
||||
58
cores/arduino/libcore/timer.h
Normal file
58
cores/arduino/libcore/timer.h
Normal 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
|
||||
96
cores/arduino/libcore/wdg.c
Normal file
96
cores/arduino/libcore/wdg.c
Normal 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();
|
||||
}
|
||||
39
cores/arduino/libcore/wdg.h
Normal file
39
cores/arduino/libcore/wdg.h
Normal 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
45
cores/arduino/main.cpp
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user