[realtek-ambz] Rework wiring_digital and WInterrupts

This commit is contained in:
Kuba Szczodrzyński
2022-04-23 22:18:32 +02:00
parent 1165218c0c
commit 7507e17677
4 changed files with 181 additions and 301 deletions

View File

@@ -1,39 +1,84 @@
#include "Arduino.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "gpio_api.h"
#include "gpio_irq_api.h"
#include "gpio_irq_ex_api.h"
extern void *gpio_pin_struct[PINS_COUNT];
extern void *gpio_irq_handler_list[PINS_COUNT];
void gpioIrqHandler(uint32_t id, gpio_irq_event event) {
if (gpio_irq_handler_list[id] != NULL) {
((void (*)(uint32_t, uint32_t))gpio_irq_handler_list[id])(id, (uint32_t)event);
}
}
void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode) {
if ( g_APinDescription[interruptNumber].ulPinType != PIO_GPIO_IRQ ) {
pinRemoveMode(interruptNumber);
}
if (pinInvalid(interruptNumber))
return;
switch(mode) {
case LOW:
pinMode(interruptNumber, INPUT_IRQ_LOW);
digitalSetIrqHandler(interruptNumber, (void *)callback);
break;
gpio_irq_handler_list[interruptNumber] = callback;
case HIGH:
pinMode(interruptNumber, INPUT_IRQ_HIGH);
digitalSetIrqHandler(interruptNumber, (void *)callback);
break;
if (g_APinDescription[interruptNumber].ulPinType == PIO_GPIO_IRQ &&
g_APinDescription[interruptNumber].ulPinMode == mode)
// Nothing changes in pin mode
return;
case FALLING:
pinMode(interruptNumber, INPUT_IRQ_FALL);
digitalSetIrqHandler(interruptNumber, (void *)callback);
break;
if (g_APinDescription[interruptNumber].ulPinType != PIO_GPIO_IRQ)
// pin mode changes; deinit gpio and free memory
pinRemoveMode(interruptNumber);
case RISING:
pinMode(interruptNumber, INPUT_IRQ_RISE);
digitalSetIrqHandler(interruptNumber, (void *)callback);
break;
gpio_irq_t *gpio;
case CHANGE:
// TODO
break;
}
if (g_APinDescription[interruptNumber].ulPinType == NOT_INITIAL) {
// allocate memory if pin not used before
gpio = malloc(sizeof(gpio_irq_t));
gpio_pin_struct[interruptNumber] = gpio;
gpio_irq_init(gpio, g_APinDescription[interruptNumber].pinname, gpioIrqHandler, interruptNumber);
g_APinDescription[interruptNumber].ulPinType = PIO_GPIO_IRQ;
} else {
// pin already used as irq
gpio = (gpio_irq_t *)gpio_pin_struct[interruptNumber];
}
g_APinDescription[interruptNumber].ulPinMode = mode;
gpio_irq_event event;
switch (mode) {
case LOW:
event = IRQ_LOW;
break;
case HIGH:
event = IRQ_HIGH;
break;
case FALLING:
event = IRQ_FALL;
break;
case RISING:
event = IRQ_RISE;
break;
default:
return;
}
gpio_irq_set(gpio, event, 1);
gpio_irq_enable(gpio);
}
void detachInterrupt(pin_size_t interruptNumber) {
if ( g_APinDescription[interruptNumber].ulPinType == PIO_GPIO_IRQ ) {
pinRemoveMode(interruptNumber);
}
if (pinInvalid(interruptNumber))
return;
if (g_APinDescription[interruptNumber].ulPinType == PIO_GPIO_IRQ) {
pinRemoveMode(interruptNumber);
}
gpio_irq_handler_list[interruptNumber] = NULL;
}
#ifdef __cplusplus
}
#endif

View File

