Is there a generic way to access a per macrodefinition defined port P, on Photon?
i.e. :
#define SS_DDR <PORT D>
#define PIN SS_DDR <insert magic here to map to pin 2, for example>
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
I’m working on adapting some code to interface RFM12b with the Photon, and I seek to adapt the code for the data direction and port register mapping from AVR to Photon:
The port layout on STM32 controllers is completely different to AVR controllers.
e.g. AFAIK the equivalent of the data direction register uses two bits per pin on STM32 rather than only one on AVRs.
To port a lib from AVR to STM you’d need to dive in a bit deeper
On the other hand setting up the SPI interface, why not just use the dedicated SPI object?
The order of the SPI pins on the breakout board in the link is not the same as the order of the SPI on the Photon. It’s no big deal, but I need to either build my own board or come up with a solution with airwires. Or use sw-spi.
@mihaigalos, first things first. The STM32 doesn’t use the same port control ports as Arduino. As such, there are low-level (high speed) port functions available to toggle pins directly.
Unless you get into the open-source system firmware and make substantial changes, you will not be able to remap the hardware SPI pins. I’m not sure why you need 1:1 mapping since you can wire the two together the way it needs to be wired. Can you explain?
I have some simple code that implements “true” software SPI. What I mean by true is that it will write to and read from the specified software SPI pins like the standard SPI.transfer() function does. I can post it if that interests you.
// Set software SPI pin values - I used the same as the hardware SPI pins
// but you can change to any pins
const int _csPin = A2;
const int _clockPin = A3;
const int _misoPin = A4;
const int _mosiPin = A5;
setup()
{
//...
// Set the soft SPI pin modes
pinMode(_csPin, OUTPUT);
digitalWrite(_csPin, HIGH);
pinMode(_mosiPin, OUTPUT);
digitalWrite(_mosiPin, LOW);
pinMode(_misoPin, INPUT);
pinMode(_clockPin, OUTPUT);
digitalWrite(_clockPin, LOW);
//...
}
loop()
{
//..
SPIxfer(data); // call that only writes data with no return value expected
byte val = SPIxfer(0xFF); // call that writes dummy value and expects return data
//...
}
//inline __attribute__((always_inline))
byte SPIxfer(byte data) {
byte b=0, bit;
for (bit = 0; bit < 8; bit++) { // walks down mask from bit 7 to bit 0
digitalWriteFast(_mosiPin, !!(data & (1 << (7 - bit))));
pinSetFast(_clockPin);
b |= pinReadFast(_misoPin) << (7 - bit);
pinResetFast(_clockPin);
}
return b;
}
The only pins you’d need to cross for HW SPI are the MOSI/MISO pins, since SCK can be taken fix, SS is software adjustable and 3.3/0V can be provided via any GPIO and IRQ could be almost amy other pin too.
You even have the option to use SPI1 (D2~D4 / SS free to choose) if that would suite you better.
If the physical location of your desired HW SCK pin (A3 or D4) provides your “anchor point” for the setup, you’d only need to “twist” MOSI and MISO - the rest of the pins can be 1:1 wired and controlled via SW.
You can even play with the orientation of your board (flip side, beside or under the Photon).