PDA

View Full Version : PIC24 clear SPI slave FIFO



The Master
- 1st July 2014, 20:50
Hi,

I'm using a PIC24FJ64GA002 chip as an SPI slave with FIFO buffers enabled. It has CLK, MOSI, MISO and SS pins connected.

The datasheet says:
"A transmission will be aborted when the SSx pin goes high and may be retried at a later time. Each data word is held in SPIxTXB until all bits are transmitted to the receiver"

My code only writes to the transmit FIFO while SSx is asserted. If SSx goes high at any point I want the transmit FIFO to be cleared and my code will retry the send later. The question is, how do I clear the entire transmit FIFO and SPIxTXB?

TommyLehmann
- 13th December 2014, 21:13
Hi,

I have a similar problem. Have you already found a solution?


Best regards

Tommy Lehmann

towlerg
- 13th December 2014, 22:04
I'm confused, your using a PIC24 with PICBasic? How so?

George

Demon
- 13th December 2014, 22:53
He's not. That's why Offtopic. :)

Robert

The Master
- 14th December 2014, 00:11
Tommy: I never got a definitive answer. My circuits never worked properly and I can't say if it was due to the buffer not clearing or some other bug so in the end I switched to the UART module instead. I prefer SPI for it's use of a clock line but UART won due to it's asynchronous nature which simplified a lot of the code. It's a shame the asynchronous version of SPI doesn't work in my chips.

George: I always use MPASM for PIC10/12/16/18 and ASM30 for PIC24. This question was about the PIC itself though so the language doesn't really matter (and, as Robert said, is why it's posted in Off Topic)

Demon
- 14th December 2014, 01:13
Off on a tangent, can you give your impression of ASM30, the costs of using it (software/hardware)?

I remember branch register and that's it from college. It's been bugging me to get back in asm ever since I saw some asm in this forum.

Robert

towlerg
- 14th December 2014, 02:44
Oops, my bad.

George

The Master
- 19th December 2014, 18:51
Robert: Sorry for the long delay. Too much going on around Christmas.

I quite like ASM30. It took a bit of getting used to as a lot of things work differently from MPASM and there are more commands but now I'm into it I like it much better. The only problem with Assembly in general is that it takes ages to write anything.

The built in macro support is only suitable for very basic things though and I usually find problems passing labels created with .equ into a macro. These days I don't use ASM30 macros at all. Instead, I define functions in PHP that write out the ASM30 code. It allows for much more compile time logic and can do things that Assembly macros will probably never do such as pulling in values from a website and inserting them in the ASM code.

I bought an ICD3 to write the code onto the PICs as my old programmer only supported up to PIC18. These aren't cheap but I'm glad I went with the ICD3 though because it is also a debugger. I honestly don't know how I used to debug things without being able to read all SFRs and RAM directly from the chips. So far I haven't paid for any software. MPLAB comes on a disc with the ICD3. I believe you have to pay if you want to use a C compiler (which is the main reason I'm still writing ASM)

The Master
- 18th January 2015, 00:43
I've finally got around to doing some proper tests on the SPI buffers.

I can confirm that de-asserting SS does not clear the slave's transmit buffer. This is almost certainly why my original code wasn't working properly.

Disabling and re-enabling the SPI module does clear the transmit buffer. I didn't need any NOPs between disabling and re-enabling so the whole thing only takes 2 instruction cycles and it's easy enough to program the master to pause for a few NOPs after de-asserting SS to make sure it doesn't try to send again while the slave is still resetting.
This method of resetting the buffer does feel a bit wrong but it's the only thing I've found that works.

I've also tried another method. This involves keeping the SPI module disabled and only enabling it once SS is asserted. I created a change notification interrupt handler to do this automatically.


.global __CNInterrupt
__CNInterrupt:

BTSS ss_reg, #ss
BSET SPI1EN_reg, #SPI1EN
BTSC ss_reg, #ss
BCLR SPI1EN_reg, #SPI1EN
RETFIE


When the SS line is asserted (active low) the module is enabled and when it is de-asserted (high) the module is disabled again. Just keep in mind that the master must pause after asserting SS. The enable/disable code is 4 instructions long and the PIC will also take a few cycles to jump into the interrupt. Notice how the BTSS/BSET come first though. This means that the module will be enabled 2 cycles faster than it will be disabled (enabling fast is likely to be more important).

If multiple SPI slaves are used then the data output pin must be set as an input. This is because disabling the module will turn the pin back into a standard IO pin. If it's configured as an output then it will hold the line in 1 state which will prevent any other slaves from sending to the master.
Note: Some PICs may require the TRIS to be set to output in order for the SPI module to work. Thankfully the ones that I use bypass the TRIS when the module is enabled.

I still don't like the fact that the module is being disabled at all but this way does feel a bit nicer and I guess there will probably be a small power saving while the module is off so this is the method I'll be using in my SPI slaves until someone can point be in a better direction.

Hopefully other people will find this post useful if they come across the same problem.