Fast alternative to digitalRead/digitalWrite

I have defined pins for 168/328, Mega, 644/1284 (Sanguino style), Leonardo, Teensy, and Teensy++. I haven't tested Leonardo yet.

I am currently doing a lot of development on STM32 and have been thinking about digital I/O for STM32. STM32 is very different than AVR. Pins have 15 modes. and there are neat registers to safely set and clear bits in a port.

Here are the modes:

STM32 pin modes
0 - Analog input.
1 - Push Pull output 10MHz.
2 - Push Pull output 2MHz.
3 - Push Pull output 50MHz.
4 - Digital input.
5 - Open Drain output 10MHz.
6 - Open Drain output 2MHz.
7 - Open Drain output 50MHz.
8 - Digital input with PullUp or PullDown resistor depending on ODR.
9 - Alternate Push Pull output 10MHz.
A - Alternate Push Pull output 2MHz.
B - Alternate Push Pull output 50MHz.
C - Reserved.
D - Alternate Open Drain output 10MHz.
E - Alternate Open Drain output 2MHz.
F - Alternate Open Drain output 50MHz.

Wow that is a lot of choices! I can see how that would take some time to work out!

Are you posting on a forum related to ARM chips, so that I can follow your work?

If you include both SdFat and DigitalPin in the same program you get a redefinition of 'struct pin_map_t' error

I know the beta has problems like the 'struct pin_map_t' error.

I am not happy with the beta and have totally restructured this library but have not had time to finish the new library.

The old version did not work well for a number of applications like fast software I2C and SPI. The new library is very different and won't be backward compatible.

const static pin_map_t pinMap[] = {
  {&DDRD, &PIND, &PORTD, 0},  // D0  0
  {&DDRD, &PIND, &PORTD, 1},  // D1  1
  {&DDRD, &PIND, &PORTD, 2},  // D2  2
  {&DDRD, &PIND, &PORTD, 3},  // D3  3
  {&DDRD, &PIND, &PORTD, 4},  // D4  4
  {&DDRD, &PIND, &PORTD, 5},  // D5  5

The compiler optimizes const static array accesses to constants? Wow! That makes the earlier attempts at digitalWriteFast look ... silly.

Hmm. With a SLIGHT amount of cooperation from the Arduino core team, the pins_arduino.h file(s) could be set up to generate either the existing PROGMEM tables OR const static arrays, so that "fast" versions of things could be written using exactly the same data used for the slow versions:

const MAYBE_STATIC uint8_t MAYBE_PROGMEM digital_pin_to_port_[] =
{
	PB, /* 0 */
	PB,
	PB,
	PB,
	PB,
//etc

// with:
#define MAYBE_STATIC static
#define MAYBE_PROGMEM
#include <pins_arduino.h>

Or...

#define digital_pin_to_port_M \
{ \
	PB, /* 0 */ \
	PB,\
	PB,\
	PB,\
	PB,\ 
//etc \
}

const uint8_t PROGMEM digital_pin_to_port_PGM[] = digital_pin_to_port_M;
static const uint8_t digital_pin_to_port_S[] = digital_pin_to_port_M;

This is extremely interesting, any improvements?

I can't improve the speed since functions like pin.high() and pin.low() compile to a single sbi or cbi instruction for low address I/O ports. All ports on the 328 and ports A-G on the Mega are low address. These instructions execute in 2 cycles or 125 ns on a 16 MHz cpu.

I have added software SPI which runs at about 2 MHz. This library supports all SPI modes for MSB first. It would be easy to add an option for LSB first.

I have not posted the latest version as a standalone library. The latest version of DigitalPin with SoftSPI is used in the new 20120719 version of SdFat. The files DigitalPin.h and SoftSPI.h are in the SdFat/utility folder and SdFat is here Google Code Archive - Long-term storage for Google Code Project Hosting..

I have also written a software I2C library based on the DigitalPin library that runs at 400 kHz. I plan to post this I2C library soon.

I can't improve the speed since functions like pin.high() and pin.low() compile to a single sbi or cbi instruction for low address I/O ports. All ports on the 328 and ports A-G on the Mega are low address. These instructions execute in 2 cycles or 125 ns on a 16 MHz cpu....

Btw this is a great result! fastDigitalWrite it's still one of the most used library because the original digitalWrite it's silly slow for many applications but the development it's stuck at 2010 and not provide any support for new micros and with the new pin management of arduino I dubt it will be useful as in the past.
Man, you made a great work! I know that direct port manipulation it's easier but the beauty of change processor and reuse the libraries for experiments without spend hours around PORTwhatever it's a dream!
I will check how you used in your sdfatlib, I'm planning to apply to liquidCrystal lib (I hope will not a nightmare...) and was really great you added any unsupported processor.

Oh. You had same problem as I do. Arduino is slow... Well I had another problem. I can't create easy libraries with bare avr c. So I started project to overcome this problem.

As a result I have very nice implementation for digital pins. That is only thing really working yet. Timers and analogRead is next.

Wanted to let you know what I have found out, so here is the project: GitHub - raphendyr/yaal: Yet another AVR Abstraction Library

raphendyr:
Oh. You had same problem as I do. Arduino is slow... Well I had another problem. I can't create easy libraries with bare avr c. So I started project to overcome this problem.

As a result I have very nice implementation for digital pins. That is only thing really working yet. Timers and analogRead is next.

Wanted to let you know what I have found out, so here is the project: GitHub - raphendyr/yaal: Yet another AVR Abstraction Library

Hi, had a look at your library. Seems you are doing similar things to the ideas I'm implementing in my own library. I also noticed you are using a very basic version of my AtomicBlock library. I'm about to release a new version compatible with AVR, AVR32, PIC32, ARM Cortex M/R if you are interested.