New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pin/port/register macros not defined in cores/Arduino.h #70

Open
oesterle opened this Issue Oct 24, 2017 · 3 comments

Comments

Projects
None yet
2 participants
@oesterle

oesterle commented Oct 24, 2017

Pin/port/register macros not defined in cores/Arduino.h, including:
digitalPinToPort
portOutputRegister
digitalPinToBitMask

Found while trying to use Adafruit_SSD1351 OLED display library:
https://github.com/adafruit/Adafruit-SSD1351-library

@pablosun pablosun self-assigned this Oct 24, 2017

@pablosun

This comment has been minimized.

Contributor

pablosun commented Oct 24, 2017

Good suggestions here, will see if we can implement those internal APIs here.
One questions though - Is the digitalWrite() API too slow for your use case here?

@pablosun

This comment has been minimized.

Contributor

pablosun commented Oct 24, 2017

@oesterle it seems that portOutputRegiter and digitalPinToBitMask are not compatible to MT7697. It is possible to expose underlying HW registers, but the usage will be different from AVR Arduinos.

HW Register Design Differences

The AVR architectures uses same HW register for "set" and "unset" pin state:

reg= portOutputRegister(digitalPinToPort(PIN));
pinMask = digitalPinToBitMask(PIN);

// this unset PIN output to LOW
*reg &= ~pinMask ; 

// this set PIN output to HIGH
*reg |= pinMask ;     

However, the peripheral system of MT7697 separates "set" and "unset" into two different HW registers:

regSet= portOutputRegisterSet(digitalPinToPort(PIN));
regUnset = portOutputRegisterSet(digitalPinToPort(PIN));

// Set PIN to HIGH
*regSet = pinMask;

// Unset PIN to LOW
*regUnset = pinMask ;

Note: We can refer to the MT76x7 Reference Manual and see the design of following HW registers:

  • GPIO_DOUT1_SET
  • GPIO_DOUT1_RESET

Speed gains of HW Regsiter

We can get around 10x gains by replacing digitalWrite calls with low-level HW register writes.

A simple digitalWrite that flips PIN 2 as show below:

#include <FreeRTOS.h>
#include <task.h>
void setup() {
  pinMode(2, OUTPUT);
  taskDISABLE_INTERRUPTS();
}

void loop() {
  while(1){
    digitalWrite(2, 1);
    digitalWrite(2, 0);
  }
}

Generates a waveform around 1.3MHz
default

If we replace the digitalWrite calls to direct HW register right:

#include <FreeRTOS.h>
#include <task.h>
void setup() {
  pinMode(2, OUTPUT);
  taskDISABLE_INTERRUPTS();
}

// Register-based GPIO write
#define IOT_GPIO_AON_BASE           (0x8300B000)
#define IOT_GPIO_DOUT1              (0x60)                 
#define IOT_GPIO_DOUT1_SET          (IOT_GPIO_DOUT1 + 0x04)
#define IOT_GPIO_DOUT1_RESET        (IOT_GPIO_DOUT1 + 0x08)
#define IOT_GPIO_DOUT2              (0x70)                 
#define IOT_GPIO_DOUT2_SET          (IOT_GPIO_DOUT2 + 0x04)
#define IOT_GPIO_DOUT2_RESET        (IOT_GPIO_DOUT2 + 0x08)
#define IOT_GPIO_DOUT3              (0x80)                 
#define IOT_GPIO_DOUT3_SET          (IOT_GPIO_DOUT3 + 0x04)
#define IOT_GPIO_DOUT3_RESET        (IOT_GPIO_DOUT3 + 0x08)
#define DRV_WriteReg32(addr,data)     ((*(volatile unsigned int *)(addr)) = (unsigned int)(data))

void loop() {
  while(1){
    DRV_WriteReg32(IOT_GPIO_AON_BASE + IOT_GPIO_DOUT1_SET, (1 << 0));
    DRV_WriteReg32(IOT_GPIO_AON_BASE + IOT_GPIO_DOUT1_RESET, (1 << 0));
  }
}

we can generate a waveform around 20MHz, which is an improvement.
default

@oesterle

This comment has been minimized.

oesterle commented Oct 25, 2017

digitalWrite is probably fast enough, for now. I'm much more concerned with being able to use common Arduino libraries with MT7697. I'm using LinkIt 7697 partly because ESP32 Arduino doesn't support BLE, yet (after almost a year of being on the market).

Whatever you can do to make existing SPI & I2C code "just work" on LinkIt 7697 will mean that I use it in more projects.

Thank you, Pablo!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment