0
votes

I need to send certain data to an FPGA with SPI using my LPC1769. However I don't quite understand how I should approach this. I currently have this code which ends up in the hardfault handler. I'm not allowed to use CMSIS so I had to define the registers myself.

void sendData(uint8_t *buf, uint32_t Length) {
    uint32_t i;
    for (i = 0; i < Length; i++) {
        while (S0SPSR != (1 << 7)) {
            S0SPDR = *buf;
            gpio0WritePin(15, 1);
            gpio0WritePin(15, 0);
            buf++;
        }
    }
return;
}

and my main function:

uint8_t TX[16];
int main(void) {
    SpiInit();
    TX[0] = 0x48;
    TX[1] = 0x65;
    TX[2] = 0x6c;
    TX[3] = 0x6c;
    TX[4] = 0x6f;
    while (1) {
        SPI_Begin();
        sendData((uint8_t*)TX, 5);
        SPI_End();
    }
 }
1
the problem could be just anywhere, especially in the code that is not shown here. You will need to debug it. Examine your fault status registers and track it down.Eugene Sh.
If I change the pointers from buf into standard arrays it will no longer end up in the hard fault handlerArrrow

1 Answers

1
votes

You definitely don't want to go bit-banging data to the SPI bus like that with this kind on modern microcontrollers.

If for some reason you're not allowed to use CMSIS, I would suggest that you have a look at how CMSIS does SPI communication. Open this (or better yet: print it out), and use "Chapter 17: LPC176x/5x SPI" from the LPC176x/5x User Manual as a reference as you go along (pages 410-420). The code should be reasonably easy to follow.

In a nutshell, you need to:

  • enable the SPI controller through the Power Control for Peripherals Register,
  • setup and enable the clock for this peripheral (Perpheral Clock Selection Register),
  • configure the I/O pins associated to SPI (MOSI, MISO, CLK, CS), clock polarity, etc... through the SPI Control Register,
  • setup interrupts so you don't have to waste time looping around status registers while waiting for new data to come in,
  • read and write data 8 bit at a time using the SPI Data Register.

Don't forget to use interrupts, your CPU cycles are best used crunching data than anything else (especially polling status registers, a very common mistake unfortunately).