arduino-nRF5
arduino-nRF5 copied to clipboard
Implement pin output modes
When a pin is switched to OUTPUT the GPIO_PIN_CNF_DRIVE_S0S1 profile is enabled. What is your opinion to implement mode switching via OUTPUT_S0S1, OUTPUT_H0S1, OUTPUT_H0H1, OUTPUT_D0S1.... OUTPUT_H0D1?
Can you please explain the differences with these modes?
Also, how do they map to the existing Arduino pinMode
API and modes: https://www.arduino.cc/en/Reference/PinMode
Extending output modes breaks the Arduino compatibility like INPUT_PULLDOWN it already does. This is implemented here but not available when using AVR.
The modes allows to switch a port into High Drive mode. This allows a higher current. The allowed current is:
nRF51: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.3.pdf (Table 62)
- Low Drive: 0.5 mA
- High Drive: 5 mA
nRF52: http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/gpio.html?cp=2_2_0_19_3_0#unique_1110673565
- Low Drive maximum: 2-5 mA (0.5 mA)
- High Drive maximum: 9-14/10-15 mA (5 mA)
I don't find a regulation about how many ports are allowed to use high drive at the same time for nRF52. For nRF51there is a Note "Maximum number of pins with 5 mA high drive is 3" in nRF51822 Product Specification v3.3 Table 63.
In my opinion the GPIO cannot be used without understanding and reading the data sheet. With actual settings driving a LED woks, but outside electrical specification. Switching any port into High Drive mode is not possible because there is a limit for nRF51 and maybe nRF52.
The next feature is the D0S1/D0H1 mode which means disconnect when Low. The S0D1 and H0D1 Mode is only available using a nRF52.
@d00616 thanks for the explanation.
Let's wait and see how the official Arduino SAMD core decides to handle this in https://github.com/arduino/ArduinoCore-samd/issues/158
@sandeepmistry Let's wait. Do you know if someone working on to define something?
@d00616 not that I'm aware of, if you have any suggestions please comment on the SAMD issue I linked to.
It looks like there is no way to find a solution which is compatible to SAMD and NRF without limiting capabilities of NRF GPIO.
@d00616 ok, we should really think if we need to expose all the options.
Advanced users can always access the nRF5x specific mode directly via registers or through a new nRF51 specific library.
@sandeepmistry I work on a board.txt generator. My idea is to generate a board configuration by providing YAML files. This simplifies the management of boards, reduce the number of menu items and allows to manage boards like https://github.com/sandeepmistry/arduino-nRF5/issues/165 outside of this repository.
When I can configure a board in YAML, I can define pin mode overrides to support all nRF5 output modes, when a pin is configured as OUTPUT pin. What do you think about it?
The board generator can manage depending libraries to access board specific hardware.
This zip file contains diffs for wiring_digital.h wiring_digital_c and wiring_constants.h to add following extra pinModes to access highdrive and disconnect on the nRF52
(ZIP file removed for cyber security reasons)
- For nRF52 extra modes are available.
- Standard drive is typically 2mA (min 1mA) '0' sink (low) or '1' source (high). High drive (VDD > 2.7V) is typically 10mA low, 9mA high (min 6mA)
- OUTPUT_S0S1 Standard '0', standard '1' same as OUTPUT
- OUTPUT_H0S1 High drive '0', standard '1'
- OUTPUT_S0H1 Standard '0', high drive '1'
- OUTPUT_H0H1 High drive '0', high 'drive '1''
- OUTPUT_D0S1 Disconnect '0' standard '1' (normally used for wired-or connections)
- OUTPUT_D0H1 Disconnect '0', high drive '1' (normally used for wired-or connections)
- OUTPUT_S0D1 Standard '0'. disconnect '1' (normally used for wired-and connections)
- OUTPUT_H0D1 High drive '0', disconnect '1' (normally used for wired-and connections)
- NOTE P0.27 should be only low (standard) drive, low frequency
@drmpf I have deleted your ZIP files as it's in poor taste to attach a ZIP file with potentially malicious content. If you wish to share a modification to this project please to a PR or share just the raw code as text.
no problem, I posted zip because github allows that type of file, but not diffs
--- \hardware\nRF5\0.6.0\cores\nRF5\wiring_digital.c 2018-08-11 05:24:03.000000000 +-1100
+++ \hardware\nRF5\0.6.0\cores\nRF5\wiring_digital.c 2019-03-10 15:43:27.000000000 +-1100
@@ -70,12 +70,21 @@
| ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
| ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
break ;
default:
+ if ((ulMode >= OUTPUT_S0S1) && (ulMode <= OUTPUT_H0D1)) {
+ uint32_t drive = ulMode - OUTPUT_S0S1;
+ // Set pin to output mode with specified drive
+ NRF_GPIO->PIN_CNF[ulPin] = ((uint32_t)GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos)
+ | ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
+ | ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
+ | ((uint32_t)drive << GPIO_PIN_CNF_DRIVE_Pos)
+ | ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
+ } // else
// do nothing
break ;
}
}
void digitalWrite( uint32_t ulPin, uint32_t ulVal )
--- \hardware\nRF5\0.6.0\cores\nRF5\wiring_digital.h 2018-08-11 05:24:03.000000000 +-1100
+++ \hardware\nRF5\0.6.0\cores\nRF5\wiring_digital.h 2019-03-10 15:43:27.000000000 +-1100
@@ -24,15 +24,28 @@
#endif
// #include "WVariant.h"
/**
* \brief Configures the specified pin to behave either as an input or an output. See the description of digital pins for details.
+ * For nRF52 extra modes are available.
+ * Standard drive is typically 2mA (min 1mA) '0' sink (low) or '1' source (high). High drive (VDD > 2.7V) is typically 10mA low, 9mA high (min 6mA)
*
+ * OUTPUT_S0S1 Standard '0', standard '1' same as OUTPUT
+ * OUTPUT_H0S1 High drive '0', standard '1'
+ * OUTPUT_S0H1 Standard '0', high drive '1'
+ * OUTPUT_H0H1 High drive '0', high 'drive '1''
+ * OUTPUT_D0S1 Disconnect '0' standard '1' (normally used for wired-or connections)
+ * OUTPUT_D0H1 Disconnect '0', high drive '1' (normally used for wired-or connections)
+ * OUTPUT_S0D1 Standard '0'. disconnect '1' (normally used for wired-and connections)
+ * OUTPUT_H0D1 High drive '0', disconnect '1' (normally used for wired-and connections)
+ * NOTE P0.27 should be only low (standard) drive, low frequency
+ *
* \param ulPin The number of the pin whose mode you wish to set
* \param ulMode Can be INPUT, OUTPUT, INPUT_PULLUP or INPUT_PULLDOWN
+ * or OUTPUT_S0S1, OUTPUT_H0S1, OUTPUT_S0H1, OUTPUT_H1H1, OUTPUT_D0S1, OUTPUT_D0H1, OUTPUT_S0D1, OUTPUT_H0D1
*/
extern void pinMode( uint32_t dwPin, uint32_t dwMode ) ;
/**
* \brief Write a HIGH or a LOW value to a digital pin.
*
--- \hardware\nRF5\0.6.0\cores\nRF5\wiring_constants.h 2018-08-11 05:24:03.000000000 +-1100
+++ \hardware\nRF5\0.6.0\cores\nRF5\wiring_constants.h 2019-03-10 15:43:27.000000000 +-1100
@@ -28,12 +28,33 @@
#define INPUT (0x0)
#define OUTPUT (0x1)
#define INPUT_PULLUP (0x2)
#define INPUT_PULLDOWN (0x3)
+/*** from nrf52_bitfields.h
+#define GPIO_PIN_CNF_DRIVE_S0S1 (0UL) //!< Standard '0', standard '1'
+#define GPIO_PIN_CNF_DRIVE_H0S1 (1UL) //!< High drive '0', standard '1'
+#define GPIO_PIN_CNF_DRIVE_S0H1 (2UL) //!< Standard '0', high drive '1'
+#define GPIO_PIN_CNF_DRIVE_H0H1 (3UL) //!< High drive '0', high 'drive '1''
+#define GPIO_PIN_CNF_DRIVE_D0S1 (4UL) //!< Disconnect '0' standard '1' (normally used for wired-or connections)
+#define GPIO_PIN_CNF_DRIVE_D0H1 (5UL) //!< Disconnect '0', high drive '1' (normally used for wired-or connections)
+#define GPIO_PIN_CNF_DRIVE_S0D1 (6UL) //!< Standard '0'. disconnect '1' (normally used for wired-and connections)
+#define GPIO_PIN_CNF_DRIVE_H0D1 (7UL) //!< High drive '0', disconnect '1' (normally used for wired-and connections)
+*********************/
+
+// The default OUTPUT is SOS1
+#define OUTPUT_S0S1 (0x10+0x0)
+#define OUTPUT_H0S1 (0x10+0x1)
+#define OUTPUT_S0H1 (0x10+0x2)
+#define OUTPUT_H0H1 (0x10+0x3)
+#define OUTPUT_D0S1 (0x10+0x4)
+#define OUTPUT_D0H1 (0x10+0x5)
+#define OUTPUT_S0D1 (0x10+0x6)
+#define OUTPUT_H0D1 (0x10+0x7)
+
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105
#define EULER 2.718281828459045235360287471352