chipKIT® Development Platform

Inspired by Arduino™

uC32 FLASH usage

Created Fri, 11 Oct 2013 14:33:29 +0000 by ecolomato


ecolomato

Fri, 11 Oct 2013 14:33:29 +0000

Hi all,

I may be crazy to think this, but here is my question ;) I wonder if there is any way of storing at least 2MB of permanent data somewhere in any 'reserved' area of the physical memory map, only for reading purposes. Of course, maintainig 512KB for sketch code.

Thanks!


majenko

Fri, 11 Oct 2013 16:57:39 +0000

You have flash or ram. You can store it in flash, but that takes some of your 512k. Another option would be to us an external flash chip (SPI) but that won't be memory mapped.


ecolomato

Sat, 12 Oct 2013 09:35:02 +0000

You have flash or ram. You can store it in flash, but that takes some of your 512k. Another option would be to us an external flash chip (SPI) but that won't be memory mapped.

I need high speed reading memory mapped data. I've read in datasheet that physical memory map is 4GB size. There are a lot of reserved areas (don't know what for), even a self-programming area for alternative code. Could some of those areas be "burned" with fixed data? if not, what are those reserved areas for?

Thank you for your reply!


majenko

Sat, 12 Oct 2013 11:06:31 +0000

The PIC32 memory map is very complicated. It has multiple "views" of it depending on the context (user, kernel, etc).

The memory map contains everything that the chip does. It has a main block of flash (up to 512K) at physical address 0x1D000000. It has a block of flash reserved for the bootloader (3K / 12K depending on chip) at physical address 0x1FC00000. There is a block of static RAM at physical address 0x00000000. All the SFRs (Special Function Registers) are mapped in from physical address 0x1F800000.

There are other small bits of flash reserver for such things as the configuration settings, but apart from that there is nothing you can "program" except the bootloader flash and the main program flash. The only way you could "add" anything is if you were to open the chip up and rewire the internals.

Similarly, I can't save documents to drive Q: on my computer, as there isn't a drive Q:. Yes, there is "space" for a drive Q:, and I could open the computer up and add another hard drive - something you cannot do with a microcontroller. Or, I could plug in a (slower) USB drive and use that.

The only way of storing that kind of data is external to the PIC32 - or use a different chip with considerably more flash, or an external bus interface.

And how fast do you need, anyway? The PIC32 is capable of SPI at up to 40MHz, and SPI flash chips usually have a "burst" mode where you can transfer big chunks of data very fast. At 40MHz you can get (40000000/8=) 5MB/s transfer rate. With a (typical) 4 byte "header" to start the transfer, to stream out 8KB of data would take roughly ((8192+4)/5000000=) 0.0016392s (or 1.6392ms). And then of course, with DMA, you could be doing said transfer "in the background" while the main CPU is doing other things.

Just store the data "offline" as it were, and copy in the chunks you want to work with at that moment in time into RAM.


ecolomato

Sat, 12 Oct 2013 12:01:05 +0000

Perfect explanation! Now i understand a bit more...

I didn't know that SPI could be so fast. I need to read 10 non-consecutive words(16-bit) every 15ms. Could it assume that requirements? I have understood that random access is slower than secuential. Isn't it?


majenko

Sat, 12 Oct 2013 12:18:02 +0000

With the chip running at 80MHz, the fastest SPI baud rate is F_OSC/2, which is 40MHz. Of course, the flash chip has to be able to cope with that speed - you may need to shop around a bit for a fast one like that.

To read 1 byte from an SPI flash takes 5 transfers. 1 byte for the read command, three bytes for the address, and 1 byte for the data. So, at 40MHz, that would be 40000000/(5*8) = 1MBps, or 1/1000000 = 1µS. That of course is the time taken for the transfer - you also have to add on the time taken to configure the transfer and deal with the data as it arrives. The actual time would be slightly higher.

Doing small transfers like that will always be less efficient, as the general formula is F_SCK/((4+N)*8)Bps, so the higher the N (number of bytes to transfer) the higher the overall throughput.

You can further improve efficiency by keeping the transfers as smooth as possible. Under normal operation with the SPI or DSPI libraries the CPU is locked in a while() loop waiting for a transfer to finish. By using an interrupt driven transfer you can be doing other things while the transfer is taking place, and if you use 32-bit transfers as much as possible that's 64 clock cycles that you can use for doing other things.

