Skip to content

Commit 86a34c7

Browse files
committed
Merge pull request arduino#3524 from facchinm/pins_DUE
Due: solve issues with nonstandard pin operations
2 parents 286c076 + 365bdf6 commit 86a34c7

File tree

5 files changed

+79
-14
lines changed

5 files changed

+79
-14
lines changed

cores/arduino/Arduino.h

+12
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,16 @@ typedef enum _ETCChannel
155155
#define PIN_ATTR_PWM (1UL<<3)
156156
#define PIN_ATTR_TIMER (1UL<<4)
157157

158+
#define PIN_STATUS_DIGITAL_INPUT_PULLUP (0x01)
159+
#define PIN_STATUS_DIGITAL_INPUT (0x02)
160+
#define PIN_STATUS_DIGITAL_OUTPUT (0x03)
161+
#define PIN_STATUS_ANALOG (0x04)
162+
#define PIN_STATUS_PWM (0x05)
163+
#define PIN_STATUS_TIMER (0x06)
164+
#define PIN_STATUS_SERIAL (0x07)
165+
#define PIN_STATUS_DW_LOW (0x10)
166+
#define PIN_STATUS_DW_HIGH (0x11)
167+
158168
/* Types used for the tables below */
159169
typedef struct _PinDescription
160170
{
@@ -170,6 +180,8 @@ typedef struct _PinDescription
170180
ETCChannel ulTCChannel ;
171181
} PinDescription ;
172182

183+
extern uint8_t g_pinStatus[];
184+
173185
/* Pins table to be instanciated into variant.cpp */
174186
extern const PinDescription g_APinDescription[] ;
175187

cores/arduino/wiring_analog.c

+7-10
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,12 @@ uint32_t analogRead(uint32_t ulPin)
148148
case ADC11 :
149149

150150
// Enable the corresponding channel
151-
if (ulChannel != latestSelectedChannel) {
151+
if (adc_get_channel_status(ADC, ulChannel) != 1) {
152152
adc_enable_channel( ADC, ulChannel );
153-
if ( latestSelectedChannel != (uint32_t)-1 )
153+
if ( latestSelectedChannel != (uint32_t)-1 && ulChannel != latestSelectedChannel)
154154
adc_disable_channel( ADC, latestSelectedChannel );
155155
latestSelectedChannel = ulChannel;
156+
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_ANALOG;
156157
}
157158

158159
// Start the ADC
@@ -189,13 +190,9 @@ static void TC_SetCMR_ChannelB(Tc *tc, uint32_t chan, uint32_t v)
189190
}
190191

191192
static uint8_t PWMEnabled = 0;
192-
static uint8_t pinEnabled[PINS_COUNT];
193193
static uint8_t TCChanEnabled[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
194194

195195
void analogOutputInit(void) {
196-
uint8_t i;
197-
for (i=0; i<PINS_COUNT; i++)
198-
pinEnabled[i] = 0;
199196
}
200197

201198
// Right now, PWM output only works on the pins with
@@ -263,7 +260,7 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) {
263260
}
264261

