Spark Logic

SPI + ISR + SPCR etc.

HexTank Fri Sep 30, 2016 11:03 am

So I’ve just moved over to the Baite MM, to utilise the faster SPI compared to the arduinos. Now, I’ve tried to move a simple sketch across and hitting compile issues verbatim.

Things aren’t declared such as SPCR, SPDR etc. and using the ISR macro yields constructor errors and what not.

Have these things been setup for the STM32 side of things or is it pragmatically different? I’m not interested in DMA or anything, I’m just looking for a simple interrupt firing when when data has been received as an SPI slave.

Replies

zmemw16 Fri Sep 30, 2016 12:55 pm

do a site search on spi slave 72 results, one prominent title includes maple mini

HexTank Fri Sep 30, 2016 1:19 pm

Add ‘interrupt’ to the equation and you get 4, one of which is this.

I did see SPIClass is used looking at http://www.stm32duino.com/viewtopic.php?t=891&start=10 and googling thereafter which led to github, unfortunately, the PR hasn’t been pulled, and nowhere else on the site is there any mention on on how the handle interrupts, I found than on another external site. The SPIClass seems incomplete, or rather, is if it’s to integrate slave as well as master mode.

I have all the bits I need to hit the hardware now and bypass the libs.

Thanks for the lesson in searching, it was a great help.

Ciao.

stevestrong Fri Sep 30, 2016 1:46 pm

We don’t mind if you would share your code :mrgreen:

zmemw16 Fri Sep 30, 2016 3:04 pm

HexTank wrote:Add ‘interrupt’ to the equation and you get 4, one of which is this.
Thanks for the lesson in searching, it was a great help.

HexTank Fri Sep 30, 2016 7:29 pm

Well, I got as far as

SPI.setModule(2);
SPI.beginSlave();
spi_irq_enable(SPI.dev(), SPI_RXNE_INTERRUPT);

martinayotte Fri Sep 30, 2016 7:40 pm

Vector table is in the file STM32F1/cores/maple/libmaple/stm32f1/performance/vector_table.S.
There is weak default_handler in file STM32F1/cores/maple/libmaple/stm32f1/performance/isrs.S
You need to override this weak handler by writing your own __irq_spi1 function.

HexTank Fri Sep 30, 2016 8:31 pm

What’s the correct syntax for overriding?

I tried thus.

void __irq_spi1()
{
digitalWrite(33, LOW);
}

martinayotte Fri Sep 30, 2016 9:54 pm

Yes, it need to be plain C, but you had a missing “void”, it should be :
extern "C" {
void __irq_spi1(void)
{
digitalWrite(33, LOW);
}
}

HexTank Sat Oct 01, 2016 7:20 am

I get the exact same fail with the C/C++ linkage mismatch. I thought as much as C implicitly assumes int XXXX( void ).

It’s a shame the compiler doesn’t say where the previous declaration was from (I’m assuming it’s the one in the isrs.S)

Ahh, well, this compiles and works.

extern "C" {
void __irq_spi1(void);
}

void __irq_spi1(void)
{
digitalWrite(33, LOW);
}

HexTank Sat Oct 01, 2016 7:54 am

I’m assuming people have had SPI comms working correctly, but things like this concern me.

https://my.st.com/public/STe2ecommuniti … tviews=290

Given the way it’s rigged up now with the Maple code, it’d be reading / writing 32bit values.

martinayotte Sat Oct 01, 2016 2:24 pm

HexTank wrote:
Ahh, well, this compiles and works.
This interrupt is now serviced, although it still hangs, so I guess it’s going to be harder to track the cause of that. :)

HexTank Sat Oct 01, 2016 2:40 pm

Turns off on an interrupt.

Reading the data in to a buffer so I can write out the values in Loop() which is working although the values I’m receiving are all 0xFF, which is wrong. The values sent from the STM to the master are all 0xFF too.

Oddly enough, my ISR is basically a spi.read in to a variable and pass that on to spi.write, I’d I change that variable, say, assign it zero before using it in the spi.write, it hangs. :D

There’s something a bit sensitive about it all, like I said in my previous post, I don’t think the DR access is correct. Even the maple source has casts before reads / writes, thats redirections casts rather than casting the result.

Next step, rest until I have some more ideas on what might be wrong.

racemaniac Sat Oct 01, 2016 6:01 pm

Not sure what kind of interrupt you’re now working on, but one of the issues i regularly encountered when working with interrupts is accidentally causing the interrupt to continuously fire. For some interrupts you must bring the system into a valid state with your handler, and if you don’t, it’ll just keep firing forever and no other code will execute.
But there are so many things that can go wrong with interrupts, i’m glad that for the moment i’m not working with them :p.

