The page https://docs.arduino.cc/learn/programming/bit-math/ gives below example for setting pins using registers for an Arduino UNO, supposedly much faster than using a loop and pinMode and digitalWrite. What are the equivalent registers in a UNO R4 WiFi?? Is there an easy way to print each bit for the equivalent ports in loop() for a UNO R4 WiFi?? Thanks for any help. AA
void setup() {
DDRD = B11111110; // digital pins 7,6,5,4,3,2,1,0
PORTD &= B00000011; // turns off 2..7, but leaves pins 0 and 1 alone
DDRB = B00111111; // digital pins -,-,13,12,11,10,9,8
PORTB = B00111000; // turns on 13,12,11; turns off 10,9,8
}
Do you mean that the fast access to registers that can be done for the R3 ( DDRD = B11111110, DDRB = B00111111, etc) cannot be done in the R4 WiFi?? Or the registers in the R4 WiFi do exist but have different names and I need to see the R4's datasheet??
A good search through the R4 core looking for constructs like R_PORTx, PDR, PODR and PIDR might be enlightening. That'll introduce you to one method; there are also others.
Yes, but note this is the case when ever you change the processor you are using when changing to any processor that is not the one used in the R3 Uno.
So for example while the nano classic will have the same internal registers as the Uno R3, the nano Every has a different processor and so a different set of ports and internal registers.
Finding what ports and registers for a specific processor is a problem which a small amount of web searches will reveal.
This is the price you pay for using this feature, it is not universal and fixes any code using to that processor, or at best that processor group. This is sometimes called "programming to the metal" While the Arduino company has done a good job of making the standard features and official libraries compatible on all platforms (processors) , many user written libraries do not, and are normally badly documented if documented at all.
So where as a digitalWrite will work on any Arduino it will not necessarily be the fastest the hardware is capable of. This is one of the reasons digitalWrite is slow, it has to do a lot of hardware abstraction to make sure it works on any platform.
Based on susan-parker's post in that thread, I did some noodling. digitalWriteFaster() should be portable across all the Renesas R4 boards. digitalWriteFastest() needs the hardware pin number which may need to be looked up by the user.
/*!
* Description: Fast digital write methods for Arduino UNO R4 WIFI and Minima
*
* Author: Bob Cousins 2025
*
* Note : incomplete and not tested on Minima. Use for entertainment only.
*/
// select method
const int METHOD = 2;
const int output_pin = 7;
// Pin Function Select, Byte access
#define PORTBASE 0x40040000 /* Port Base */
// hardware numbering
// general purpose, port = 0 to 9, pin = 0 to 15
#define PFS_BY(pfs_port,pfs_pin) *((volatile unsigned char *)(PORTBASE + 0x0800UL + ((pfs_port) * 0x40UL) + 0x0003 + ( (pfs_pin) * 4)))
// Hardware Pin specific
// Port 1, Pin 7
#define PFS_P107_BY *((volatile unsigned char *)(PORTBASE + 0x0843 + (7 * 4)))
// Port 1, Pin 12
#define PFS_P112_BY *((volatile unsigned char *)(PORTBASE + 0x0843 + (12 * 4)))
// Set Pin Direction to OUTPUT
#define PFS_PDR_OUTPUT 0x04
// uses Arduino pin numbering
static inline void digitalWriteFaster (int pin, int val)
{
int port = g_pin_cfg[pin].pin >> 8;
int port_pin = g_pin_cfg[pin].pin & 0xFF;
PFS_BY (port, port_pin) = PFS_PDR_OUTPUT + val;
}
// uses hardware pin numbering
static inline void digitalWriteFastest (int pin, int val)
{
PFS_BY (pin >> 8, pin & 0xFF) = PFS_PDR_OUTPUT + val;
}
void setup() {
// put your setup code here, to run once:
pinMode (output_pin, OUTPUT);
}
// derived from pinout diagram, or variant.cpp
#ifdef ARDUINO_UNOR4_WIFI
#define HW_PIN_0 (0x300 + 1)
#define HW_PIN_1 (0x300 + 2)
#define HW_PIN_2 (0x100 + 4)
#define HW_PIN_3 (0x100 + 5)
#define HW_PIN_4 (0x100 + 6)
#define HW_PIN_5 (0x100 + 7)
#define HW_PIN_6 (0x100 + 11)
#define HW_PIN_7 (0x100 + 12)
// TODO: etc...
#elif defined(ARDUINO_UNOR4_MINIMA)
#define HW_PIN_0 (0x300 + 1)
#define HW_PIN_1 (0x300 + 2)
#define HW_PIN_2 (0x100 + 5)
#define HW_PIN_3 (0x100 + 4)
#define HW_PIN_4 (0x100 + 3)
#define HW_PIN_5 (0x100 + 2)
#define HW_PIN_6 (0x100 + 6)
#define HW_PIN_7 (0x100 + 7)
// TODO: etc...
#else
#error Platform not supported
#endif
const int hw_pin = HW_PIN_7;
void loop()
{
// put your main code here, to run repeatedly:
if (METHOD == 0)
{
// 960 ns
digitalWrite(output_pin, HIGH);
digitalWrite(output_pin, LOW);
}
else if (METHOD == 1)
{
// 290 ns
digitalWriteFaster (output_pin, HIGH);
digitalWriteFaster (output_pin, LOW);
}
else if (METHOD == 2)
{
// 84 ns
digitalWriteFastest (hw_pin, HIGH);
digitalWriteFastest (hw_pin, LOW);
}
else if (METHOD == 3)
{
// 83 ns
PFS_BY(hw_pin >> 8, hw_pin & 0xFF) = PFS_PDR_OUTPUT + 1;
PFS_BY(hw_pin >> 8, hw_pin & 0xFF) = PFS_PDR_OUTPUT + 0;
}
else if (METHOD == 4)
{
// 83 ns
#ifdef ARDUINO_UNOR4_WIFI
PFS_P112_BY = 0x05; // HIGH
PFS_P112_BY = 0x04; // LOW
#else
// NB, this is pin 7 on Minima, but pin 5 on WIFI
PFS_P107_BY = 0x05; // HIGH
PFS_P107_BY = 0x04; // LOW
#endif
}
delay (1);
}