265262
uint32_t chan = g_APinDescription[ulPin].ulPWMChannel;
266-
if (!pinEnabled[ulPin]) {
263+
if ((g_pinStatus[ulPin] & 0xF) != PIN_STATUS_PWM) {
267264
// Setup PWM for this pin
268265
PIO_Configure(g_APinDescription[ulPin].pPort,
269266
g_APinDescription[ulPin].ulPinType,
@@ -273,7 +270,7 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) {
273270
PWMC_SetPeriod(PWM_INTERFACE, chan, PWM_MAX_DUTY_CYCLE);
274271
PWMC_SetDutyCycle(PWM_INTERFACE, chan, ulValue);
275272
PWMC_EnableChannel(PWM_INTERFACE, chan);
276-
pinEnabled[ulPin] = 1;
273+
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_PWM;
277274
}
278275

279276
PWMC_SetDutyCycle(PWM_INTERFACE, chan, ulValue);
@@ -328,12 +325,12 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) {
328325
TC_SetCMR_ChannelB(chTC, chNo, TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_SET);
329326
}
330327
}
331-
if (!pinEnabled[ulPin]) {
328+
if ((g_pinStatus[ulPin] & 0xF) != PIN_STATUS_PWM) {
332329
PIO_Configure(g_APinDescription[ulPin].pPort,
333330
g_APinDescription[ulPin].ulPinType,
334331
g_APinDescription[ulPin].ulPin,
335332
g_APinDescription[ulPin].ulPinConfiguration);
336-
pinEnabled[ulPin] = 1;
333+
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_PWM;
337334
}
338335
if (!TCChanEnabled[interfaceID]) {
339336
TC_Start(chTC, chNo);

cores/arduino/wiring_digital.c

+33-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ extern void pinMode( uint32_t ulPin, uint32_t ulMode )
2929
return ;
3030
}
3131

32+
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_ANALOG)
33+
{
34+
adc_disable_channel( ADC, g_APinDescription[ulPin].ulADCChannelNumber);
35+
}
36+
37+
if ((g_pinStatus[ulPin] & 0xF) < PIN_STATUS_DIGITAL_OUTPUT && g_pinStatus[ulPin] != 0)
38+
{
39+
// return if already configured in the right way
40+
if (((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_INPUT && ulMode == INPUT) ||
41+
((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_INPUT_PULLUP && ulMode == INPUT_PULLUP) ||
42+
((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_OUTPUT && ulMode == OUTPUT))
43+
return;
44+
}
45+
3246
switch ( ulMode )
3347
{
3448
case INPUT:
@@ -39,6 +53,7 @@ extern void pinMode( uint32_t ulPin, uint32_t ulMode )
3953
PIO_INPUT,
4054
g_APinDescription[ulPin].ulPin,
4155
0 ) ;
56+
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_INPUT;
4257
break ;
4358

4459
case INPUT_PULLUP:
@@ -49,15 +64,18 @@ extern void pinMode( uint32_t ulPin, uint32_t ulMode )
4964
PIO_INPUT,
5065
g_APinDescription[ulPin].ulPin,
5166
PIO_PULLUP ) ;
67+
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_INPUT_PULLUP;
5268
break ;
5369

5470
case OUTPUT:
5571
PIO_Configure(
5672
g_APinDescription[ulPin].pPort,
57-
PIO_OUTPUT_1,
73+
(g_pinStatus[ulPin] & 0xF0) >> 4 ? PIO_OUTPUT_1 : PIO_OUTPUT_0,
5874
g_APinDescription[ulPin].ulPin,
5975
g_APinDescription[ulPin].ulPinConfiguration ) ;
6076

77+
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT;
78+
6179
/* if all pins are output, disable PIO Controller clocking, reduce power consumption */
6280
if ( g_APinDescription[ulPin].pPort->PIO_OSR == 0xffffffff )
6381
{
@@ -78,6 +96,12 @@ extern void digitalWrite( uint32_t ulPin, uint32_t ulVal )
7896
return ;
7997
}
8098

99+
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_PWM) {
100+
pinMode(ulPin, OUTPUT);
101+
}
102+
103+
g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0x0F) | (ulVal << 4) ;
104+
81105
if ( PIO_GetOutputDataStatus( g_APinDescription[ulPin].pPort, g_APinDescription[ulPin].ulPin ) == 0 )
82106
{
83107
PIO_PullUp( g_APinDescription[ulPin].pPort, g_APinDescription[ulPin].ulPin, ulVal ) ;
@@ -90,6 +114,14 @@ extern void digitalWrite( uint32_t ulPin, uint32_t ulVal )
90114

91115
extern int digitalRead( uint32_t ulPin )
92116
{
117+
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_OUTPUT) {
118+
return (g_pinStatus[ulPin] & 0xF0) >> 4;
119+
}
120+
121+
if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_ANALOG) {
122+
pinMode(ulPin, INPUT);
123+
}
124+
93125
if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
94126
{
95127
return LOW ;

system/libsam/source/adc.c

+24-3
Original file line numberDiff line numberDiff line change
@@ -192,18 +192,39 @@ void adc_set_resolution(Adc *p_adc,const enum adc_resolution_t resolution)
192192
void adc_configure_trigger(Adc *p_adc, const enum adc_trigger_t trigger,
193193
uint8_t uc_freerun)
194194
{
195-
p_adc->ADC_MR |= trigger | ((uc_freerun << 7) & ADC_MR_FREERUN);
195+
//Warning ADC_MR_TRGSEL_Msk does not include ADC_MR_TRGEN.
196+
p_adc->ADC_MR &= ~(ADC_MR_TRGEN | ADC_MR_TRGSEL_Msk | ADC_MR_FREERUN); //Clear all bits related to triggers and freerun
197+
198+
//Configure FreeRun
199+
if(uc_freerun & ADC_MR_FREERUN == ADC_MR_FREERUN_ON) { //FreeRun is enabled
200+
p_adc->ADC_MR |= ADC_MR_FREERUN_ON;
201+
202+
//Free Run Mode: Never wait for any trigger
203+
//No need to continue and enable hardware triggers
204+
return;
205+
}
206+
207+
//Configure hardware triggers
208+
if(trigger & ADC_MR_TRGEN == ADC_MR_TRGEN_EN) { //Hardware trigger is enabled
209+
p_adc->ADC_MR |= (trigger & ADC_MR_TRGSEL_Msk) | ADC_MR_TRGEN_EN; //Set trigger selection bits and enable hardware trigger
210+
}
196211
}
197212
#elif SAM3U_SERIES
198213
/**
199-
* \brief Configure conversion trigger and free run mode.
214+
* \brief Configure conversion trigger.
200215
*
201216
* \param p_adc Pointer to an ADC instance.
202217
* \param trigger Conversion trigger.
203218
*/
204219
void adc_configure_trigger(Adc *p_adc, const enum adc_trigger_t trigger)
205220
{
206-
p_adc->ADC_MR |= trigger;
221+
//Warning ADC_MR_TRGSEL_Msk does not include ADC_MR_TRGEN.
222+
p_adc->ADC_MR &= ~(ADC_MR_TRGEN | ADC_MR_TRGSEL_Msk); //Clear all bits related to triggers
223+
224+
//Configure hardware triggers
225+
if(trigger & ADC_MR_TRGEN == ADC_MR_TRGEN_EN) { //Hardware trigger is enabled
226+
p_adc->ADC_MR |= (trigger & ADC_MR_TRGSEL_Msk) | ADC_MR_TRGEN_EN; //Set trigger selection bits and enable hardware trigger
227+
}
207228
}
208229
#endif
209230

variants/arduino_due_x/variant.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@ extern const PinDescription g_APinDescription[]=
291291
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }
292292
} ;
293293

294+
295+
uint8_t g_pinStatus[PINS_COUNT] = {0};
296+
294297
#ifdef __cplusplus
295298
}
296299
#endif

0 commit comments

Comments
 (0)