@@ -40,30 +40,6 @@ extern void yield(void);
#define sprintf rtl_sprintf
#endif
/*
extern void *pvPortMalloc( size_t xWantedSize );
extern void vPortFree( void *pv );
extern void *pvPortReAlloc( void *pv, size_t xWantedSize );
extern size_t xPortGetFreeHeapSize( void );
extern size_t xPortGetMinimumEverFreeHeapSize( void );
extern void *tcm_heap_malloc(int size);
extern void *tcm_heap_calloc(int size);
extern void tcm_heap_free(void * mem);
extern void tcm_heap_dump(void);
extern int tcm_heap_freeSpace(void);
#ifndef malloc
#define malloc pvPortMalloc
#endif
#ifndef free
#define free vPortFree
#endif
#ifndef realloc
#define realloc pvPortReAlloc
#endif
*/
#define NOT_INITIAL (1UL<<0)
#define PIO_GPIO (1UL<<1)
#define PIO_PWM (1UL<<2)
@@ -78,32 +54,26 @@ extern int tcm_heap_freeSpace(void);
/* Types used for the tables below */
typedef struct _PinDescription
{
// HW PinNames
uint32_t pinname;
// Current Pin Type
uint32_t ulPinType;
// Supported Pin Function
uint32_t ulPinAttribute;
// Current Pin Mode
uint32_t ulPinMode;
} PinDescription ;
/* Pins table to be instanciated into variant.cpp */
extern PinDescription g_APinDescription[];
extern bool pinInvalid(pin_size_t pinNumber);
extern void pinRemoveMode(pin_size_t pinNumber);
/* moved from wiring_digital.h */
extern void digitalChangeDir( uint32_t ulPin, uint8_t direction);
/**************************** Extend API by RTK ***********************************/
extern uint32_t digitalPinToPort( uint32_t ulPin );
extern uint32_t digitalPinToBitMask( uint32_t ulPin );
extern uint32_t digitalSetIrqHandler( uint32_t ulPin, void (*handler)(uint32_t id, uint32_t event) );
extern uint32_t digitalClearIrqHandler( uint32_t ulPin );
extern void pinRemoveMode(uint32_t ulPin);
extern uint32_t digitalPinToPort( uint32_t pinNumber );
extern uint32_t digitalPinToBitMask( uint32_t pinNumber );
/* moved from wiring_analog.h */
/*
@@ -122,23 +92,9 @@ extern void analogOutputInit( void ) ;
extern void analogWritePeriod(int us);
/* moved from wiring_constants.h */
// TODO use these correctly in wiring
// #define INPUT_PULLDOWN INPUT
// #define INPUT_PULLNONE 0x03
#define INPUT_IRQ_FALL 0x05
#define INPUT_IRQ_RISE 0x06
#define INPUT_IRQ_LOW 0x07
#define INPUT_IRQ_HIGH 0x08
#define DEFAULT 1
#define EXTERNAL 0
// undefine stdlib's abs if encountered
/* #ifdef abs
#undef abs
#endif // abs
#define abs(x) ((x)>0?(x):-(x)) */
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
extern uint32_t ulPortSetInterruptMask( void );

View File

