chipKIT® Development Platform

Inspired by Arduino™

Trouble with SPDR SPCR

Created Sun, 05 Jun 2011 01:48:11 +0000 by Jacob Christ


Jacob Christ

Sun, 05 Jun 2011 01:48:11 +0000

I'm trying to get some contributed libraries working and they are trying to access the SPDR and SPCR registers and I'm getting errors.

error: 'SPCR' was not declared in this scope error: 'SPSR' was not declared in this scope

I tried to just access these from the setup() or loop() and get the following errors:

sketch_jun04c.cpp:26:9: error: 'SPCR' was not declared in this scope sketch_jun04c.cpp:27:9: error: 'SPSR' was not declared in this scope

I see they are being used in the spi.h and spi.cpp files and I tried to include the same files they do and get more errors.

I think this is related to this issue:

http://www.chipkit.org/forum/viewtopic.php?f=6&t=31

Jacob


Jacob Christ

Tue, 07 Jun 2011 21:15:52 +0000

I think I'm understanding this issue, if others run across the problem this topic seems to be the why its happening:

http://www.chipkit.org/forum/viewtopic.php?f=6&t=32&p=354#p354

Jacob


Jacob Christ

Wed, 08 Jun 2011 07:53:33 +0000

To expound further on this issue for those whom may tread after me (including myself at some later point in life with less memory cell intact):

SPDR and SPCR refer to the SPI Data and SPI Config registers of the AVR processors, of which I've never used so I didn't recognize there function immediately. The library I was looking at is setting bits in these registers to change the SPI mode rather than using a library call (which may not exist).

This is accomplished using the CKP and CKE bits of the SPIxCON register of the PIC32.

My confusion came mostly due to a misconception on my part that the Arduino platform provided greater abstraction from the micro-controller than it actually does topped off with the libraries directory off the root of the mpide directory having the AVR code in it and not seeing the PIC code off the bat. (which exists in the ./hardware/pic32/libraries/ directory). So I thought the PIC was running using these registers in the SPI library but it is actually not.

I was able to get the SPI clocking and transmitting data using this code on the Uno32:

#if defined(__PIC32MX__)
  #include <plib.h>
#endif

#include <SPI.h>

void setup(){
  // Notes:  Arduino Uno Pin 13 is the SPI SCLK pin
  // Notes:  Arduino Uno Pin 12 is the SPI MISO pin
  // Notes:  Arduino Uno Pin 11 is the SPI MOSI pin
  // Notes:  Arduino Uno Pin 10 is ???
  // Notes:  Arduino Uno Pin 9 goes only to connector
  // Notes:  Arduino Uno Pin 8 goes only to connector
  pinMode(8, OUTPUT);

  SPI.begin();
  //SPCR = 0x51;
  //SPDR = 0x50;
#if defined(__PIC32MX__)
  SPI2BRG = 0x1ff; // Slow the SPI way down for my lazy scope...
#endif
}
void loop(){
  digitalWrite(8, LOW);
  SPI.transfer(0x55);
  digitalWrite(8, HIGH);
}

Jacob

My two axioms of embedded development First Axiom: If the tools work, then your job is easy. Second Axiom: The tools never work.


alvesjc

Sun, 07 Oct 2012 01:10:27 +0000

Hi!

I'm bumping on this issue right now.

I'm getting a lot of errors like this:

" D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp: In function 'byte mmc::readSector(byte*, uint32_t)': D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp:226:2: error: 'SPDR' was not declared in this scope D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp:230:12: error: 'SPSR' was not declared in this scope D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp:230:25: error: 'SPIF' was not declared in this scope D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp:235:11: error: 'SPSR' was not declared in this scope D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp:235:24: error: 'SPIF' was not declared in this scope "

I've tried to include <SPI.h> but it complains that doesn't exists.

Can you help regarding this?

Thank you.

BR,

Joao


majenko

Sun, 07 Oct 2012 08:23:42 +0000

Just including SPI.h (or DSPI.h) will have no effect.

The library will need re-writing so that it doesn't use AVR registers at all.

TBH, anyone who wrote a library for the Arduino that used SPI, but didn't use the SPI library should be shot (for starters). The whole point of the SPI library is that it was to provide a layer of abstraction from the hardware. But, oh no... so many idiots just went ahead and wrote libraries that access AVR registers directly.

