I figured out how to control the outputs directly like direct port manipulation on the Arduino. Could be useful if you need to roll your own bit-banged library or something like that
Check out this example code with timing info measured with my Rigol DS1052 50MHz oscilloscope.
//--------------------------
// Simple Bit-Bang Example
// BDub 2013
//--------------------------
uint16_t pin = D7;
void setup() {
pinMode(pin,OUTPUT);
}
void loop() {
// Bit-Bang Digital Output D7 at 18MHz = System Clock 72MHz / 4
// HIGH time = 27.7ns
// LOW time = 27.7ns
PIN_MAP[pin].gpio_peripheral->BSRR = PIN_MAP[pin].gpio_pin; // HIGH
PIN_MAP[pin].gpio_peripheral->BRR = PIN_MAP[pin].gpio_pin; // LOW
PIN_MAP[pin].gpio_peripheral->BSRR = PIN_MAP[pin].gpio_pin; // HIGH
PIN_MAP[pin].gpio_peripheral->BRR = PIN_MAP[pin].gpio_pin; // LOW
PIN_MAP[pin].gpio_peripheral->BSRR = PIN_MAP[pin].gpio_pin; // HIGH
PIN_MAP[pin].gpio_peripheral->BRR = PIN_MAP[pin].gpio_pin; // LOW
PIN_MAP[pin].gpio_peripheral->BSRR = PIN_MAP[pin].gpio_pin; // HIGH
PIN_MAP[pin].gpio_peripheral->BRR = PIN_MAP[pin].gpio_pin; // LOW
// Wrapped up in function calls slows down to 1.53MHz
// HIGH time = 332ns
// LOW time = 320ns
pinHigh(pin);
pinLow(pin);
pinHigh(pin);
pinLow(pin);
pinHigh(pin);
pinLow(pin);
pinHigh(pin);
pinLow(pin);
// Some logic added, but wrapping removed slows down to 1.44MHz
// HIGH time = 360ns
// LOW time = 336ns
bool state = HIGH;
for(int x=0; x<8; x++) {
state = !state;
if(state) PIN_MAP[pin].gpio_peripheral->BSRR = PIN_MAP[pin].gpio_pin; // HIGH
else PIN_MAP[pin].gpio_peripheral->BRR = PIN_MAP[pin].gpio_pin; // LOW
}
// Using digitalWrite() slows down to 227kHz
// HIGH time = 2.28us
// LOW time = 2.16us
digitalWrite(pin,HIGH); // This first HIGH time was actually 4.4us,
digitalWrite(pin,LOW); // while the LOW time was 2.16us.
digitalWrite(pin,HIGH); // The next three were actually 2.28us HIGH,
digitalWrite(pin,LOW); // and 2.16us LOW.
digitalWrite(pin,HIGH); // |
digitalWrite(pin,LOW); // |
digitalWrite(pin,HIGH); // |
digitalWrite(pin,LOW); // |
}
void pinHigh(uint16_t pin) {
PIN_MAP[pin].gpio_peripheral->BSRR = PIN_MAP[pin].gpio_pin; // HIGH
}
void pinLow(uint16_t pin) {
PIN_MAP[pin].gpio_peripheral->BRR = PIN_MAP[pin].gpio_pin; // LOW
}