@@ -1,21 +1,3 @@
/*
Copyright (c) 2011 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Arduino.h"
#ifdef __cplusplus
@@ -30,234 +12,131 @@ extern "C" {
extern void *gpio_pin_struct[PINS_COUNT];
extern void *gpio_irq_handler_list[PINS_COUNT];
void gpioIrqHandler(uint32_t id, gpio_irq_event event) {
if ( gpio_irq_handler_list[id] != NULL ) {
( (void (*)(uint32_t,uint32_t) )gpio_irq_handler_list[id] ) ( id, (uint32_t)event );
}
bool pinInvalid(pin_size_t pinNumber) {
return pinNumber < 0 || pinNumber > PINS_COUNT || g_APinDescription[pinNumber].pinname == NC;
}
void pinMode(pin_size_t pinNumber, PinModeArduino pinMode)
{
void *pGpio_t;
if ( pinNumber < 0 || pinNumber > PINS_COUNT || (g_APinDescription[pinNumber].pinname == NC) )
{
// Invalid pin
return;
}
if ( (g_APinDescription[pinNumber].ulPinType == PIO_GPIO || g_APinDescription[pinNumber].ulPinType == PIO_GPIO_IRQ)
&& g_APinDescription[pinNumber].ulPinMode == pinMode)
{
// Nothing changes in pin mode
return;
}
if ( g_APinDescription[pinNumber].ulPinType == PIO_PWM ) {
// If this pin has been configured as PWM, then it cannot change to another mode
return;
}
if ( g_APinDescription[pinNumber].ulPinType == PIO_GPIO &&
(pinMode == INPUT_IRQ_FALL || pinMode == INPUT_IRQ_RISE) ) {
// Pin mode changes from gpio_t to gpio_irq_t
pinRemoveMode(pinNumber);
}
if ( g_APinDescription[pinNumber].ulPinType == PIO_GPIO_IRQ &&
(pinMode == INPUT || pinMode == OUTPUT || pinMode == INPUT_PULLUP || pinMode == INPUT_PULLDOWN || pinMode == OUTPUT_OPENDRAIN) ) {
// Pin mode changes from gpio_irq_t to gpio_t
pinRemoveMode(pinNumber);
}
if ( g_APinDescription[pinNumber].ulPinType == NOT_INITIAL ) {
if (pinMode == INPUT_IRQ_FALL || pinMode == INPUT_IRQ_RISE || pinMode == INPUT_IRQ_LOW || pinMode == INPUT_IRQ_HIGH) {
gpio_pin_struct[pinNumber] = malloc ( sizeof(gpio_irq_t) );
pGpio_t = gpio_pin_struct[pinNumber];
gpio_irq_init( pGpio_t, g_APinDescription[pinNumber].pinname, gpioIrqHandler, pinNumber);
g_APinDescription[pinNumber].ulPinType = PIO_GPIO_IRQ;
} else {
gpio_pin_struct[pinNumber] = malloc ( sizeof(gpio_t) );
pGpio_t = gpio_pin_struct[pinNumber];
gpio_init( pGpio_t, g_APinDescription[pinNumber].pinname );
g_APinDescription[pinNumber].ulPinType = PIO_GPIO;
}
g_APinDescription[pinNumber].ulPinMode = pinMode;
} else {
pGpio_t = gpio_pin_struct[pinNumber];
}
switch ( pinMode )
{
case INPUT:
gpio_dir( (gpio_t *)pGpio_t, PIN_INPUT );
gpio_mode( (gpio_t *)pGpio_t, PullNone );
break;
case INPUT_PULLDOWN:
gpio_dir( (gpio_t *)pGpio_t, PIN_INPUT );
gpio_mode( (gpio_t *)pGpio_t, PullDown );
break;
case INPUT_PULLUP:
gpio_dir( (gpio_t *)pGpio_t, PIN_INPUT );
gpio_mode( (gpio_t *)pGpio_t, PullUp );
break;
case OUTPUT:
gpio_dir( (gpio_t *)pGpio_t, PIN_OUTPUT );
gpio_mode( (gpio_t *)pGpio_t, PullNone );
break;
case OUTPUT_OPENDRAIN:
gpio_dir( (gpio_t *)pGpio_t, PIN_OUTPUT );
gpio_mode( (gpio_t *)pGpio_t, OpenDrain );
break;
case INPUT_IRQ_FALL:
gpio_irq_set( (gpio_irq_t *)pGpio_t, IRQ_FALL, 1 );
gpio_irq_enable( (gpio_irq_t *)pGpio_t );
break;
case INPUT_IRQ_RISE:
gpio_irq_set( (gpio_irq_t *)pGpio_t, IRQ_RISE, 1 );
gpio_irq_enable( (gpio_irq_t *)pGpio_t );
break;
case INPUT_IRQ_LOW:
gpio_irq_set( (gpio_irq_t *)pGpio_t, IRQ_LOW, 1 );
gpio_irq_enable( (gpio_irq_t *)pGpio_t );
break;
case INPUT_IRQ_HIGH:
gpio_irq_set( (gpio_irq_t *)pGpio_t, IRQ_HIGH, 1 );
gpio_irq_enable( (gpio_irq_t *)pGpio_t );
break;
default:
break ;
}
void pinRemoveMode(pin_size_t pinNumber) {
if (pinInvalid(pinNumber))
return;
if (g_APinDescription[pinNumber].ulPinType == PIO_PWM) {
pwmout_t *obj = (pwmout_t *)gpio_pin_struct[pinNumber];
pwmout_free(obj);
}
if (g_APinDescription[pinNumber].ulPinType == PIO_GPIO) {
gpio_t *obj = (gpio_t *)gpio_pin_struct[pinNumber];
gpio_deinit(obj, g_APinDescription[pinNumber].pinname);
free(obj);
}
if (g_APinDescription[pinNumber].ulPinType == PIO_GPIO_IRQ) {
gpio_irq_t *obj = (gpio_irq_t *)gpio_pin_struct[pinNumber];
gpio_irq_deinit(obj);
free(obj);
}
gpio_pin_struct[pinNumber] = NULL;
g_APinDescription[pinNumber].ulPinType = NOT_INITIAL;
g_APinDescription[pinNumber].ulPinMode = NOT_INITIAL;
}
void digitalWrite(pin_size_t pinNumber, PinStatus status)
{
gpio_t *pGpio_t;
void pinMode(pin_size_t pinNumber, PinModeArduino pinMode) {
if (pinInvalid(pinNumber))
return;
if ( pinNumber < 0 || pinNumber > PINS_COUNT || (g_APinDescription[pinNumber].pinname == NC) )
{
return;
}
if (g_APinDescription[pinNumber].ulPinType == PIO_GPIO && g_APinDescription[pinNumber].ulPinMode == pinMode)
// Nothing changes in pin mode
return;
if ( g_APinDescription[pinNumber].ulPinType != PIO_GPIO )
{
return;
}
/* if (g_APinDescription[pinNumber].ulPinType == PIO_PWM) {
// If this pin has been configured as PWM, then it cannot change to another mode
return;
} */
pGpio_t = (gpio_t *)gpio_pin_struct[pinNumber];
if (g_APinDescription[pinNumber].ulPinType != PIO_GPIO)
// pin mode changes; deinit gpio and free memory
pinRemoveMode(pinNumber);
gpio_write( pGpio_t, status );
gpio_t *gpio;
if (g_APinDescription[pinNumber].ulPinType == NOT_INITIAL) {
// allocate memory if pin not used before
gpio = malloc(sizeof(gpio_t));
gpio_pin_struct[pinNumber] = gpio;
gpio_init(gpio, g_APinDescription[pinNumber].pinname);
g_APinDescription[pinNumber].ulPinType = PIO_GPIO;
} else {
// pin already used as gpio
gpio = (gpio_t *)gpio_pin_struct[pinNumber];
}
g_APinDescription[pinNumber].ulPinMode = pinMode;
PinDirection dir;
PinMode mode;
switch (pinMode) {
case INPUT:
dir = PIN_INPUT;
mode = PullNone;
break;
case INPUT_PULLDOWN:
dir = PIN_INPUT;
mode = PullDown;
break;
case INPUT_PULLUP:
dir = PIN_INPUT;
mode = PullUp;
break;
case OUTPUT:
dir = PIN_OUTPUT;
mode = PullNone;
break;
case OUTPUT_OPENDRAIN:
dir = PIN_OUTPUT;
mode = OpenDrain;
break;
default:
return;
}
gpio_dir(gpio, dir);
gpio_mode(gpio, mode);
}
PinStatus digitalRead(pin_size_t pinNumber)
{
gpio_t *pGpio_t;
int pin_status;
void digitalWrite(pin_size_t pinNumber, PinStatus status) {
if (pinInvalid(pinNumber))
return;
if (g_APinDescription[pinNumber].ulPinType != PIO_GPIO)
return;
if ( pinNumber < 0 || pinNumber > PINS_COUNT || (g_APinDescription[pinNumber].pinname == NC) )
{
return -1;
}
if ( g_APinDescription[pinNumber].ulPinType != PIO_GPIO )
{
return -1;
}
pGpio_t = (gpio_t *)gpio_pin_struct[pinNumber];
pin_status = gpio_read( pGpio_t );
return pin_status;
gpio_t *gpio = (gpio_t *)gpio_pin_struct[pinNumber];
gpio_write(gpio, status);
}
void digitalChangeDir( uint32_t ulPin, uint8_t direction)
{
gpio_t *pGpio_t;
u32 RegValue;
PinStatus digitalRead(pin_size_t pinNumber) {
if (pinInvalid(pinNumber))
return;
if (g_APinDescription[pinNumber].ulPinType != PIO_GPIO)
return;
if ( ulPin < 0 || ulPin > PINS_COUNT || (g_APinDescription[ulPin].pinname == NC) )
{
return;
}
if ( g_APinDescription[ulPin].ulPinType != PIO_GPIO )
{
return;
}
pGpio_t = (gpio_t *)gpio_pin_struct[ulPin];
gpio_dir( pGpio_t, direction );
gpio_t *gpio = (gpio_t *)gpio_pin_struct[pinNumber];
return gpio_read(gpio);
}
/**************************** Extend API by RTK ***********************************/
uint32_t digitalPinToPort( uint32_t ulPin )
{
uint32_t pin_name;
uint32_t digitalPinToPort(uint32_t pinNumber) {
if (pinInvalid(pinNumber))
return 0xFFFFFFFF;
if ( ulPin < 0 || ulPin > PINS_COUNT || (g_APinDescription[ulPin].pinname == NC) )
{
return 0xFFFFFFFF;
}
pin_name = HAL_GPIO_GetPinName(g_APinDescription[ulPin].pinname);
return HAL_GPIO_GET_PORT_BY_NAME(pin_name);
uint32_t pin_name = HAL_GPIO_GetPinName(g_APinDescription[pinNumber].pinname);
return HAL_GPIO_GET_PORT_BY_NAME(pin_name);
}
uint32_t digitalPinToBitMask( uint32_t ulPin )
{
uint32_t pin_name;
uint32_t digitalPinToBitMask(uint32_t pinNumber) {
if (pinInvalid(pinNumber))
return 0xFFFFFFFF;
if ( ulPin < 0 || ulPin > PINS_COUNT || (g_APinDescription[ulPin].pinname == NC) )
{
return 0xFFFFFFFF;
}
pin_name = HAL_GPIO_GetPinName(g_APinDescription[ulPin].pinname);
return 1 << (HAL_GPIO_GET_PIN_BY_NAME(pin_name));
}
uint32_t digitalSetIrqHandler( uint32_t ulPin, void (*handler)(uint32_t id, uint32_t event) ) {
gpio_irq_handler_list[ulPin] = (void *) handler;
}
uint32_t digitalClearIrqHandler( uint32_t ulPin ) {
gpio_irq_handler_list[ulPin] = NULL;
}
void pinRemoveMode(uint32_t ulPin) {
if ( g_APinDescription[ulPin].ulPinType == PIO_PWM ) {
// The PWM pin can only be disabled
pwmout_t *obj = (pwmout_t *)gpio_pin_struct[ulPin];
// HAL_Pwm_Disable( &obj->pwm_hal_adp );
g_APinDescription[ulPin].ulPinMode = PWM_MODE_DISABLED;
}
if ( g_APinDescription[ulPin].ulPinType == PIO_GPIO ) {
gpio_deinit( (gpio_t *)gpio_pin_struct[ulPin], g_APinDescription[ulPin].pinname );
free ( (gpio_t *)gpio_pin_struct[ulPin] );
gpio_pin_struct[ulPin] = NULL;
g_APinDescription[ulPin].ulPinType = NOT_INITIAL;
g_APinDescription[ulPin].ulPinMode = NOT_INITIAL;
}
if ( g_APinDescription[ulPin].ulPinType == PIO_GPIO_IRQ ) {
gpio_irq_deinit( (gpio_irq_t *)gpio_pin_struct[ulPin] );
free ( (gpio_irq_t *)gpio_pin_struct[ulPin] );
gpio_pin_struct[ulPin] = NULL;
g_APinDescription[ulPin].ulPinType = NOT_INITIAL;
g_APinDescription[ulPin].ulPinMode = NOT_INITIAL;
}
uint32_t pin_name = HAL_GPIO_GetPinName(g_APinDescription[pinNumber].pinname);
return 1 << (HAL_GPIO_GET_PIN_BY_NAME(pin_name));
}
#ifdef __cplusplus

View File

@@ -15,8 +15,8 @@
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 "variant.h"
#include "Arduino.h"
#include "variant.h"
#include "gpio_api.h"
#ifdef __cplusplus