So, now that there is more than just the AVR in circulation with the Wiring platform, 90% of libraries that work with SPI will not work on anything but AVR chips.

(I hasten to note that my libraries always use the SPI or DSPI library ;) )

So, you will have to delve into the library, find out what it's doing, and re-write it for the DSPI (preferably) library.

You can surround your modifications with

#if defined(__PIC32MX__)
... your code ...
#else
... original code ...
#endif

so that it remains compatible with the Arduino.


alvesjc

Sun, 07 Oct 2012 11:51:35 +0000

Hi.

Ok, thank you for your answer.

I'll try to see what to change, I'll need to understand both libraries first.

Regards,

Joao


majenko

Sun, 07 Oct 2012 13:39:52 +0000

You'll need to familiarise yourself with those SPI registers in the ATmega328p data sheet as well.


alvesjc

Sun, 07 Oct 2012 17:50:00 +0000

This is a huge mess.

I'm trying to match the registers and its content.

So it seems that:

SPDR matches with SPIxBUF; SPCR with SPIxCON; SPSR with SPIxSTAT;

Right now I'm stuck at status registers.

What would be the best match for SPIF bit in SPSR for AVR looking to SPIxSTAT? SPITBE bit?

For refence about what I'm asking, page 174 in http://www.atmel.com/Images/doc8161.pdf and page 387 from http://ww1.microchip.com/downloads/en/devicedoc/pic32mx_datasheet_v2_61143b.pdf

The first functions I'm looking to from mmc.cpp in tinyfat lib are:

static void spiSend(uint8_t data)

static uint8_t spiRec(void) { spiSend(0XFF); return SPDR; }

This I think I can change to:

static void spiSend(uint8_t data)

static uint8_t spiRec(void) { spiSend(0XFF); return SPI1BUF; }

Is this correct?


majenko

Sun, 07 Oct 2012 18:08:07 +0000

Why not just #include <DSPI.h> file, create a new DSPIx object for the channel you want to use, and then call the functions of that object instead of messing with registers?


alvesjc

Sun, 07 Oct 2012 18:57:52 +0000

Well, basically because I've found it harder to find where to apply DSPI functions.

For example, mmc::initialize is a mix of functions where it includes the SPI initialization.

But I'll try to narrow all the SPI stuff again.


alvesjc

Sun, 07 Oct 2012 22:16:38 +0000

Hi again.

I've followed your suggestion, but no luck so far.

I've got rid of the SPDR like error msgs, but still can't compile.

I'm getting this errors now.

D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp: In function 'uint8_t mmc::initialize(uint8_t)': D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp:124:9: error: cannot convert 'volatile uint32_t*' to 'volatile uint8_t*' in assignment D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp:126:11: error: cannot convert 'volatile uint32_t*' to 'volatile uint8_t*' in assignment D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp:128:11: error: cannot convert 'volatile uint32_t*' to 'volatile uint8_t*' in assignment D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp:130:10: error: cannot convert 'volatile uint32_t*' to 'volatile uint8_t*' in assignment D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp: In function 'byte mmc::writeSector(const byte*, uint32_t)': D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp:298:26: error: invalid conversion from 'const byte*' to 'uint8_t*' D:\Docs\ChipKit\mpide-0023-windows-20120811-test.\hardware\pic32\libraries\tinyFAT\mmc.cpp:298:26: error: initializing argument 2 of 'void DSPI::transfer(uint16_t, uint8_t*)'

Just in the first error, in line 124 I've this line:

P_SS	= portOutputRegister(digitalPinToPort(_SS));

I don't understand what the compiler wants now. Can you help?

File is attached.


majenko

Mon, 08 Oct 2012 11:08:42 +0000

I don't know where P_SS et al are defined, or what they are defined as.

However, the Arduino is 8 bit, so all the registers are 8 bit. The ChipKit is 32 bit, therefore all the registers are 32 bit.

It is quite likely that P_SS et al are defined as 8 bit unsigned variables, which is fine when you're working with 8 bit unsigned registers. But on the ChipKit you will need to expand them to 32 bit unsigned variables.