In another thread here ([url]http://www.chipkit.org/forum/viewtopic.php?f=7&t=2570[/url]) I have a library for working with SPI SRAM chips - it presents an incredibly simple interface for reading as it looks just like an array of bytes. The SRAM chip I was working with at the time was limited to just 20MHz, so the figures are lower than the theoretical ones we talked about here, but you can see from that how the bigger transfers are much much more efficient. Feel free to take that library and modify it for working with SPI Flash chips (for reading it may work without modification). It just uses the standard DSPI library, so transfers aren't as efficient as they could be.


ecolomato

Thu, 17 Oct 2013 06:32:37 +0000

I'm following your advice, and now I'm using an external SPI flash memory that works great for me!

Now I'm using 2 SPI devices, with different SPI port parameters, so I will use both SPI ports on uC32, but SPI1 shares pins with UART1. It's posible to use both at the same time? SPI flash on SPI1 won't accept data if not SS1.

Thanks!


mikes

Thu, 17 Oct 2013 11:12:21 +0000

Mpide comes with a SoftSPI library that should allow any set of pins to be a spi port.


ecolomato

Thu, 17 Oct 2013 13:31:28 +0000

I thought about that, but I understood that SoftSPI requires much more CPU time than hardware port. Isn't it?


majenko

Thu, 17 Oct 2013 15:32:22 +0000

How do you mean SPI flash won't accept data if not on SS1?

SS1 is just an IO pin. It has no special meaning unless you are either using framed SPI, or doing slave SPI work, neither of which you are doing.

The only caveat is that if the SS pin is set to input then the SPI module switches to slave mode.

I assume you're using the DSPI library? If so, the SS pin is very much nothing special. Yes, it defaults to the "SS1" pin, but it can be absolutely anything you like.

DSPI1 flash_spi;

void setup()
{
  flash_spi.begin(18);
  pinMode(18, OUTPUT);
}

... will set up the SPI1 channel to work with pin D18 as it's SS pin.


mikes

Fri, 18 Oct 2013 00:37:51 +0000

I thought about that, but I understood that SoftSPI requires much more CPU time than hardware port. Isn't it?

The Cpu does more but the transfer time should be the same. The only way the hardware one would be faster is if the speed is very high, or you use interrupt driven transfers so the processor could do other things between changing bits.


ecolomato

Sat, 19 Oct 2013 07:36:34 +0000

How do you mean SPI flash won't accept data if not on SS1? SS1 is just an IO pin. It has no special meaning unless you are either using framed SPI, or doing slave SPI work, neither of which you are doing. The only caveat is that if the SS pin is set to input then the SPI module switches to slave mode. I assume you're using the DSPI library? If so, the SS pin is very much nothing special. Yes, it defaults to the "SS1" pin, but it can be absolutely anything you like.

DSPI1 flash_spi;
void setup()
{
flash_spi.begin(18);
pinMode(18, OUTPUT);
}

... will set up the SPI1 channel to work with pin D18 as it's SS pin.

Sorry but, I have not explained well.

SPI Flash will only accept data if it's SSx pin is low. Then, Could I multiplex data between SPI flash and a Serial device (UART)?

I'm not using DSPI library because it's so slooooow! I'm working on registers. 10 times faster (even more!).

The Cpu does more but the transfer time should be the same. The only way the hardware one would be faster is if the speed is very high, or you use interrupt driven transfers so the processor could do other things between changing bits.

Now SPI transfer at 40Mhz is fast enough. CPU has to do a lot of work between transfers, so it's very important not to overload it. Software emulated peripherals are discarded.


majenko

Sat, 19 Oct 2013 10:10:42 +0000

Ah, I see what you mean now.

Yes, if you raise /SS then the chip will effectively be inert, and you can do what you want with the signal lines. However, you won't be able to use the "normal" serial functions, like Serial1.read(), etc - you will need to directly manipulate the UART registers like you are manipulating the SPI registers. You will need to disable the SPI peripheral, then enable the UART peripheral, do your UART work, then disable the UART to re-enable the SPI.

You may also need to add a small tri-state buffer (74HC245 for example) to the UART lines so you can isolate the UART connection from the chip as the UART signals won't know you've switched off the UART peripheral and would be interfering with the SPI data.

Messy, but doable.


ecolomato

Thu, 24 Oct 2013 09:59:03 +0000

Ok, That's it!

Thank you very much!