[core] Refactor Wiring, use PinData for parameters

This commit is contained in:
Kuba Szczodrzyński
2023-05-24 18:20:22 +02:00
parent bc74c21599
commit e5f98ff41f
22 changed files with 397 additions and 394 deletions

View 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

View File

@@ -1,6 +1,6 @@
/* Copyright (c) Kuba Szczodrzyński 2022-06-20. */
#include "wiring_custom.h"
#include "wiring_private.h"
#if LT_HAS_FREERTOS
#include <FreeRTOS.h>
@@ -32,6 +32,18 @@ void runPeriodicTasks() {
#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.
* Returns NULL if pin number is invalid.
@@ -85,20 +97,6 @@ bool pinEnabled(PinInfo *pin, uint32_t 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
* the current reading resolution.

View File

@@ -21,7 +21,10 @@ extern "C" {
#define PIN_SWD (1 << 10)
#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 {
/**
@@ -37,9 +40,9 @@ typedef struct {
*/
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;
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 runPeriodicTasks(); // implemented in wiring_custom.c
void pinModeRemove(pin_size_t pinNumber, uint32_t mask);
PinInfo *pinInfo(pin_size_t pinNumber);
PinInfo *pinByIndex(uint32_t index);
PinInfo *pinByGpio(uint32_t gpio);
uint32_t pinIndex(PinInfo *pin);
bool pinSupported(PinInfo *pin, uint32_t mask);
bool pinEnabled(PinInfo *pin, uint32_t mask);
bool pinIsOutput(PinInfo *pin);
bool pinIsInput(PinInfo *pin);
void pinRemoveMode(PinInfo *pin, uint32_t mask);
/**
* @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);
void analogReadResolution(int res);

View 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);
}

View 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

View 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