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:
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
|
||||
Reference in New Issue
Block a user