From 9affb8f68d7323e7effa6800773ea4dc0701bf09 Mon Sep 17 00:00:00 2001
From: Thibaut VIARD <thibaut.viard@atmel.com>
Date: Wed, 19 Nov 2014 15:22:38 +0100
Subject: [PATCH]  fixing pullup mode and adding pulldown

Signed-off-by: Thibaut VIARD <thibaut.viard@atmel.com>
---
 cores/arduino/wiring_digital.c | 19 +++++++++++++++++--
 cores/arduino/wiring_digital.h |  3 ++-
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c
index 5c03e8d5..1550d414 100644
--- a/cores/arduino/wiring_digital.c
+++ b/cores/arduino/wiring_digital.c
@@ -25,6 +25,7 @@
 
 int pinPeripheral( uint32_t ulPin, EPioType ulPeripheral )
 {
+  // Handle the case the pin isn't usable as PIO
   if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
   {
     return -1 ;
@@ -121,11 +122,13 @@ int pinPeripheral( uint32_t ulPin, EPioType ulPeripheral )
 
 void pinMode( uint32_t ulPin, uint32_t ulMode )
 {
+  // Handle the case the pin isn't usable as PIO
   if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
   {
     return ;
   }
 
+  // Set pin mode according to chapter '22.6.3 I/O Pin Configuration'
   switch ( ulMode )
   {
     case INPUT:
@@ -138,6 +141,18 @@ void pinMode( uint32_t ulPin, uint32_t ulMode )
       // Set pin to input mode with pull-up resistor enabled
       PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN) ;
       PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
+
+      // Enable pull level (cf '22.6.3.2 Input Configuration' and '22.8.7 Data Output Value Set')
+      PORT->Group[g_APinDescription[ulPin].ulPort].OUTSET.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
+    break ;
+
+    case INPUT_PULLDOWN:
+      // Set pin to input mode with pull-down resistor enabled
+      PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN) ;
+      PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
+
+      // Enable pull level (cf '22.6.3.2 Input Configuration' and '22.8.6 Data Output Value Clear')
+      PORT->Group[g_APinDescription[ulPin].ulPort].OUTCLR.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
     break ;
 
     case OUTPUT:
@@ -154,7 +169,7 @@ void pinMode( uint32_t ulPin, uint32_t ulMode )
 
 void digitalWrite( uint32_t ulPin, uint32_t ulVal )
 {
-  /* Handle the case the pin isn't usable as PIO */
+  // Handle the case the pin isn't usable as PIO
   if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
   {
     return ;
@@ -182,7 +197,7 @@ void digitalWrite( uint32_t ulPin, uint32_t ulVal )
 
 int digitalRead( uint32_t ulPin )
 {
-  /* Handle the case the pin isn't usable as PIO */
+  // Handle the case the pin isn't usable as PIO
   if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
   {
     return LOW ;
diff --git a/cores/arduino/wiring_digital.h b/cores/arduino/wiring_digital.h
index e7f5ff42..fca8ba93 100644
--- a/cores/arduino/wiring_digital.h
+++ b/cores/arduino/wiring_digital.h
@@ -26,6 +26,7 @@
 #define INPUT           (0x0ul)
 #define OUTPUT          (0x1ul)
 #define INPUT_PULLUP    (0x2ul)
+#define INPUT_PULLDOWN  (0x4ul)
 
 #define LOW             (0x0ul)
 #define HIGH            (0x1ul)
@@ -44,7 +45,7 @@ extern int pinPeripheral( uint32_t ulPin, EPioType ulPeripheral ) ;
  * \brief Configures the specified pin to behave either as an input or an output. See the description of digital pins for details.
  *
  * \param ulPin The number of the pin whose mode you wish to set
- * \param ulMode Either INPUT or OUTPUT
+ * \param ulMode Can be INPUT, OUTPUT, INPUT_PULLUP or INPUT_PULLDOWN
  */
 extern void pinMode( uint32_t dwPin, uint32_t dwMode ) ;
 
-- 
GitLab