1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-01-18 07:52:14 +01:00

keep track of pin status using g_pinStatus array and act accordingly

This commit adds 80 bytes to RAM usage and some overhead in normal operations.
This commit is contained in:
Martino Facchin 2015-07-14 17:29:36 +02:00
parent 33255ef46d
commit d1c65ca8fe
4 changed files with 49 additions and 12 deletions

View File

@ -155,6 +155,16 @@ typedef enum _ETCChannel
#define PIN_ATTR_PWM (1UL<<3)
#define PIN_ATTR_TIMER (1UL<<4)
#define PIN_STATUS_DIGITAL_INPUT_PULLUP (0x01)
#define PIN_STATUS_DIGITAL_INPUT (0x02)
#define PIN_STATUS_DIGITAL_OUTPUT (0x03)
#define PIN_STATUS_ANALOG (0x04)
#define PIN_STATUS_PWM (0x05)
#define PIN_STATUS_TIMER (0x06)
#define PIN_STATUS_SERIAL (0x07)
#define PIN_STATUS_DW_LOW (0x10)
#define PIN_STATUS_DW_HIGH (0x11)
/* Types used for the tables below */
typedef struct _PinDescription
{
@ -170,6 +180,8 @@ typedef struct _PinDescription
ETCChannel ulTCChannel ;
} PinDescription ;
extern uint8_t g_pinStatus[];
/* Pins table to be instanciated into variant.cpp */
extern const PinDescription g_APinDescription[] ;

View File

@ -153,6 +153,7 @@ uint32_t analogRead(uint32_t ulPin)
if ( latestSelectedChannel != (uint32_t)-1 && ulChannel != latestSelectedChannel)
adc_disable_channel( ADC, latestSelectedChannel );
latestSelectedChannel = ulChannel;
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_ANALOG;
}
// Start the ADC
@ -189,13 +190,9 @@ static void TC_SetCMR_ChannelB(Tc *tc, uint32_t chan, uint32_t v)
}
static uint8_t PWMEnabled = 0;
static uint8_t pinEnabled[PINS_COUNT];
static uint8_t TCChanEnabled[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
void analogOutputInit(void) {
uint8_t i;
for (i=0; i<PINS_COUNT; i++)
pinEnabled[i] = 0;
}
// Right now, PWM output only works on the pins with
@ -263,7 +260,7 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) {
}
uint32_t chan = g_APinDescription[ulPin].ulPWMChannel;
if (!pinEnabled[ulPin]) {
if ((g_pinStatus[ulPin] & 0xF) != PIN_STATUS_PWM) {
// Setup PWM for this pin
PIO_Configure(g_APinDescription[ulPin].pPort,
g_APinDescription[ulPin].ulPinType,
@ -273,7 +270,7 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) {
PWMC_SetPeriod(PWM_INTERFACE, chan, PWM_MAX_DUTY_CYCLE);
PWMC_SetDutyCycle(PWM_INTERFACE, chan, ulValue);
PWMC_EnableChannel(PWM_INTERFACE, chan);
pinEnabled[ulPin] = 1;
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_PWM;
}
PWMC_SetDutyCycle(PWM_INTERFACE, chan, ulValue);
@ -328,12 +325,12 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) {
TC_SetCMR_ChannelB(chTC, chNo, TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_SET);
}
}
if (!pinEnabled[ulPin]) {
if ((g_pinStatus[ulPin] & 0xF) != PIN_STATUS_PWM) {
PIO_Configure(g_APinDescription[ulPin].pPort,
g_APinDescription[ulPin].ulPinType,
g_APinDescription[ulPin].ulPin,
g_APinDescription[ulPin].ulPinConfiguration);
pinEnabled[ulPin] = 1;
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_PWM;
}
if (!TCChanEnabled[interfaceID]) {
TC_Start(chTC, chNo);

View File

@ -29,12 +29,19 @@ extern void pinMode( uint32_t ulPin, uint32_t ulMode )
return ;
}
#if defined __SAM3X8E__ || defined __SAM3X8H__
if(g_APinDescription[ulPin].ulPinType != NO_ADC && adc_get_channel_status(ADC, g_APinDescription[ulPin].ulADCChannelNumber))
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_ANALOG)
{
adc_disable_channel( ADC, g_APinDescription[ulPin].ulADCChannelNumber);
}
#endif
if ((g_pinStatus[ulPin] & 0xF) < PIN_STATUS_DIGITAL_OUTPUT && g_pinStatus[ulPin] != 0)
{
// return if already configured in the right way
if (((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_INPUT && ulMode == INPUT) ||
((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_INPUT_PULLUP && ulMode == INPUT_PULLUP) ||
((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_OUTPUT && ulMode == OUTPUT))
return;
}
switch ( ulMode )
{
@ -46,6 +53,7 @@ extern void pinMode( uint32_t ulPin, uint32_t ulMode )
PIO_INPUT,
g_APinDescription[ulPin].ulPin,
0 ) ;
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_INPUT;
break ;
case INPUT_PULLUP:
@ -56,15 +64,18 @@ extern void pinMode( uint32_t ulPin, uint32_t ulMode )
PIO_INPUT,
g_APinDescription[ulPin].ulPin,
PIO_PULLUP ) ;
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_INPUT_PULLUP;
break ;
case OUTPUT:
PIO_Configure(
g_APinDescription[ulPin].pPort,
PIO_OUTPUT_0,
g_pinStatus[ulPin] = ((g_pinStatus[ulPin] & 0xF0) >> 4 ? PIO_OUTPUT_1 : PIO_OUTPUT_0),
g_APinDescription[ulPin].ulPin,
g_APinDescription[ulPin].ulPinConfiguration ) ;
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT;
/* if all pins are output, disable PIO Controller clocking, reduce power consumption */
if ( g_APinDescription[ulPin].pPort->PIO_OSR == 0xffffffff )
{
@ -85,6 +96,12 @@ extern void digitalWrite( uint32_t ulPin, uint32_t ulVal )
return ;
}
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_PWM) {
pinMode(ulPin, OUTPUT);
}
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0x0F) | (ulVal << 4) ;
if ( PIO_GetOutputDataStatus( g_APinDescription[ulPin].pPort, g_APinDescription[ulPin].ulPin ) == 0 )
{
PIO_PullUp( g_APinDescription[ulPin].pPort, g_APinDescription[ulPin].ulPin, ulVal ) ;
@ -97,6 +114,14 @@ extern void digitalWrite( uint32_t ulPin, uint32_t ulVal )
extern int digitalRead( uint32_t ulPin )
{
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_OUTPUT) {
return (g_pinStatus[ulPin] & 0xF0) >> 4;
}
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_ANALOG) {
pinMode(ulPin, INPUT);
}
if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
{
return LOW ;

View File

@ -291,6 +291,9 @@ extern const PinDescription g_APinDescription[]=
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }
} ;
uint8_t g_pinStatus[PINS_COUNT] = {0};
#ifdef __cplusplus
}
#endif