Search code examples
carduinospimsp430

Assistance with understanding serial communication (SPI) on the Arduino Mega


So I am trying to translate some code for operating an LCD from Arduino to C for an MSP430F5529. The LCD uses SPI for communication and I am confused on how this code is causing the Arduino to communicate with it properly, and was hoping that someone with decent Arduino experience would be able to explain some things (I have never used one). I have linked to the entire program on pastebin at the end, but this is the section I am focused on right now:

void comm_out(char c)
{
  int i;
  digitalWrite(CS, LOW);
  digitalWrite(AO, LOW);
  for(i=0;i<8;i++)
  {
    if((c&0x80) == 0x80)
    {
      PORTA |= 0x80;
      PORTA &= ~0x40;
      PORTA |= 0x40;
    }
    else
    {
      PORTA &= ~0x80;
      PORTA &= ~0x40;
      PORTA |= 0x40;
    } 
    c = c<<1;
  }
  digitalWrite(CS, HIGH);
  digitalWrite(AO, HIGH);
}

So I understand any of the code that has to do with setting some of the digital pins on the Arduino (looks like they are only ever output because the program never sets a direction for them) to high or low as that is pretty straight forward, but I don't quite get what the for loop is doing in terms of SPI.

I get what the function is doing directly. It gets an 8-bit input that it decided was a character (though that doesn't really mater) and checks to see if the first bit is a 1 or 0. If it is a 1 it sets PORTA to the following in 3 steps:

1: 1xxx xxxx 2: 10xx xxxx 3: 11xx xxxx

and if it is a 0 then it sets PORTA to the following in 3 steps:

1: 0xxx xxxx 2: 00xx xxxx 3: 01xx xxxx

It then shifts the input so that the next bit is highest and does the check again until its checked all 8 bits. But I have no clue what this is doing to the Arduino that makes it properly communicate to the LCD over serial. From all the documentation I've checked I can't even determine what PORTA is. I had assumed that it might be mapped to some kind of module for serial communication but it doesn't seem like it.

The other thing I was confused about were the declarations at the top

int SCLK = 28; // SCL signal connected to digital pin 28 of Arduino Mega     
int SI = 29; // SI signal connected to digital pin 29 of Arduino Mega     
int CS = 30; // CS signal connected to digital pin 30 of Arduino Mega     
int RES = 31; // RES signal connected to digital pin 31 of Arduino Mega     
int AO = 32; // A0 signal connected to digital pin 32 of Arduino Mega

A0, RES, and CS are all fine because those are just static pins that are set up for down, but SI is supposed to be serial input and SCLK is supposed to be the clock signal for SPI, but as far as I can tell in doccumentation port 28 and 29 aren't anything special and just generic I/O ports.

Here is the port map I was referring to: http://pighixxx.com/atmega2560v3_0.pdf

Here is the the link to the entirety of the code: http://pastebin.com/DxMGJZDu

Any advice or rather, any anything? I am struggling to make sense of this.


Solution

  • This code implements SPI with bit banging, which

    is a technique for serial communications using software instead of dedicated hardware. Software directly sets and samples the state of pins on the microcontroller, and is responsible for all parameters of the signal: timing, levels, synchronization, etc.

    In SPI, the receiving device reads the state of the data line when a certain edge happens on the clock line (raising or falling; either is possible, depending on the device).

    For each bit, this code sets the value of the data line, and then cycles the clock line low and high.