HexTank Sat Oct 01, 2016 9:27 pm

I’m just using ( in this case ) global SPI1 intr, looking at the manual, you just need to read SPR_DR for it to empty RX, so unless the compiler is generating dodgy assembler ( not checked yet ) I don’t know. I suppose I’ll need to figure why 0xFF is read from the master first, I know this side works as I had it hooked up to ProMicro, it’s just the ProMicro couldn’t handle an 8mhz clock.

I have a Billy no mates scope on its why from China just to verify all that stuff is OK, but SS and CLK clearly work.

HexTank Fri Oct 07, 2016 6:48 pm

Ok, analyser turned up, what a godsend, it highlighted noobiness on multiple levels.

No matter how many times I checked it appears I still had SCLK and SS the wrong way around, that alone was sure to cause issues. :)
Now, I know I have MISO and MOSI the wrong way around, having them the correct way around causes another SPI device to fail (which is bolted on to the master), so, this begs the question.

Is SS on SPI1 as slave just ignored? as in, when it goes high, it doesn’t go in to a high impedance state?

HexTank Fri Oct 07, 2016 7:04 pm

Hrm, so putting a pullup to Vcc or pulldown to Gnd for SS and SPI interrupt still fires regardless, this pin does nothing in slave, or is this a setup issue?

RogerClark Fri Oct 07, 2016 8:58 pm

Dont use the SS pin for CS.

It has a special function and is not designed to be used as CS.

Basically its some weird function developed by STM, which no one else uses.

We tried to disable this weird use of SS, but I am not sure it was successful. So its better to use a completely different pin for CS functions

HexTank Fri Oct 07, 2016 9:04 pm

Ok I have it working now, thanks for the assists and suggestions etc.

I plugged all my wires to SPI2 and it worked, so I thought maybe the analyser was interfering somehow, so removed those probes and put wires back to SPI1, still works. Put probes back on and still works. :?

For curiosity should anyone fall upon this post. ( a little crude, but will tidy it up after I have finished revelling in success )

#include <SPI.h>

char buf [100];
volatile byte pos;
volatile boolean process_it;

void setup()
{
Serial.begin(9600);
pos = 0; // buffer empty
process_it = false;

SPI.setModule(1);
SPI.beginSlave();
spi_irq_enable(SPI.dev(), SPI_RXNE_INTERRUPT);

pinMode(33, OUTPUT);
digitalWrite(33, HIGH); // turn the LED on (HIGH is the voltage level)
}

extern "C" {
void __irq_spi1(void);
}

void __irq_spi1(void)
{
digitalWrite(33, LOW); // toggle onboard LED to see if we crash out
short b = spi_rx_reg(SPI.dev()); // read data which shoould flush RXNE
spi_tx_reg(SPI.dev(), b); // echo data back to master

if (pos < sizeof buf) // append to a buffer and GTFO of the interrupt
{
buf [pos++] = b;
process_it = true;
}

digitalWrite(33, HIGH); // turn LED back on, we got this far.. oh my.
}

void loop()
{
delay(1000);
Serial.print("*"); // in case we crash whilst LED is still on :D
if (process_it)
{
buf [pos] = 0;
for( int i=0; i<12 && i<pos; i++ )
{
Serial.print(buf[i], HEX);
}
pos = 0;
process_it = false;
}
}

HexTank Fri Oct 07, 2016 9:05 pm

This is just when dealing with master thought, right? A slave with no form of CS as a slave would be pretty much useless. (which is what I’m dealing with)

RogerClark wrote:Dont use the SS pin for CS.

It has a special function and is not designed to be used as CS.

Basically its some weird function developed by STM, which no one else uses.

We tried to disable this weird use of SS, but I am not sure it was successful. So its better to use a completely different pin for CS functions

RogerClark Fri Oct 07, 2016 11:04 pm

We have to use GPIO to control CS, and we can’t use the SS pin for this, as the MCU seems to randomly override the GPIO settings

This is known bug for the F103 device, which a lot of people (not just Arduino users) have complained to ST about.

But from what I recall, ST say that the way it operates is “by design” (even though it looks like a bug)

So just use a different pin for you CS and use digitalWrite to control it

Note. For some devices a hardware SS pin just doesn’t work because of the timing. i.e NSS may go low just a few nS before the data is clocked, and I know at least one device which requires delays between CS going low and the first byte of data being received

Sign in to reply