[core] Refactor Wiring, use PinData for parameters
This commit is contained in:
@@ -1,22 +1,11 @@
|
|||||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */
|
/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include "wiring_private.h"
|
||||||
#include <include.h>
|
|
||||||
|
|
||||||
#include <arm_arch.h>
|
|
||||||
#include <bk_timer.h>
|
|
||||||
#include <bk_timer_pub.h>
|
|
||||||
#include <rtos_pub.h>
|
|
||||||
#include <sys_rtos.h>
|
|
||||||
|
|
||||||
#define TICKS_PER_US (CFG_XTAL_FREQUENCE / 1000 / 1000)
|
#define TICKS_PER_US (CFG_XTAL_FREQUENCE / 1000 / 1000)
|
||||||
#define US_PER_OVERFLOW (portTICK_PERIOD_MS * 1000)
|
#define US_PER_OVERFLOW (portTICK_PERIOD_MS * 1000)
|
||||||
#define TICKS_PER_OVERFLOW (TICKS_PER_US * US_PER_OVERFLOW)
|
#define TICKS_PER_OVERFLOW (TICKS_PER_US * US_PER_OVERFLOW)
|
||||||
|
|
||||||
void delayMilliseconds(unsigned long ms) {
|
|
||||||
rtos_delay_milliseconds(ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t getTicksCount() {
|
static uint32_t getTicksCount() {
|
||||||
// copied from bk_timer_ctrl(), for speeds
|
// copied from bk_timer_ctrl(), for speeds
|
||||||
uint32_t timeout = 0;
|
uint32_t timeout = 0;
|
||||||
@@ -104,8 +93,22 @@ unsigned long micros() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void yield() {
|
void pinRemoveMode(PinInfo *pin, uint32_t mask) {
|
||||||
runPeriodicTasks();
|
PinData *data = pinData(pin);
|
||||||
vTaskDelay(1);
|
if ((mask & PIN_GPIO) && (pin->enabled & PIN_GPIO)) {
|
||||||
taskYIELD();
|
gpio_config(pin->gpio, GMODE_INPUT_PULLDOWN);
|
||||||
|
pinDisable(pin, PIN_GPIO);
|
||||||
|
}
|
||||||
|
if ((mask & PIN_IRQ) && (pin->enabled & PIN_IRQ)) {
|
||||||
|
data->irqHandler = NULL;
|
||||||
|
gpio_int_disable(pin->gpio);
|
||||||
|
pinDisable(pin, PIN_IRQ);
|
||||||
|
}
|
||||||
|
if ((mask & PIN_PWM) && (pin->enabled & PIN_PWM)) {
|
||||||
|
data->pwm->cfg.bits.en = PWM_DISABLE;
|
||||||
|
__wrap_bk_printf_disable();
|
||||||
|
sddev_control(PWM_DEV_NAME, CMD_PWM_DEINIT_PARAM, data->pwm);
|
||||||
|
__wrap_bk_printf_enable();
|
||||||
|
pinDisable(pin, PIN_PWM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-20. */
|
/* Copyright (c) Kuba Szczodrzyński 2022-06-20. */
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include "wiring_private.h"
|
||||||
|
|
||||||
#include <gpio_pub.h>
|
|
||||||
#include <pwm_pub.h>
|
|
||||||
#include <saradc_pub.h>
|
|
||||||
|
|
||||||
static GPIO_INDEX pwmToGpio[] = {
|
static GPIO_INDEX pwmToGpio[] = {
|
||||||
GPIO6, // PWM0
|
GPIO6, // PWM0
|
||||||
@@ -59,11 +55,7 @@ static pwm_param_t pwm;
|
|||||||
static uint16_t adcData[1];
|
static uint16_t adcData[1];
|
||||||
|
|
||||||
uint16_t analogReadVoltage(pin_size_t pinNumber) {
|
uint16_t analogReadVoltage(pin_size_t pinNumber) {
|
||||||
PinInfo *pin = pinInfo(pinNumber);
|
pinCheckGetInfo(pinNumber, PIN_ADC, 0);
|
||||||
if (!pin)
|
|
||||||
return 0;
|
|
||||||
if (!pinSupported(pin, PIN_ADC))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
UINT32 status;
|
UINT32 status;
|
||||||
saradc_desc_t adc;
|
saradc_desc_t adc;
|
||||||
@@ -90,11 +82,10 @@ uint16_t analogReadMaxVoltage(pin_size_t pinNumber) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void analogWrite(pin_size_t pinNumber, int value) {
|
void analogWrite(pin_size_t pinNumber, int value) {
|
||||||
PinInfo *pin = pinInfo(pinNumber);
|
pinCheckGetData(pinNumber, PIN_PWM, );
|
||||||
if (!pin)
|
|
||||||
return;
|
// GPIO can't be used together with PWM
|
||||||
if (!pinSupported(pin, PIN_PWM))
|
pinRemoveMode(pin, PIN_GPIO | PIN_IRQ);
|
||||||
return;
|
|
||||||
|
|
||||||
float percent = value * 1.0 / ((1 << _analogWriteResolution) - 1);
|
float percent = value * 1.0 / ((1 << _analogWriteResolution) - 1);
|
||||||
uint32_t frequency = 26 * _analogWritePeriod - 1;
|
uint32_t frequency = 26 * _analogWritePeriod - 1;
|
||||||
@@ -122,8 +113,9 @@ void analogWrite(pin_size_t pinNumber, int value) {
|
|||||||
sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_LEVL_SET_HIGH, &pwm.channel);
|
sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_LEVL_SET_HIGH, &pwm.channel);
|
||||||
sddev_control(PWM_DEV_NAME, CMD_PWM_UNIT_ENABLE, &pwm.channel);
|
sddev_control(PWM_DEV_NAME, CMD_PWM_UNIT_ENABLE, &pwm.channel);
|
||||||
__wrap_bk_printf_enable();
|
__wrap_bk_printf_enable();
|
||||||
pin->enabled &= ~PIN_GPIO;
|
// pass global PWM object pointer
|
||||||
pin->enabled |= PIN_PWM;
|
data->pwm = &pwm;
|
||||||
|
pinEnable(pin, PIN_PWM);
|
||||||
} else {
|
} else {
|
||||||
// update duty cycle
|
// update duty cycle
|
||||||
sddev_control(PWM_DEV_NAME, CMD_PWM_SET_DUTY_CYCLE, &pwm);
|
sddev_control(PWM_DEV_NAME, CMD_PWM_SET_DUTY_CYCLE, &pwm);
|
||||||
@@ -131,11 +123,7 @@ void analogWrite(pin_size_t pinNumber, int value) {
|
|||||||
} else {
|
} else {
|
||||||
if (pinEnabled(pin, PIN_PWM)) {
|
if (pinEnabled(pin, PIN_PWM)) {
|
||||||
// disable PWM
|
// disable PWM
|
||||||
pwm.cfg.bits.en = PWM_DISABLE;
|
pinRemoveMode(pin, PIN_PWM);
|
||||||
__wrap_bk_printf_disable();
|
|
||||||
sddev_control(PWM_DEV_NAME, CMD_PWM_DEINIT_PARAM, &pwm);
|
|
||||||
__wrap_bk_printf_enable();
|
|
||||||
pin->enabled &= ~PIN_PWM;
|
|
||||||
}
|
}
|
||||||
// force level as LOW
|
// force level as LOW
|
||||||
pinMode(pinNumber, OUTPUT);
|
pinMode(pinNumber, OUTPUT);
|
||||||
|
|||||||
23
cores/beken-72xx/arduino/src/wiring_data.h
Normal file
23
cores/beken-72xx/arduino/src/wiring_data.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/* Copyright (c) Kuba Szczodrzyński 2023-05-24. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <sdk_private.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct PinData_s {
|
||||||
|
pwm_param_t *pwm;
|
||||||
|
PinMode gpioMode;
|
||||||
|
PinStatus irqMode;
|
||||||
|
void *irqHandler;
|
||||||
|
void *irqParam;
|
||||||
|
bool irqChange;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
@@ -1,20 +1,16 @@
|
|||||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-20. */
|
/* Copyright (c) Kuba Szczodrzyński 2022-06-20. */
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include "wiring_private.h"
|
||||||
|
|
||||||
#include <gpio_pub.h>
|
|
||||||
|
|
||||||
void pinMode(pin_size_t pinNumber, PinMode pinMode) {
|
void pinMode(pin_size_t pinNumber, PinMode pinMode) {
|
||||||
PinInfo *pin = pinInfo(pinNumber);
|
pinCheckGetData(pinNumber, PIN_GPIO, );
|
||||||
if (!pin)
|
|
||||||
return;
|
if (pinEnabled(pin, PIN_GPIO) && data->gpioMode == pinMode)
|
||||||
if (!pinSupported(pin, PIN_GPIO))
|
|
||||||
return;
|
|
||||||
if (pinEnabled(pin, PIN_PWM))
|
|
||||||
// disable PWM before using the pin
|
|
||||||
analogWrite(pinNumber, 0);
|
|
||||||
if (pinEnabled(pin, PIN_GPIO) && pin->mode == pinMode)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// GPIO can't be used together with PWM
|
||||||
|
pinRemoveMode(pin, PIN_PWM);
|
||||||
|
|
||||||
switch (pinMode) {
|
switch (pinMode) {
|
||||||
case INPUT:
|
case INPUT:
|
||||||
gpio_config(pin->gpio, GMODE_INPUT);
|
gpio_config(pin->gpio, GMODE_INPUT);
|
||||||
@@ -31,34 +27,21 @@ void pinMode(pin_size_t pinNumber, PinMode pinMode) {
|
|||||||
case OUTPUT_OPENDRAIN:
|
case OUTPUT_OPENDRAIN:
|
||||||
gpio_config(pin->gpio, GMODE_SET_HIGH_IMPENDANCE);
|
gpio_config(pin->gpio, GMODE_SET_HIGH_IMPENDANCE);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
pin->enabled |= PIN_GPIO;
|
pinEnable(pin, PIN_GPIO);
|
||||||
pin->mode = pinMode;
|
data->gpioMode = pinMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void digitalWrite(pin_size_t pinNumber, PinStatus status) {
|
void digitalWrite(pin_size_t pinNumber, PinStatus status) {
|
||||||
// verify level is 0 or 1
|
pinCheckGetData(pinNumber, PIN_GPIO, );
|
||||||
if (status > HIGH)
|
pinSetOutputPull(pin, data, pinNumber, status);
|
||||||
return;
|
gpio_output(pin->gpio, !!status);
|
||||||
PinInfo *pin = pinInfo(pinNumber);
|
|
||||||
if (!pin)
|
|
||||||
return;
|
|
||||||
// pin is not GPIO yet or not OUTPUT; enable or disable input pullup
|
|
||||||
if (!pinEnabled(pin, PIN_GPIO) || !pinIsOutput(pin)) {
|
|
||||||
pinMode(pinNumber, status * INPUT_PULLUP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// write the new state
|
|
||||||
gpio_output(pin->gpio, status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PinStatus digitalRead(pin_size_t pinNumber) {
|
PinStatus digitalRead(pin_size_t pinNumber) {
|
||||||
PinInfo *pin = pinInfo(pinNumber);
|
pinCheckGetData(pinNumber, PIN_GPIO, LOW);
|
||||||
if (!pin)
|
pinSetInputMode(pin, data, pinNumber);
|
||||||
return 0;
|
|
||||||
// pin is not GPIO yet or not INPUT; change the mode
|
|
||||||
if (!pinEnabled(pin, PIN_GPIO) || !pinIsInput(pin))
|
|
||||||
pinMode(pinNumber, INPUT);
|
|
||||||
// read the value
|
|
||||||
return gpio_input(pin->gpio);
|
return gpio_input(pin->gpio);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,98 +1,70 @@
|
|||||||
/* Copyright (c) Kuba Szczodrzyński 2022-07-31. */
|
/* Copyright (c) Kuba Szczodrzyński 2022-07-31. */
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include "wiring_private.h"
|
||||||
|
|
||||||
#include <gpio_pub.h>
|
|
||||||
|
|
||||||
static void *irqHandlerList[PINS_COUNT] = {NULL};
|
|
||||||
static void *irqHandlerArgs[PINS_COUNT] = {NULL};
|
|
||||||
static bool irqChangeList[PINS_COUNT];
|
|
||||||
|
|
||||||
static void irqHandler(unsigned char gpio) {
|
static void irqHandler(unsigned char gpio) {
|
||||||
PinInfo *pin = pinByGpio(gpio);
|
PinInfo *pin = pinByGpio(gpio);
|
||||||
if (pin == NULL)
|
if (pin == NULL)
|
||||||
return;
|
return;
|
||||||
uint32_t index = pinIndex(pin);
|
PinData *data = pinData(pin);
|
||||||
if (!irqHandlerList[index])
|
if (!data->irqHandler)
|
||||||
return;
|
return;
|
||||||
if (irqChangeList[index]) {
|
if (data->irqChange) {
|
||||||
if (pin->mode == INPUT_PULLDOWN) {
|
if (data->gpioMode == INPUT_PULLDOWN) {
|
||||||
pin->mode = INPUT_PULLUP;
|
data->gpioMode = INPUT_PULLUP;
|
||||||
gpio_int_enable(pin->gpio, GPIO_INT_LEVEL_FALLING, irqHandler);
|
gpio_int_enable(pin->gpio, GPIO_INT_LEVEL_FALLING, irqHandler);
|
||||||
} else if (pin->mode == INPUT_PULLUP) {
|
} else if (data->gpioMode == INPUT_PULLUP) {
|
||||||
pin->mode = INPUT_PULLDOWN;
|
data->gpioMode = INPUT_PULLDOWN;
|
||||||
gpio_int_enable(pin->gpio, GPIO_INT_LEVEL_RISING, irqHandler);
|
gpio_int_enable(pin->gpio, GPIO_INT_LEVEL_RISING, irqHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (irqHandlerArgs[index] == NULL) {
|
if (!data->irqParam)
|
||||||
((voidFuncPtr)irqHandlerList[index])();
|
((voidFuncPtr)data->irqHandler)();
|
||||||
} else {
|
else
|
||||||
((voidFuncPtrParam)irqHandlerList[index])(irqHandlerArgs[index]);
|
((voidFuncPtrParam)data->irqHandler)(data->irqParam);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode) {
|
|
||||||
attachInterruptParam(interruptNumber, (voidFuncPtrParam)callback, mode, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void *param) {
|
void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void *param) {
|
||||||
PinInfo *pin = pinInfo(interruptNumber);
|
pinCheckGetData(interruptNumber, PIN_IRQ, );
|
||||||
if (!pin)
|
|
||||||
return;
|
|
||||||
if (!pinSupported(pin, PIN_IRQ))
|
|
||||||
return;
|
|
||||||
uint32_t index = pinIndex(pin);
|
|
||||||
uint32_t event = 0;
|
|
||||||
PinMode modeNew = 0;
|
|
||||||
bool change = 0;
|
|
||||||
|
|
||||||
|
data->irqHandler = callback;
|
||||||
|
data->irqParam = param;
|
||||||
|
|
||||||
|
if (pinEnabled(pin, PIN_IRQ) && data->irqMode == mode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// GPIO can't be used together with PWM
|
||||||
|
pinRemoveMode(pin, PIN_PWM);
|
||||||
|
|
||||||
|
uint32_t event = 0;
|
||||||
|
bool change = false;
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case LOW:
|
case LOW:
|
||||||
event = GPIO_INT_LEVEL_LOW;
|
event = GPIO_INT_LEVEL_LOW;
|
||||||
modeNew = INPUT_PULLUP;
|
|
||||||
change = false;
|
|
||||||
break;
|
break;
|
||||||
case HIGH:
|
case HIGH:
|
||||||
event = GPIO_INT_LEVEL_HIGH;
|
event = GPIO_INT_LEVEL_HIGH;
|
||||||
modeNew = INPUT_PULLDOWN;
|
|
||||||
change = false;
|
|
||||||
break;
|
break;
|
||||||
case FALLING:
|
case FALLING:
|
||||||
event = GPIO_INT_LEVEL_FALLING;
|
event = GPIO_INT_LEVEL_FALLING;
|
||||||
modeNew = INPUT_PULLUP;
|
|
||||||
change = false;
|
|
||||||
break;
|
break;
|
||||||
case RISING:
|
case RISING:
|
||||||
event = GPIO_INT_LEVEL_RISING;
|
event = GPIO_INT_LEVEL_RISING;
|
||||||
modeNew = INPUT_PULLDOWN;
|
|
||||||
change = false;
|
|
||||||
break;
|
break;
|
||||||
case CHANGE:
|
case CHANGE:
|
||||||
event = GPIO_INT_LEVEL_FALLING;
|
event = GPIO_INT_LEVEL_FALLING;
|
||||||
modeNew = INPUT_PULLUP;
|
change = true;
|
||||||
change = true;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
irqHandlerList[index] = callback;
|
pinEnable(pin, PIN_IRQ);
|
||||||
irqHandlerArgs[index] = param;
|
data->irqMode = mode;
|
||||||
irqChangeList[index] = change;
|
data->irqChange = change;
|
||||||
|
|
||||||
gpio_int_enable(pin->gpio, event, irqHandler);
|
gpio_int_enable(pin->gpio, event, irqHandler);
|
||||||
pin->enabled |= PIN_IRQ | PIN_GPIO;
|
|
||||||
pin->mode = modeNew;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void detachInterrupt(pin_size_t interruptNumber) {
|
void detachInterrupt(pin_size_t interruptNumber) {
|
||||||
PinInfo *pin = pinInfo(interruptNumber);
|
pinModeRemove(interruptNumber, PIN_IRQ);
|
||||||
if (!pin)
|
|
||||||
return;
|
|
||||||
if (!pinSupported(pin, PIN_IRQ))
|
|
||||||
return;
|
|
||||||
uint32_t index = pinIndex(pin);
|
|
||||||
irqHandlerList[index] = NULL;
|
|
||||||
irqHandlerArgs[index] = NULL;
|
|
||||||
irqChangeList[index] = false;
|
|
||||||
gpio_int_disable(pin->gpio);
|
|
||||||
pin->enabled &= ~PIN_IRQ;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,18 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
// most stuff is here
|
// most stuff is here - this has to be before other includes!
|
||||||
#include <include.h>
|
#include <include.h>
|
||||||
// other includes
|
// other includes
|
||||||
|
#include <arm_arch.h>
|
||||||
|
#include <bk_timer.h>
|
||||||
|
#include <bk_timer_pub.h>
|
||||||
#include <flash_pub.h>
|
#include <flash_pub.h>
|
||||||
#include <gpio_pub.h>
|
#include <gpio_pub.h>
|
||||||
#include <param_config.h>
|
#include <param_config.h>
|
||||||
|
#include <pwm_pub.h>
|
||||||
|
#include <rtos_pub.h>
|
||||||
|
#include <saradc_pub.h>
|
||||||
#include <start_type_pub.h>
|
#include <start_type_pub.h>
|
||||||
#include <sys_ctrl.h>
|
#include <sys_ctrl.h>
|
||||||
#include <sys_rtos.h>
|
#include <sys_rtos.h>
|
||||||
|
|||||||
17
cores/common/arduino/src/wiring.c
Normal file
17
cores/common/arduino/src/wiring.c
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* Copyright (c) Kuba Szczodrzyński 2023-05-24. */
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#if LT_HAS_FREERTOS
|
||||||
|
|
||||||
|
__attribute__((weak)) void delay(uint32_t ms) {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((weak)) void yield() {
|
||||||
|
runPeriodicTasks();
|
||||||
|
vTaskDelay(1);
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-20. */
|
/* Copyright (c) Kuba Szczodrzyński 2022-06-20. */
|
||||||
|
|
||||||
#include "wiring_custom.h"
|
#include "wiring_private.h"
|
||||||
|
|
||||||
#if LT_HAS_FREERTOS
|
#if LT_HAS_FREERTOS
|
||||||
#include <FreeRTOS.h>
|
#include <FreeRTOS.h>
|
||||||
@@ -32,6 +32,18 @@ void runPeriodicTasks() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable modes specified by 'mask'.
|
||||||
|
*/
|
||||||
|
void pinModeRemove(pin_size_t pinNumber, uint32_t mask) {
|
||||||
|
PinInfo *pin = pinInfo(pinNumber);
|
||||||
|
if (!pin)
|
||||||
|
return;
|
||||||
|
pinRemoveMode(pin, mask);
|
||||||
|
if (pin->enabled == PIN_NONE && mask == PIN_MODE_ALL)
|
||||||
|
pinRemoveData(pin);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get PinInfo struct for the specified number.
|
* @brief Get PinInfo struct for the specified number.
|
||||||
* Returns NULL if pin number is invalid.
|
* Returns NULL if pin number is invalid.
|
||||||
@@ -85,20 +97,6 @@ bool pinEnabled(PinInfo *pin, uint32_t mask) {
|
|||||||
return (pin->enabled & mask) == mask;
|
return (pin->enabled & mask) == mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if GPIO pin is configured as output.
|
|
||||||
*/
|
|
||||||
bool pinIsOutput(PinInfo *pin) {
|
|
||||||
return pin->mode == OUTPUT || pin->mode == OUTPUT_OPENDRAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if GPIO pin is configured as output.
|
|
||||||
*/
|
|
||||||
bool pinIsInput(PinInfo *pin) {
|
|
||||||
return pin->mode == INPUT || pin->mode == INPUT_PULLUP || pin->mode == INPUT_PULLDOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read voltage from ADC and return a value between 0 and
|
* @brief Read voltage from ADC and return a value between 0 and
|
||||||
* the current reading resolution.
|
* the current reading resolution.
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ extern "C" {
|
|||||||
#define PIN_SWD (1 << 10)
|
#define PIN_SWD (1 << 10)
|
||||||
#define PIN_UART (1 << 11)
|
#define PIN_UART (1 << 11)
|
||||||
|
|
||||||
#define PIN_INVALID 255
|
#define PIN_MODE_ALL 0xFFFFFFFF
|
||||||
|
#define PIN_INVALID 255
|
||||||
|
|
||||||
|
typedef struct PinData_s PinData;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/**
|
/**
|
||||||
@@ -37,9 +40,9 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
uint32_t enabled;
|
uint32_t enabled;
|
||||||
/**
|
/**
|
||||||
* @brief Pin mode (direction, IRQ level, etc.).
|
* @brief Pin data (direction, IRQ level, etc.). The structure is family-specific.
|
||||||
*/
|
*/
|
||||||
uint32_t mode;
|
PinData *data;
|
||||||
} PinInfo;
|
} PinInfo;
|
||||||
|
|
||||||
extern PinInfo lt_arduino_pin_info_list[PINS_COUNT];
|
extern PinInfo lt_arduino_pin_info_list[PINS_COUNT];
|
||||||
@@ -57,14 +60,21 @@ bool startMainTask(void);
|
|||||||
void mainTask(const void *arg); // implemented in main.cpp
|
void mainTask(const void *arg); // implemented in main.cpp
|
||||||
void runPeriodicTasks(); // implemented in wiring_custom.c
|
void runPeriodicTasks(); // implemented in wiring_custom.c
|
||||||
|
|
||||||
|
void pinModeRemove(pin_size_t pinNumber, uint32_t mask);
|
||||||
PinInfo *pinInfo(pin_size_t pinNumber);
|
PinInfo *pinInfo(pin_size_t pinNumber);
|
||||||
PinInfo *pinByIndex(uint32_t index);
|
PinInfo *pinByIndex(uint32_t index);
|
||||||
PinInfo *pinByGpio(uint32_t gpio);
|
PinInfo *pinByGpio(uint32_t gpio);
|
||||||
uint32_t pinIndex(PinInfo *pin);
|
uint32_t pinIndex(PinInfo *pin);
|
||||||
bool pinSupported(PinInfo *pin, uint32_t mask);
|
bool pinSupported(PinInfo *pin, uint32_t mask);
|
||||||
bool pinEnabled(PinInfo *pin, uint32_t mask);
|
bool pinEnabled(PinInfo *pin, uint32_t mask);
|
||||||
bool pinIsOutput(PinInfo *pin);
|
void pinRemoveMode(PinInfo *pin, uint32_t mask);
|
||||||
bool pinIsInput(PinInfo *pin);
|
|
||||||
|
/**
|
||||||
|
* @brief Deinitialize the pin, by removing all enabled modes.
|
||||||
|
*/
|
||||||
|
inline void pinModeNone(pin_size_t pinNumber) {
|
||||||
|
pinModeRemove(pinNumber, PIN_MODE_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
int analogRead(pin_size_t pinNumber);
|
int analogRead(pin_size_t pinNumber);
|
||||||
void analogReadResolution(int res);
|
void analogReadResolution(int res);
|
||||||
|
|||||||
7
cores/common/arduino/src/wiring_irq.c
Normal file
7
cores/common/arduino/src/wiring_irq.c
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/* Copyright (c) Kuba Szczodrzyński 2023-05-24. */
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode) {
|
||||||
|
attachInterruptParam(interruptNumber, (voidFuncPtrParam)callback, mode, NULL);
|
||||||
|
}
|
||||||
25
cores/common/arduino/src/wiring_private.c
Normal file
25
cores/common/arduino/src/wiring_private.c
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/* Copyright (c) Kuba Szczodrzyński 2023-05-24. */
|
||||||
|
|
||||||
|
#include "wiring_private.h"
|
||||||
|
|
||||||
|
#if __has_include(<wiring_data.h>)
|
||||||
|
/**
|
||||||
|
* @brief Allocate and return a PinData structure (family-specific).
|
||||||
|
*/
|
||||||
|
PinData *pinData(PinInfo *pin) {
|
||||||
|
if (pin->data == NULL) {
|
||||||
|
pin->data = calloc(1, sizeof(PinData));
|
||||||
|
}
|
||||||
|
return (PinData *)pin->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deallocate the PinData structure.
|
||||||
|
*/
|
||||||
|
void pinRemoveData(PinInfo *pin) {
|
||||||
|
if (pin->data != NULL) {
|
||||||
|
free(pin->data);
|
||||||
|
}
|
||||||
|
pin->data = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
64
cores/common/arduino/src/wiring_private.h
Normal file
64
cores/common/arduino/src/wiring_private.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/* Copyright (c) Kuba Szczodrzyński 2023-05-24. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#if __has_include(<sdk_private.h>)
|
||||||
|
#include <sdk_private.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<wiring_data.h>)
|
||||||
|
#include <wiring_data.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PinData *pinData(PinInfo *pin);
|
||||||
|
void pinRemoveData(PinInfo *pin);
|
||||||
|
|
||||||
|
inline void pinEnable(PinInfo *pin, uint32_t mask) {
|
||||||
|
pin->enabled |= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void pinDisable(PinInfo *pin, uint32_t mask) {
|
||||||
|
pin->enabled &= ~mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define pinCheckGetInfo(pinNumber, mask, ret) \
|
||||||
|
PinInfo *pin = pinInfo(pinNumber); \
|
||||||
|
if (!pin) \
|
||||||
|
return ret; \
|
||||||
|
if (!pinSupported(pin, mask)) \
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
#define pinCheckGetData(pinNumber, mask, ret) \
|
||||||
|
PinInfo *pin = pinInfo(pinNumber); \
|
||||||
|
if (!pin) \
|
||||||
|
return ret; \
|
||||||
|
if (!pinSupported(pin, mask)) \
|
||||||
|
return ret; \
|
||||||
|
PinData *data = pinData(pin);
|
||||||
|
|
||||||
|
#define pinIsOutput(pin, data) (pinEnabled(pin, PIN_GPIO) && (data->gpioMode ^ 0b101) < 5)
|
||||||
|
#define pinIsInput(pin, data) (pinEnabled(pin, PIN_GPIO) && (data->gpioMode ^ 0b101) > 4)
|
||||||
|
|
||||||
|
#define pinSetOutputPull(pin, data, pinNumber, status) \
|
||||||
|
do { \
|
||||||
|
if (!pinIsOutput(pin, data)) { \
|
||||||
|
pinMode(pinNumber, INPUT_PULLDOWN ^ !!status); \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
#define pinSetInputMode(pin, data, pinNumber) \
|
||||||
|
do { \
|
||||||
|
if (!pinIsInput(pin, data)) \
|
||||||
|
pinMode(pinNumber, INPUT); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
extern void pinRemoveMode(pin_size_t pinNumber);
|
|
||||||
extern void _tone(uint32_t ulPin, unsigned int frequency, unsigned long duration);
|
|
||||||
|
|
||||||
void tone(uint32_t ulPin, unsigned int frequency, unsigned long duration) {
|
|
||||||
_tone(ulPin, frequency, duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
void noTone(uint32_t ulPin) {
|
|
||||||
pinRemoveMode(ulPin);
|
|
||||||
}
|
|
||||||
@@ -1,48 +1,11 @@
|
|||||||
/*
|
/* Copyright (c) Kuba Szczodrzyński 2022-04-23. */
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
#include "wiring_private.h"
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
#include <cmsis_os.h>
|
|
||||||
|
|
||||||
#ifndef portNVIC_SYSTICK_CURRENT_VALUE_REG
|
#ifndef portNVIC_SYSTICK_CURRENT_VALUE_REG
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG (*((volatile uint32_t *)0xe000e018))
|
#define portNVIC_SYSTICK_CURRENT_VALUE_REG (*((volatile uint32_t *)0xe000e018))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern uint32_t xTaskGetTickCount();
|
|
||||||
extern uint32_t xTaskGetTickCountFromISR();
|
|
||||||
|
|
||||||
static __inline uint32_t __get_ipsr__(void) {
|
|
||||||
volatile uint32_t __regIPSR __asm("ipsr");
|
|
||||||
return (__regIPSR);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *gpio_pin_struct[PINS_COUNT] = {NULL};
|
|
||||||
|
|
||||||
void delay(uint32_t ms) {
|
|
||||||
/* osStatus ret; */
|
|
||||||
|
|
||||||
/* ret = */ osDelay(ms);
|
|
||||||
/* if ((ret != osEventTimeout) && (ret != osOK)) {
|
|
||||||
printf("delay : ERROR : 0x%x \n", ret);
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
|
|
||||||
void delayMicroseconds(unsigned int us) {
|
void delayMicroseconds(unsigned int us) {
|
||||||
int i;
|
int i;
|
||||||
uint32_t t0, tn;
|
uint32_t t0, tn;
|
||||||
@@ -61,7 +24,7 @@ void delayMicroseconds(unsigned int us) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned long millis(void) {
|
unsigned long millis(void) {
|
||||||
return (__get_ipsr__() == 0) ? xTaskGetTickCount() : xTaskGetTickCountFromISR();
|
return (__get_IPSR() == 0) ? xTaskGetTickCount() : xTaskGetTickCountFromISR();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long micros(void) {
|
unsigned long micros(void) {
|
||||||
@@ -69,7 +32,7 @@ unsigned long micros(void) {
|
|||||||
uint32_t us;
|
uint32_t us;
|
||||||
uint32_t tick_per_us = F_CPU / 1000;
|
uint32_t tick_per_us = F_CPU / 1000;
|
||||||
|
|
||||||
if (__get_ipsr__() == 0) {
|
if (__get_IPSR() == 0) {
|
||||||
tick1 = xTaskGetTickCount();
|
tick1 = xTaskGetTickCount();
|
||||||
us = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
us = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
tick2 = xTaskGetTickCount();
|
tick2 = xTaskGetTickCount();
|
||||||
@@ -88,8 +51,22 @@ unsigned long micros(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void yield(void) {
|
void pinRemoveMode(PinInfo *pin, uint32_t mask) {
|
||||||
runPeriodicTasks();
|
PinData *data = pinData(pin);
|
||||||
vTaskDelay(1);
|
if ((mask & PIN_GPIO) && (pin->enabled & PIN_GPIO)) {
|
||||||
taskYIELD();
|
gpio_deinit(data->gpio);
|
||||||
|
free(data->gpio);
|
||||||
|
pinDisable(pin, PIN_GPIO);
|
||||||
|
}
|
||||||
|
if ((mask & PIN_IRQ) && (pin->enabled & PIN_IRQ)) {
|
||||||
|
data->irqHandler = NULL;
|
||||||
|
gpio_irq_free(data->irq);
|
||||||
|
free(data->irq);
|
||||||
|
pinDisable(pin, PIN_IRQ);
|
||||||
|
}
|
||||||
|
if ((mask & PIN_PWM) && (pin->enabled & PIN_PWM)) {
|
||||||
|
pwmout_free(data->pwm);
|
||||||
|
free(data->pwm);
|
||||||
|
pinDisable(pin, PIN_PWM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,6 @@
|
|||||||
/*
|
/* Copyright (c) Kuba Szczodrzyński 2022-06-20. */
|
||||||
Copyright (c) 2011 Arduino. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
#include "wiring_private.h"
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <sdk_private.h>
|
|
||||||
|
|
||||||
/* ADC */
|
/* ADC */
|
||||||
static analogin_t adc1;
|
static analogin_t adc1;
|
||||||
@@ -28,17 +11,13 @@ static bool g_adc_enabled[] = {false, false, false};
|
|||||||
// from realtek_amebaz_va0_example/example_sources/adc_vbat/src/main.c
|
// from realtek_amebaz_va0_example/example_sources/adc_vbat/src/main.c
|
||||||
#define AD2MV(ad, offset, gain) (((ad >> 4) - offset) * 1000 / gain)
|
#define AD2MV(ad, offset, gain) (((ad >> 4) - offset) * 1000 / gain)
|
||||||
|
|
||||||
extern void *gpio_pin_struct[];
|
|
||||||
|
|
||||||
extern void pinRemoveMode(pin_size_t pinNumber);
|
|
||||||
|
|
||||||
// TODO implement custom ADC calibration
|
// TODO implement custom ADC calibration
|
||||||
|
|
||||||
uint16_t analogReadVoltage(pin_size_t pinNumber) {
|
uint16_t analogReadVoltage(pin_size_t pinNumber) {
|
||||||
uint16_t ret = 0;
|
uint16_t ret = 0;
|
||||||
switch (pinNumber) {
|
switch (pinNumber) {
|
||||||
#ifdef PIN_A1
|
#ifdef PIN_ADC2
|
||||||
case PIN_A1:
|
case PIN_ADC2:
|
||||||
if (g_adc_enabled[1] == false) {
|
if (g_adc_enabled[1] == false) {
|
||||||
analogin_init(&adc2, AD_2);
|
analogin_init(&adc2, AD_2);
|
||||||
g_adc_enabled[1] = true;
|
g_adc_enabled[1] = true;
|
||||||
@@ -47,8 +26,8 @@ uint16_t analogReadVoltage(pin_size_t pinNumber) {
|
|||||||
// AD_1 - 0.0V-5.0V
|
// AD_1 - 0.0V-5.0V
|
||||||
return AD2MV(ret, 0x496, 0xBA);
|
return AD2MV(ret, 0x496, 0xBA);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PIN_A0
|
#ifdef PIN_ADC1
|
||||||
case PIN_A0:
|
case PIN_ADC1:
|
||||||
if (g_adc_enabled[0] == false) {
|
if (g_adc_enabled[0] == false) {
|
||||||
analogin_init(&adc1, AD_1);
|
analogin_init(&adc1, AD_1);
|
||||||
g_adc_enabled[0] = true;
|
g_adc_enabled[0] = true;
|
||||||
@@ -56,8 +35,8 @@ uint16_t analogReadVoltage(pin_size_t pinNumber) {
|
|||||||
ret = analogin_read_u16(&adc1);
|
ret = analogin_read_u16(&adc1);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef PIN_A2
|
#ifdef PIN_ADC3
|
||||||
case PIN_A2:
|
case PIN_ADC3:
|
||||||
if (g_adc_enabled[2] == false) {
|
if (g_adc_enabled[2] == false) {
|
||||||
analogin_init(&adc3, AD_3);
|
analogin_init(&adc3, AD_3);
|
||||||
g_adc_enabled[2] = true;
|
g_adc_enabled[2] = true;
|
||||||
@@ -82,27 +61,20 @@ uint16_t analogReadMaxVoltage(pin_size_t pinNumber) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void analogWrite(pin_size_t pinNumber, int value) {
|
void analogWrite(pin_size_t pinNumber, int value) {
|
||||||
PinInfo *pin = pinInfo(pinNumber);
|
pinCheckGetData(pinNumber, PIN_PWM, );
|
||||||
if (!pin)
|
|
||||||
return;
|
|
||||||
pwmout_t *obj;
|
|
||||||
|
|
||||||
if (pinSupported(pin, PIN_PWM)) {
|
// GPIO can't be used together with PWM
|
||||||
float percent = value * 1.0 / (1 << _analogWriteResolution);
|
pinRemoveMode(pin, PIN_GPIO | PIN_IRQ);
|
||||||
if (pin->enabled != PIN_PWM) {
|
|
||||||
if ((pin->enabled == PIN_GPIO) || (pin->enabled == PIN_IRQ)) {
|
pwmout_t *pwm = data->pwm;
|
||||||
pinRemoveMode(pinNumber);
|
if (!pwm) {
|
||||||
}
|
// allocate memory if pin not used before
|
||||||
gpio_pin_struct[pinNumber] = malloc(sizeof(pwmout_t));
|
data->pwm = pwm = malloc(sizeof(pwmout_t));
|
||||||
pwmout_t *obj = (pwmout_t *)gpio_pin_struct[pinNumber];
|
pwmout_init(pwm, pin->gpio);
|
||||||
pwmout_init(obj, pin->gpio);
|
pwmout_period_us(pwm, _analogWritePeriod);
|
||||||
pwmout_period_us(obj, _analogWritePeriod);
|
pinEnable(pin, PIN_PWM);
|
||||||
pwmout_write(obj, percent);
|
|
||||||
pin->enabled = PIN_PWM;
|
|
||||||
} else {
|
|
||||||
pwmout_t *obj = (pwmout_t *)gpio_pin_struct[pinNumber];
|
|
||||||
// pwmout_period_us(obj, _writePeriod);
|
|
||||||
pwmout_write(obj, percent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float percent = value * 1.0 / (1 << _analogWriteResolution);
|
||||||
|
pwmout_write(pwm, percent);
|
||||||
}
|
}
|
||||||
|
|||||||
24
cores/realtek-amb/arduino/src/wiring_data.h
Normal file
24
cores/realtek-amb/arduino/src/wiring_data.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/* Copyright (c) Kuba Szczodrzyński 2023-05-24. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <sdk_private.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct PinData_s {
|
||||||
|
gpio_t *gpio;
|
||||||
|
gpio_irq_t *irq;
|
||||||
|
pwmout_t *pwm;
|
||||||
|
PinMode gpioMode;
|
||||||
|
PinStatus irqMode;
|
||||||
|
void *irqHandler;
|
||||||
|
void *irqParam;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
@@ -1,68 +1,32 @@
|
|||||||
#include <Arduino.h>
|
/* Copyright (c) Kuba Szczodrzyński 2022-04-23. */
|
||||||
#include <sdk_private.h>
|
|
||||||
|
|
||||||
extern void *gpio_pin_struct[PINS_COUNT];
|
#include "wiring_private.h"
|
||||||
|
|
||||||
void pinRemoveMode(pin_size_t pinNumber) {
|
|
||||||
PinInfo *pin = pinInfo(pinNumber);
|
|
||||||
if (!pin)
|
|
||||||
return;
|
|
||||||
if (pinEnabled(pin, PIN_PWM)) {
|
|
||||||
pwmout_t *obj = (pwmout_t *)gpio_pin_struct[pinNumber];
|
|
||||||
pwmout_free(obj);
|
|
||||||
}
|
|
||||||
if (pinEnabled(pin, PIN_GPIO)) {
|
|
||||||
gpio_t *obj = (gpio_t *)gpio_pin_struct[pinNumber];
|
|
||||||
gpio_deinit(obj);
|
|
||||||
free(obj);
|
|
||||||
}
|
|
||||||
if (pinEnabled(pin, PIN_IRQ)) {
|
|
||||||
gpio_irq_t *obj = (gpio_irq_t *)gpio_pin_struct[pinNumber];
|
|
||||||
gpio_irq_deinit(obj);
|
|
||||||
free(obj);
|
|
||||||
}
|
|
||||||
gpio_pin_struct[pinNumber] = NULL;
|
|
||||||
pin->enabled = PIN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pinMode(pin_size_t pinNumber, PinMode pinMode) {
|
void pinMode(pin_size_t pinNumber, PinMode pinMode) {
|
||||||
PinInfo *pin = pinInfo(pinNumber);
|
pinCheckGetData(pinNumber, PIN_GPIO, );
|
||||||
if (!pin)
|
|
||||||
|
if (pinEnabled(pin, PIN_GPIO) && data->gpioMode == pinMode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pinEnabled(pin, PIN_GPIO) && pin->mode == pinMode)
|
#if LT_RTL8720C
|
||||||
// Nothing changes in pin mode
|
// apparently IRQ can't be used with any kind of pull-up/down
|
||||||
return;
|
// TODO verify if it can be used on AmebaZ
|
||||||
|
pinRemoveMode(pin, PIN_PWM | PIN_IRQ);
|
||||||
|
#else
|
||||||
|
// GPIO can't be used together with PWM
|
||||||
|
pinRemoveMode(pin, PIN_PWM);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!pinSupported(pin, PIN_GPIO))
|
gpio_t *gpio = data->gpio;
|
||||||
// cannot set ADC as I/O
|
if (!gpio) {
|
||||||
return;
|
|
||||||
|
|
||||||
/* if (pin->enabled == PIN_PWM) {
|
|
||||||
// If this pin has been configured as PWM, then it cannot change to another mode
|
|
||||||
return;
|
|
||||||
} */
|
|
||||||
|
|
||||||
if (pin->enabled != PIN_GPIO)
|
|
||||||
// pin mode changes; deinit gpio and free memory
|
|
||||||
pinRemoveMode(pinNumber);
|
|
||||||
|
|
||||||
gpio_t *gpio;
|
|
||||||
|
|
||||||
if (pin->enabled == PIN_NONE) {
|
|
||||||
// allocate memory if pin not used before
|
// allocate memory if pin not used before
|
||||||
gpio = malloc(sizeof(gpio_t));
|
data->gpio = gpio = malloc(sizeof(gpio_t));
|
||||||
gpio_pin_struct[pinNumber] = gpio;
|
|
||||||
gpio_init(gpio, pin->gpio);
|
gpio_init(gpio, pin->gpio);
|
||||||
pin->enabled = PIN_GPIO;
|
pinEnable(pin, PIN_GPIO);
|
||||||
} else {
|
|
||||||
// pin already used as gpio
|
|
||||||
gpio = (gpio_t *)gpio_pin_struct[pinNumber];
|
|
||||||
}
|
}
|
||||||
pin->mode = pinMode;
|
|
||||||
|
|
||||||
PinDirection dir;
|
PinDirection dir;
|
||||||
PinMode mode;
|
PinModeRTL mode;
|
||||||
|
|
||||||
switch (pinMode) {
|
switch (pinMode) {
|
||||||
case INPUT:
|
case INPUT:
|
||||||
@@ -88,29 +52,20 @@ void pinMode(pin_size_t pinNumber, PinMode pinMode) {
|
|||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
data->gpioMode = pinMode;
|
||||||
|
|
||||||
gpio_dir(gpio, dir);
|
gpio_dir(gpio, dir);
|
||||||
gpio_mode(gpio, mode);
|
gpio_mode(gpio, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void digitalWrite(pin_size_t pinNumber, PinStatus status) {
|
void digitalWrite(pin_size_t pinNumber, PinStatus status) {
|
||||||
PinInfo *pin = pinInfo(pinNumber);
|
pinCheckGetData(pinNumber, PIN_GPIO, );
|
||||||
if (!pin)
|
pinSetOutputPull(pin, data, pinNumber, status);
|
||||||
return;
|
gpio_write(data->gpio, !!status);
|
||||||
if (pin->enabled != PIN_GPIO)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gpio_t *gpio = (gpio_t *)gpio_pin_struct[pinNumber];
|
|
||||||
gpio_write(gpio, status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PinStatus digitalRead(pin_size_t pinNumber) {
|
PinStatus digitalRead(pin_size_t pinNumber) {
|
||||||
PinInfo *pin = pinInfo(pinNumber);
|
pinCheckGetData(pinNumber, PIN_GPIO, LOW);
|
||||||
if (!pin)
|
pinSetInputMode(pin, data, pinNumber);
|
||||||
return LOW;
|
return gpio_read(data->gpio);
|
||||||
if (pin->enabled != PIN_GPIO)
|
|
||||||
return LOW;
|
|
||||||
|
|
||||||
gpio_t *gpio = (gpio_t *)gpio_pin_struct[pinNumber];
|
|
||||||
return gpio_read(gpio);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,59 +1,50 @@
|
|||||||
#include <Arduino.h>
|
/* Copyright (c) Kuba Szczodrzyński 2022-04-23. */
|
||||||
#include <sdk_private.h>
|
|
||||||
|
|
||||||
extern void *gpio_pin_struct[PINS_COUNT];
|
#include "wiring_private.h"
|
||||||
static void *gpio_irq_handler_list[PINS_COUNT] = {NULL};
|
|
||||||
static void *gpio_irq_handler_args[PINS_COUNT] = {NULL};
|
|
||||||
|
|
||||||
extern void pinRemoveMode(pin_size_t pinNumber);
|
|
||||||
|
|
||||||
static void gpioIrqHandler(uint32_t id, gpio_irq_event event) {
|
static void gpioIrqHandler(uint32_t id, gpio_irq_event event) {
|
||||||
// id is pin index
|
// id is pin data
|
||||||
if (gpio_irq_handler_list[id] != NULL) {
|
PinData *data = (PinData *)id;
|
||||||
if (gpio_irq_handler_args[id] == NULL)
|
if (!data->irqHandler)
|
||||||
((voidFuncPtr)gpio_irq_handler_list[id])();
|
return;
|
||||||
else
|
if (!data->irqParam)
|
||||||
((voidFuncPtrParam)gpio_irq_handler_list[id])(gpio_irq_handler_args[id]);
|
((voidFuncPtr)data->irqHandler)();
|
||||||
}
|
else
|
||||||
}
|
((voidFuncPtrParam)data->irqHandler)(data->irqParam);
|
||||||
|
|
||||||
void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode) {
|
|
||||||
attachInterruptParam(interruptNumber, (voidFuncPtrParam)callback, mode, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void *param) {
|
void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void *param) {
|
||||||
PinInfo *pin = pinInfo(interruptNumber);
|
pinCheckGetData(interruptNumber, PIN_IRQ, );
|
||||||
if (pin == NULL)
|
|
||||||
return;
|
|
||||||
uint32_t index = pinIndex(pin);
|
|
||||||
|
|
||||||
gpio_irq_handler_list[index] = callback;
|
data->irqHandler = callback;
|
||||||
gpio_irq_handler_args[index] = param;
|
data->irqParam = param;
|
||||||
|
|
||||||
if (pin->enabled == PIN_IRQ && pin->mode == mode)
|
if (pinEnabled(pin, PIN_IRQ) && data->irqMode == mode)
|
||||||
// Nothing changes in pin mode
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pin->enabled != PIN_IRQ)
|
#if LT_RTL8720C
|
||||||
// pin mode changes; deinit gpio and free memory
|
// apparently IRQ can't be used with any kind of pull-up/down
|
||||||
pinRemoveMode(interruptNumber);
|
// TODO verify if it can be used on AmebaZ
|
||||||
|
pinRemoveMode(pin, PIN_PWM | PIN_GPIO);
|
||||||
|
#else
|
||||||
|
// GPIO can't be used together with PWM
|
||||||
|
pinRemoveMode(pin, PIN_PWM);
|
||||||
|
#endif
|
||||||
|
|
||||||
gpio_irq_t *gpio;
|
gpio_irq_t *irq = data->irq;
|
||||||
|
if (!irq) {
|
||||||
if (pin->enabled == PIN_NONE) {
|
|
||||||
// allocate memory if pin not used before
|
// allocate memory if pin not used before
|
||||||
gpio = malloc(sizeof(gpio_irq_t));
|
data->irq = irq = malloc(sizeof(gpio_irq_t));
|
||||||
gpio_pin_struct[index] = gpio;
|
if (gpio_irq_init(irq, pin->gpio, gpioIrqHandler, (uint32_t)data) != 0) {
|
||||||
gpio_irq_init(gpio, pin->gpio, gpioIrqHandler, index);
|
LT_W("IRQ init failed");
|
||||||
pin->enabled = PIN_IRQ;
|
free(data->irq);
|
||||||
} else {
|
data->irq = NULL;
|
||||||
// pin already used as irq
|
return;
|
||||||
gpio = (gpio_irq_t *)gpio_pin_struct[index];
|
}
|
||||||
|
pinEnable(pin, PIN_IRQ);
|
||||||
}
|
}
|
||||||
pin->mode = mode;
|
|
||||||
|
|
||||||
gpio_irq_event event;
|
gpio_irq_event event;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case LOW:
|
case LOW:
|
||||||
event = IRQ_LOW;
|
event = IRQ_LOW;
|
||||||
@@ -67,22 +58,22 @@ void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback,
|
|||||||
case RISING:
|
case RISING:
|
||||||
event = IRQ_RISE;
|
event = IRQ_RISE;
|
||||||
break;
|
break;
|
||||||
|
case CHANGE:
|
||||||
|
#if LT_RTL8720C
|
||||||
|
event = IRQ_FALL_RISE;
|
||||||
|
#else
|
||||||
|
LT_W("CHANGE interrupts not supported");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
data->irqMode = mode;
|
||||||
|
|
||||||
gpio_irq_set(gpio, event, 1);
|
gpio_irq_set(irq, event, 1);
|
||||||
gpio_irq_enable(gpio);
|
gpio_irq_enable(irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void detachInterrupt(pin_size_t interruptNumber) {
|
void detachInterrupt(pin_size_t interruptNumber) {
|
||||||
PinInfo *pin = pinInfo(interruptNumber);
|
pinModeRemove(interruptNumber, PIN_IRQ);
|
||||||
if (pin == NULL)
|
|
||||||
return;
|
|
||||||
uint32_t index = pinIndex(pin);
|
|
||||||
|
|
||||||
if (pin->enabled == PIN_IRQ) {
|
|
||||||
pinRemoveMode(interruptNumber);
|
|
||||||
}
|
|
||||||
gpio_irq_handler_list[index] = NULL;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,7 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include "wiring_private.h"
|
||||||
#include <sdk_private.h>
|
|
||||||
|
|
||||||
extern void *gpio_pin_struct[];
|
|
||||||
|
|
||||||
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
|
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
|
||||||
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
|
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
|
||||||
@@ -34,19 +31,17 @@ extern unsigned long pulseIn(uint8_t pinNumber, uint8_t state, unsigned long tim
|
|||||||
return 0;
|
return 0;
|
||||||
uint32_t index = pinIndex(pin);
|
uint32_t index = pinIndex(pin);
|
||||||
|
|
||||||
gpio_t *pGpio_t;
|
|
||||||
|
|
||||||
uint32_t start_ticks, cur_ticks;
|
uint32_t start_ticks, cur_ticks;
|
||||||
|
|
||||||
if (pin->gpio == NC)
|
if (pin->gpio == NC)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Handle */
|
/* Handle */
|
||||||
if (pin->enabled != PIN_GPIO) {
|
if (!pinEnabled(pin, PIN_GPIO)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
PinData *data = pinData(pin);
|
||||||
pGpio_t = (gpio_t *)gpio_pin_struct[index];
|
gpio_t *pGpio_t = data->gpio;
|
||||||
|
|
||||||
// wait for any previous pulse to end
|
// wait for any previous pulse to end
|
||||||
start_ticks = us_ticker_read();
|
start_ticks = us_ticker_read();
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cmsis_os.h>
|
#include <cmsis_os.h>
|
||||||
|
#undef malloc
|
||||||
|
#undef free
|
||||||
|
#undef calloc
|
||||||
|
|
||||||
// mbed APIs
|
// mbed APIs
|
||||||
#include <gpio_api.h>
|
#include <gpio_api.h>
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ lt_reboot_reason_t lt_get_reboot_reason() {
|
|||||||
|
|
||||||
void lt_gpio_recover() {
|
void lt_gpio_recover() {
|
||||||
sys_jtag_off();
|
sys_jtag_off();
|
||||||
|
sys_swd_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*__ __
|
/*__ __
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ extern "C" {
|
|||||||
|
|
||||||
// SDK
|
// SDK
|
||||||
void software_reset();
|
void software_reset();
|
||||||
|
void sys_swd_off();
|
||||||
void sys_uart_download_mode();
|
void sys_uart_download_mode();
|
||||||
void sys_download_mode(uint8_t mode);
|
void sys_download_mode(uint8_t mode);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user