I'm currently trying to code a lower-lever bit shift register (74HC595) for Arduino Zero (that is based on SAMD21 Cortex M0).
I've already done a higher-level class with looks like that :
BitRegister.h
#ifndef BitRegister_h
#define BitRegister_h
#include "Arduino.h"
class BitRegister
{
public:
BitRegister(byte dataPin, byte clockPin, byte latchPin, uint8_t registerSize = 1);
void sendData(uint8_t led);
void shiftOut2(uint8_t bitOrder, uint8_t val);
private:
byte m_dataPin;
byte m_clockPin;
byte m_latchPin;
uint8_t m_registerSize; //allows register's cascade
};
#endif
BitRegister.cpp
#include "BitRegister.h"
//**************************************************************
BitRegister::BitRegister(byte dataPin,
byte clockPin,
byte latchPin,
uint8_t registerSize)
: m_dataPin(dataPin),
m_clockPin(clockPin),
m_latchPin(latchPin),
m_registerSize(registerSize) //Number of register (if cascade)
{
pinMode(m_dataPin, OUTPUT);
pinMode(m_clockPin, OUTPUT);
pinMode(m_latchPin, OUTPUT);
}
//**************************************************************
void BitRegister::sendData(uint8_t led)
{
led -= 1; //first LED is number 1
digitalWrite(m_latchPin, LOW);
for(int i = 1; i < m_registerSize + 1; i++){
int registerNumber = m_registerSize - i; //The number of the register we're working on in the loop
shiftOut(m_dataPin, m_clockPin, MSBFIRST, ~( 1 << (led - registerNumber*8) ) & 0xFF);
}
digitalWrite(m_latchPin, HIGH);
}
void BitRegister::shiftOut2(uint8_t bitOrder, uint8_t val)
{
uint8_t i;
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST)
digitalWrite(m_dataPin, !!(val & (1 << i)));
else
digitalWrite(m_dataPin, !!(val & (1 << (7 - i))));
digitalWrite(m_clockPin, HIGH);
digitalWrite(m_clockPin, LOW);
}
}
The problem is that I have to use it with many registers in cascade ant the shiftOut2 method (based on Arduino's shiftOut method) is really slow (I think due to the multiple digitalWrite).
So based on this SAMD21 Cortex M0 tutorial and on the Arduino Zero Pinout Diagram (below), I tried to create a lower-level of my bit shift register class. 
The problem I'm currently facing is that I don't manage to rewrite the totality of my shiftOut2 method so for my test I have to write the ports numbers in hard directly in the method's body.
I connect my registers to Arduino's pins 10, 11 and 12 which are SAMD21 ports 18, 16 and 19.
The code of my class (which works) is the following :
LowBitRegister.h is the same as BitRegister.h (except class name and class constructor name).
LowBitRegister.cpp
#include "LowBitRegister.h"
//**************************************************************
LowBitRegister::LowBitRegister(byte dataPin,
byte clockPin,
byte latchPin,
uint8_t registerSize)
: m_dataPin(dataPin),
m_clockPin(clockPin),
m_latchPin(latchPin),
m_registerSize(registerSize) //Number of register (if cascade)
{
REG_PORT_DIR0 |= (1 << 18) | (1 << 19) | (1 << 16); //Set dataPin, clockPin and latchPin to OUTPUT
}
//**************************************************************
void LowBitRegister::sendData(uint8_t led)
{
led -= 1; //first LED is number 1
REG_PORT_OUT0 &= ~(1 << 16); //Set latchPin to LOW
for(int i = 1; i < m_registerSize + 1; i++){
int registerNumber = m_registerSize - i; //The number of the register we're working on in the loop
shiftOut2(MSBFIRST, ~( 1 << (led - registerNumber*8) ) & 0xFF);
}
REG_PORT_OUT0 |= (1 << 16); //Set latchPin to HIGH
}
void LowBitRegister::shiftOut2(uint8_t bitOrder, uint8_t val)
{
uint8_t i;
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST)
digitalWrite(m_dataPin, !!(val & (1 << i)));
else
digitalWrite(m_dataPin, !!(val & (1 << (7 - i))));
REG_PORT_OUT0 |= (1 << 19); //Set clockPin to HIGH
REG_PORT_OUT0 &= ~(1 << 19); //Set clockPin to LOW
}
}
As you can see, the only parts I don't manage to rewrite are :
digitalWrite(m_dataPin, !!(val & (1 << i)));
and
digitalWrite(m_dataPin, !!(val & (1 << (7 - i))));
If you have an idea to solve my problem I will be happy to read it.
Thank you!
I finally found a solution (but if you see any optimization I am interested) :
LowBitRegister.h
LowBitRegister.cpp