EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

External SPI Flash for storing data

Started by pozz June 30, 2019
> > I DO NOT USE the linker for either SDRAM or SPIFI Flash. > > The program loads "by hand" the bitmaps from SPI Flash to the SDRAM area. > > Why? I understood that a SPI Flash connected to SPIFI is mapped directly > to the internal address space. So the MCU should access images on SPI > Flash as they are in internal Flash. > >
That's a long story. My system went through a lot of revisions, starting with LPC2478, then LPC1788 and lastly LPC4088. At first there was only the sd card and the bitmaps were loaded from it. When I switched to LPC4088 I hoped that letting the bitmaps in the SPIFI Flash will be faster than having them in SDRAM based on the fact that the SPIFI and SDRAM are on different busses. And it was! And the latest version of the system, indeed, have the bitmaps in SPIFI Flash directly. Unfortunately you cannot use this aproach since you don't use the SPIFI interface.
> > Also loads the big dictionary file from a sd card to the SDRAM area. > > The SDRAM partitioning is very simple, without involving the linker: the frame buffer which is first (at address 0xA0000000) and fixed in size. Next is the bitmap file from the serial flash. The size of the file is self-contained ina small header so it's known. The dictionary loads on top of the bitmaps wherever this address is. > > Regarding the bitmap file: This is a single file in a custom format, which contains a small header for the size (at least). Every bitmap has also a small header in front of it, also for the size. I construct this big file with my own small C program which takes hundreds of bitmaps from a folder. > > A very simple C program in mingw (CodeBlocks). > > And last, the application is using the bitmap images based on their index. The index table (containing the start addresses in the SDRAM) is constructed at the time the file is loaded from serial flash in SDRAM. > > Yes, this is another approach. I will give it a try.
Since the bitmaps were completely external "objects" I tried to make the firmware as decoupled as possible from them. At least, I really didn't want to involve the compiler and linker.
Il 02/07/2019 06:35, raimond.dragomir@gmail.com ha scritto:
>>> I DO NOT USE the linker for either SDRAM or SPIFI Flash. >>> The program loads "by hand" the bitmaps from SPI Flash to the SDRAM area. >> >> Why? I understood that a SPI Flash connected to SPIFI is mapped directly >> to the internal address space. So the MCU should access images on SPI >> Flash as they are in internal Flash. >> >> > That's a long story. My system went through a lot of revisions, starting with LPC2478, then LPC1788 and lastly LPC4088. At first there was only the sd card and the bitmaps were loaded from it. > When I switched to LPC4088 I hoped that letting the bitmaps in the SPIFI Flash will be faster than having them in SDRAM based on the fact that the SPIFI and SDRAM are on different busses. > And it was! And the latest version of the system, indeed, have the bitmaps in SPIFI Flash directly. > Unfortunately you cannot use this aproach since you don't use the SPIFI interface.
I rememeber I tried to choose a MCU with LCD controller, 32-bits SDRAM interface and SPIFI, however I didn't find anything in QFP package, maybe only BGA that we cannot manage. So are you saying that images in SDRAM, together with framebuffer, will be slow? What do you mean with... slow?
> >>> Also loads the big dictionary file from a sd card to the SDRAM area. >>> The SDRAM partitioning is very simple, without involving the linker: the frame buffer which is first (at address 0xA0000000) and fixed in size. Next is the bitmap file from the serial flash. The size of the file is self-contained ina small header so it's known. The dictionary loads on top of the bitmaps wherever this address is. >>> Regarding the bitmap file: This is a single file in a custom format, which contains a small header for the size (at least). Every bitmap has also a small header in front of it, also for the size. I construct this big file with my own small C program which takes hundreds of bitmaps from a folder. >>> A very simple C program in mingw (CodeBlocks). >>> And last, the application is using the bitmap images based on their index. The index table (containing the start addresses in the SDRAM) is constructed at the time the file is loaded from serial flash in SDRAM. >> >> Yes, this is another approach. I will give it a try. > > Since the bitmaps were completely external "objects" I tried to make the firmware as decoupled as possible from them. At least, I really didn't want to involve the compiler and linker.
I was thinking about your approach, it's nice because you don't use compiler/linker. However I'm using emWin as GUI libraries (you too?) so I have to call functions such as: GUI_DrawBitmap(&bmp); where bmp is a pointer to a struct GUI_BITMAP defined by emWin. You said you use a home-made "bitmaps compiler" running on the desktop PC to generate a "file of bitmaps". How are you sure "bitmaps compiler" generates data compatible with emWin running on the target? Even if you define the *same* struct in "bitmaps compiler", it runs on completely different machine and you will have the risk that struct are represented in memory with a different layout (I think of integer size, padding, alignment, and so on). One solution is: extern const GUI_BITMAP *bmp_convert(unsigned int bitmap_index); GUI_DrawBitmap(bmp_convert(BITMAP_BACKGROUND)); bmp_convert() is an helper function that convert the image from "bitmaps compiler" format to a "well-defined in target" GUI_BITMAP, returning its pointer.
> I rememeber I tried to choose a MCU with LCD controller, 32-bits SDRAM > interface and SPIFI, however I didn't find anything in QFP package, > maybe only BGA that we cannot manage. >
LPC2478 - QFP208 LPC1788 - QFP208 LPC4088 - QFP208 - has SPIFI
> So are you saying that images in SDRAM, together with framebuffer, will > be slow? What do you mean with... slow? >
Good question :-) Slower for sure. I have some runtime profiling of the time spent to show a full screen image. As I said, I really wanted to see if SPIFI bitmaps would be faster than SDRAM bitmaps. But don't ask me the figures, don't remember such details. LPC2478 - slow (sdram bitmaps) LPC1788 - faster (sdram bitmaps but 120MHz cpu and other improvements) LPC4088 - same as 1788 with sdram bitmaps LPC4088 - faster with SPIFI bitmaps LPC4088 with everything in SDRAM (including the code!) - slow! - I wanted to see how fast SDRAM execution is but the result is predictable, very important in this kind of MCU is the parallelism of the internal busses. The idea is that the LCD bus master uses the SDRAM for the frame buffer quite intesively, and the CPU should be updating the same framebuffer. With bitmaps in SDRAM, the CPU will access the SDRAM for both read and write. With bitmaps in SPIFIFlash the CPU will access the SDRAM only for write.
> > > >>> Also loads the big dictionary file from a sd card to the SDRAM area. > >>> The SDRAM partitioning is very simple, without involving the linker: the frame buffer which is first (at address 0xA0000000) and fixed in size. Next is the bitmap file from the serial flash. The size of the file is self-contained ina small header so it's known. The dictionary loads on top of the bitmaps wherever this address is. > >>> Regarding the bitmap file: This is a single file in a custom format, which contains a small header for the size (at least). Every bitmap has also a small header in front of it, also for the size. I construct this big file with my own small C program which takes hundreds of bitmaps from a folder. > >>> A very simple C program in mingw (CodeBlocks). > >>> And last, the application is using the bitmap images based on their index. The index table (containing the start addresses in the SDRAM) is constructed at the time the file is loaded from serial flash in SDRAM. > >> > >> Yes, this is another approach. I will give it a try. > > > > Since the bitmaps were completely external "objects" I tried to make the firmware as decoupled as possible from them. At least, I really didn't want to involve the compiler and linker. > > I was thinking about your approach, it's nice because you don't use > compiler/linker. However I'm using emWin as GUI libraries (you too?) so > I have to call functions such as: > > GUI_DrawBitmap(&bmp); > > where bmp is a pointer to a struct GUI_BITMAP defined by emWin. You said > you use a home-made "bitmaps compiler" running on the desktop PC to > generate a "file of bitmaps". How are you sure "bitmaps compiler" > generates data compatible with emWin running on the target? > Even if you define the *same* struct in "bitmaps compiler", it runs on > completely different machine and you will have the risk that struct are > represented in memory with a different layout (I think of integer size, > padding, alignment, and so on). > > One solution is: > > extern const GUI_BITMAP *bmp_convert(unsigned int bitmap_index); > GUI_DrawBitmap(bmp_convert(BITMAP_BACKGROUND)); > > bmp_convert() is an helper function that convert the image from "bitmaps > compiler" format to a "well-defined in target" GUI_BITMAP, returning its > pointer.
I don't use emWin. I use a personal library that I developed over time. It's history started with a mono-chrome one.
Il 02/07/2019 10:31, raimond.dragomir@gmail.com ha scritto:
>> I rememeber I tried to choose a MCU with LCD controller, 32-bits SDRAM >> interface and SPIFI, however I didn't find anything in QFP package, >> maybe only BGA that we cannot manage. >> > > LPC2478 - QFP208 > LPC1788 - QFP208 > LPC4088 - QFP208 - has SPIFI
Do you know if LPC4088 is pin-to-pin compatible with LPC1788? I'm using QFP208 too, but LPC1785. Maybe LPC4088 is pin-to-pin compatible with LPC1785 too.
>> So are you saying that images in SDRAM, together with framebuffer, will >> be slow? What do you mean with... slow? >> > Good question :-) > Slower for sure. I have some runtime profiling of the time spent to show a full screen image. As I said, I really wanted to see if SPIFI bitmaps would be faster than SDRAM bitmaps. But don't ask me the figures, don't remember such details. > LPC2478 - slow (sdram bitmaps) > LPC1788 - faster (sdram bitmaps but 120MHz cpu and other improvements)
^^^^^^^ I'm here, with LPC1785 running at 120MHz. I hope your "faster" will be good for my application.
> LPC4088 - same as 1788 with sdram bitmaps > LPC4088 - faster with SPIFI bitmaps > LPC4088 with everything in SDRAM (including the code!) - slow! - I wanted to see how fast SDRAM execution is but the result is predictable, very important in this kind of MCU is the parallelism of the internal busses. > > The idea is that the LCD bus master uses the SDRAM for the frame buffer quite intesively, and the CPU should be updating the same framebuffer. With bitmaps in SDRAM, the CPU will access the SDRAM for both read and write. With bitmaps in SPIFIFlash the CPU will access the SDRAM only for write.
I see.
>>>>> Also loads the big dictionary file from a sd card to the SDRAM area. >>>>> The SDRAM partitioning is very simple, without involving the linker: the frame buffer which is first (at address 0xA0000000) and fixed in size. Next is the bitmap file from the serial flash. The size of the file is self-contained ina small header so it's known. The dictionary loads on top of the bitmaps wherever this address is. >>>>> Regarding the bitmap file: This is a single file in a custom format, which contains a small header for the size (at least). Every bitmap has also a small header in front of it, also for the size. I construct this big file with my own small C program which takes hundreds of bitmaps from a folder. >>>>> A very simple C program in mingw (CodeBlocks). >>>>> And last, the application is using the bitmap images based on their index. The index table (containing the start addresses in the SDRAM) is constructed at the time the file is loaded from serial flash in SDRAM. >>>> >>>> Yes, this is another approach. I will give it a try. >>> >>> Since the bitmaps were completely external "objects" I tried to make the firmware as decoupled as possible from them. At least, I really didn't want to involve the compiler and linker. >> >> I was thinking about your approach, it's nice because you don't use >> compiler/linker. However I'm using emWin as GUI libraries (you too?) so >> I have to call functions such as: >> >> GUI_DrawBitmap(&bmp); >> >> where bmp is a pointer to a struct GUI_BITMAP defined by emWin. You said >> you use a home-made "bitmaps compiler" running on the desktop PC to >> generate a "file of bitmaps". How are you sure "bitmaps compiler" >> generates data compatible with emWin running on the target? >> Even if you define the *same* struct in "bitmaps compiler", it runs on >> completely different machine and you will have the risk that struct are >> represented in memory with a different layout (I think of integer size, >> padding, alignment, and so on). >> >> One solution is: >> >> extern const GUI_BITMAP *bmp_convert(unsigned int bitmap_index); >> GUI_DrawBitmap(bmp_convert(BITMAP_BACKGROUND)); >> >> bmp_convert() is an helper function that convert the image from "bitmaps >> compiler" format to a "well-defined in target" GUI_BITMAP, returning its >> pointer. > > I don't use emWin. I use a personal library that I developed over time. It's history started with a mono-chrome one.
I see.
marți, 2 iulie 2019, 11:58:11 UTC+3, pozz a scris:
> Il 02/07/2019 10:31, raimond.dragomir@gmail.com ha scritto: > >> I rememeber I tried to choose a MCU with LCD controller, 32-bits SDRAM > >> interface and SPIFI, however I didn't find anything in QFP package, > >> maybe only BGA that we cannot manage. > >> > > > > LPC2478 - QFP208 > > LPC1788 - QFP208 > > LPC4088 - QFP208 - has SPIFI > > Do you know if LPC4088 is pin-to-pin compatible with LPC1788? I'm using > QFP208 too, but LPC1785. Maybe LPC4088 is pin-to-pin compatible with > LPC1785 too. >
I don't remember, but there are great chances. When I switched to 4088 I was changing some things here and there, especially adding the serial flash. If you have a 1785 I don't know if 4088 brings something to you, as long as you don't use the SPIFI anyway. There are some other improvements of course, like the eeprom, but I don't remember something big. The SDRAM is still 80MHz max. I tested two configurations, CPU=120MHz, SDRAM=60MHz and CPU=SDRAM=80MHz. In my system these two configurations worked about the same. I've chosen the CPU=120MHz, SDRAM=60MHz. I have also tested CPU=SDRAM=96Mhz, and it worked very well. In fact, the LPC1788 variant is only working at 96MHz, with many units in the field. Well, the "field" is very friendly room temperature, lets say 15-35 degree Celsius...
Den 2019-07-01 kl. 00:15, skrev pozz:
> I have a board with Cortex-M3 NXP LPC1875 MCU with 512kB internal Flash, > one 8MB external SDRAM and 2MB external SPI Flash. The external Flash is > connected to a normal SPI, not SPIFI (in other words, it isn't mapped to > the internal address space). Insted the SDRAM is mapped to the internal > address space, starting from address 0xA000 0000. > > The application will use a 480x272 RGB LCD connected to the internal LCD > controller of the MCU. This controller needs a framebuffer for the > display, so the need of SDRAM. > Moreover the application will use many constant images that can't be > stored in the small internal Flash. > > The idea is to save the images (more generally constant data) to the > external SPI Flash and copy all of them to external SDRAM at startup, > that is big enough for everything (framebuffer, constant data and others). > Now I'm trying to arrange a good strategy for the use of external > Flashin this scenario. > > I'm thinking to create the following sections for the linker: > - SPI_FLASH: type=ROM, base address=0xA000 0000, size=2MB > - SDRAM: type=RAM, base address=0xA020 0000, size=6MB > > The constant images will be allocated to SPI_FLASH section, so the > linker will put them directly to the beginning of SDRAM address space. > The trick of defining the SPI_FLASH section as ROM (really it's RAM > space) allows the linker to put the constant data directly there (a > .text read-only section), thinking that it's a non volatile memory > (otherwise, it would have put constants in the .data section of another > ROM area). > The copy from external Flash to 0xA000 0000 is a very simple task. After > this copy, the code could run as usual. > > Now the only problem is how to program the internal and external Flash > starting from the output of the linker. Indeed in the output file the > constant images are in the SDRAM address space, so if we use the output > file as is, the images will be lost after the first power down. > > My idea is to write a USB bootloader that receives the output file as > is. The bootloader should know how to read/write to the external Flash > and know that it is mapped to area 0xA000 0000. > However there are some drawbacks of this approach. > > The debug&test process will be slow. I can't use the IDE as usual to > launch a debug session. If some constant data saved in external Flash > changs, I need to use the bootloader (and the companion sw on the PC) to > upgrade the external Flash first. So I need at least two connections > between developing machine and target: the USB and the debug probe. > However this drawback can be accepted. The project can be compiled in > mingw platform (i.e., in Windows), so most of the debug will be done in > Windows PC where the problem of external Flash doesn't apply. The number > of times I will need to debug&test directly on the target will be small. > > The second drawback again relates to debug process. What happens if I > launch a debug session with an output file that has some initialized > data in SDRAM address space? I think I would receive an error, because > the debugger is able to program data in the address space of the > internal Flash. I'm not sure what happens if it encounters data in the > external SDRAM address space. Maybe I need to use a Flash driver (as in > MCUXpresso naming). > > I don't know if there are some better approaches.
With an IAR C compiler you can define write your own flashloader. When you download the code using the debugger, the flashloader will program the SPI flash. The linker can generate copy tables which can be used for copying from the SPI flash to the SDRAM. The actual copy routine, you have to write yourself. AP

The 2024 Embedded Online Conference