support linux system

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

View File

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