How to use own memory with SPI hardware driver DevHwSpi

Discussion about writing software for VS1005 and the VSOS Operating System. Also posts about VS1005-related hardware design and device drivers should be posted here.
User avatar
Henrik
VLSI Staff
Posts: 1107
Joined: Tue 2010-06-22 14:10

How to use own memory with SPI hardware driver DevHwSpi

Post by Henrik » Wed 2015-02-04 10:35

Hello Nishikant!

You asked how to use your own SPI memory connected to VS1005's SPI0 or SPI1. I will show here an example.

1) First connect your SPI memory to your VS1005 board. Let's assume you want to use GPIO0_15 as your chip select.
2) Add the following code to VSOS 3.20's file vsos_vs1005g.h. In that file you will find very similar code that creates the 'S' system disk. You could add your code right after it:

Code: Select all

{
  static DEVICE mySpiFlash; // this SPI flash device (only one flash per design is supported)
  static DEVICE mySpi; // the SPI bus used to connect to this SPI flash
  static const devHwSpiHwInfo myHwInfo = {
    (__mem_y spiRegisters*)SPI0_CF, // SPI0_CF for SPI0, SPI1_CF for SPI1
    // The following csPin field may have one of three values:
    // - 0xFFFF = 74HC138 address decoder connected to GPIO0_11, GPIO1_00, and GPIO1_15.
    //            This is the case with the VS1005g Developer Board connection to SPI0
    // - 0x0FFF = Use VS1005 internal flash memory chip select
    // - 0x00xy = USE GPIO port x pin y. E.g. GPIO0_15 = 0x0f
    0x0f, // csPin
    // The following field is the iochannel number.
    // - If csPin = 0xFFFF, then here must be 74HC138 address decoder select pattern.
    //   On the VS1005g Developer Board the value must be 3.
    // - If using internal flash memory or a dedicated GPIO pin, the number doesn't matter.
    3, // io channel number (74HC138 address decoder select pattern)
    // clockDivider is what gets written to register SPI0_CLKCF / SPI1_CLKCF bits 9:2
    1, //speed (clock divider)
  };

  // Create Spi device. After calling this function, you can use the functions in devHwSpi.h
  // If your device is something else than memory, this is the final step supported by VSOS
  DevHwSpiCreate(&mySpi, &myHwInfo, 0);

  // If you want to have a file system on your SPI memory, you'll get it with the following
  // steps.
  DevSpiFlashCreate(&spiFlash, &spi, 2048); // 2048 = 2048 KiBytes. Change as appropriate.
  // Finally, assign a drive letter to the memory.
  // Example: If assigning letter 'B', use 'B'-'A' here.
  vo_pdevices['B'-'A'] = &spiFlash;
}
If you don't want to modify VSOS, you can also create the driver in your application, but in that case I think you need to copy files devHwSpi.c and devSpiFlash.c from the VSOS sources. In this case you'll end up with having the drivers twice in the memory.

Note that if you want to use the DevSpiFlash, you need to format the drive with your PC. To get it to show on your PC, create a configuration that loads an application that executes the following code:

Code: Select all

// Shows device as a USB mass storage drive to PC
VoMassStorage('B');
You will first get a linker error, but see what functions the linker is complaining about, and copy appropriate files from VSOS until your program links.

Kind regards,
- Henrik
Good signatures never die. They just fade away.

nishikant
Senior User
Posts: 78
Joined: Mon 2014-12-08 15:39

Re: How to use own memory with SPI hardware driver DevHwSpi

Post by nishikant » Wed 2015-02-04 11:06

Hi Henrik,
Thanks for the Reply....
As discussed before, i want to interface one EEPROM (which supports only SPI interface) with SPI0 of VS1005, because i have already used SPI1(as a slave device) for some other interface.
VS1005 uses SPI0 for Internal/External flash interface. I want to use the VS1005's Internal flash which is using SPI0, and then i need to interface the EEPROM with the same SPI0.
I don't think the solution which you have mentioned will work for this.
so could you please take a look on this.
waiting for quick response from your end....

User avatar
Henrik
VLSI Staff
Posts: 1107
Joined: Tue 2010-06-22 14:10

Re: How to use own memory with SPI hardware driver DevHwSpi

Post by Henrik » Wed 2015-02-04 14:51

Hello Nishikant,
nishikant wrote:As discussed before, i want to interface one EEPROM (which supports only SPI interface) with SPI0 of VS1005, because i have already used SPI1(as a slave device) for some other interface.
Yes.
nishikant wrote:VS1005 uses SPI0 for Internal/External flash interface. I want to use the VS1005's Internal flash which is using SPI0, and then i need to interface the EEPROM with the same SPI0.
Yes.
nishikant wrote:I don't think the solution which you have mentioned will work for this.
It should.

After running this example you should have system drive 'S' which, depending on your kernel, is the default internal or external flash. You should also have 'B', which is your own flash connected to SPI0, but with GPIO0_15 as chip select.

Kind regards,
- Henrik
Good signatures never die. They just fade away.

User avatar
Panu
VLSI Staff
Posts: 2586
Joined: Tue 2010-06-22 13:43

Re: How to use own memory with SPI hardware driver DevHwSpi

Post by Panu » Thu 2015-02-05 11:25

I want to use the VS1005's Internal flash which is using SPI0, and then i need to interface the EEPROM with the same SPI0.
I don't think the solution which you have mentioned will work for this.
It basically works - you will have the two drives 'S' and 'B', but if you use the same DevSpiFlash device driver for both flashes, they will corrupt each other's writes because there is only one 4-kilobyte cache - and it might corrupt each others reads too, I don't remember how it's written. (That's why it says "only one flash per design is supported" in the comments.) The solution would be
  • 1) to make a separate .DL3 driver for the "B:" flash so that it allocates a 4-kilobyte cache buffer of its own
  • or 2) to write code to invalidate the cache when the other flash is accessed
  • or 3) make one of the drivers read only so that it doesn't use the cache
The easiest way to make it work is to make it into a .DL3 driver. And you can show the flash in the PC very if you make a CONFIG.TXT profile [5] which loads the driver as drive 'S' and press [S1] and [S2] together when booting.

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

mar_tin
User
Posts: 14
Joined: Thu 2018-03-08 14:04

Re: How to use own memory with SPI hardware driver DevHwSpi

Post by mar_tin » Mon 2018-03-12 15:29

Hello all,

as a newbie I'm a bit confused of how to do this properly:

I would start new VSOS3 solution, copy the devSpiFlash.c and .h, devHwSpi.c and .h and and include them in the main file. Then I simply put the Henrik's code into the main() function. I should probably put something to init() or fini() but I don't know what exactly. After solution is built I should have the devSpiFl.dl3 (for example) which I will add to the config.txt and it should create the B drive.

Should it work? According to the build errors I am doing it wrong:

Code: Select all

 ?_spiFlash?  ?_spi?  ?_PinToGpioHwLockMask? ERROR: "_spiFlash" is needed but not found anywhere.
- Martin

mar_tin
User
Posts: 14
Joined: Thu 2018-03-08 14:04

Re: How to use own memory with SPI hardware driver DevHwSpi

Post by mar_tin » Fri 2018-03-16 12:19

Ok, got it working now, foolish me :) The error in previous post was obviously due to the missing sources. I started adding one by one, but there was always something else missing.

Anyways, would someone review my changes? I made it a dirty way - without much thinking, just try and see what happens:

1) These are obvious, no need to explain that:
I'm booting from internal and trying to connect to external flash on dev board. Simply got those values from vsos_vs1005g.c.
CS_PIN: 0x0f -> CSPIN_USE_IOCHANNEL
Speed: 1 -> 6144

2) Not sure about this, but this way I only needed to add folowing files to the project: devHwSpi.c / .h, devSpiFlash.c / .h, hwLockPinMask.c

Code: Select all

DevSpiFlashCreate(&spiFlash, &spi, 2048); -> DevSpiFlashCreate(&mySpiFlash, &mySpi, 2048);  
vo_pdevices['B'-'A'] = &spiFlash; -> vo_pdevices['B'-'A'] = &mySpiFlash;
Main.c looks like this:

Code: Select all

/* For free support for VSIDE, please visit www.vsdsp-forum.com */

// Starting point template for creating VSOS3 libraries and device drivers.
// This will create a <projectname>.DL3 file, which you can copy to 
// your VS1005 Developer Board's system disk's SYS subdirectory.

#include <vo_stdio.h>
#include <volink.h>     // Linker directives like DLLENTRY
#include <apploader.h>  // RunLibraryFunction etc
#include <kernel.h>		// Kernel symbols
#include <consolestate.h> // appFlags etc

#include "devSpiFlash.h"
#include "devHwSpi.h"

// If init(), main() or fini() are not needed, remove them from the solution.
// There's no need to have any unneeded functions in the library.


// Startup code for each instance of the library
// If CONFIG.TXT has several instance of the same driver, this is called for each line.
ioresult main(char *parameters) {
	// If this is a device driver, add function handlers with SetHandler
	// or write new values of system variables here. Don't forget to save the
	// old values, you should restore their values in fini().
	//printf("Parameters: '%s'\n",parameters);
	
  static DEVICE mySpiFlash; // this SPI flash device (only one flash per design is supported)
  static DEVICE mySpi; // the SPI bus used to connect to this SPI flash
  static const devHwSpiHwInfo myHwInfo = {
    (__mem_y spiRegisters*)SPI0_CF, // SPI0_CF for SPI0, SPI1_CF for SPI1
    // The following csPin field may have one of three values:
    // - 0xFFFF = 74HC138 address decoder connected to GPIO0_11, GPIO1_00, and GPIO1_15.
    //            This is the case with the VS1005g Developer Board connection to SPI0
    // - 0x0FFF = Use VS1005 internal flash memory chip select
    // - 0x00xy = USE GPIO port x pin y. E.g. GPIO0_15 = 0x0f
    CSPIN_USE_IOCHANNEL, // csPin
    // The following field is the iochannel number.
    // - If csPin = 0xFFFF, then here must be 74HC138 address decoder select pattern.
    //   On the VS1005g Developer Board the value must be 3.
    // - If using internal flash memory or a dedicated GPIO pin, the number doesn't matter.
    3, // io channel number (74HC138 address decoder select pattern)
    // clockDivider is what gets written to register SPI0_CLKCF / SPI1_CLKCF bits 9:2
    6144, //speed (clock divider)
  };
	
  // Create Spi device. After calling this function, you can use the functions in devHwSpi.h
  // If your device is something else than memory, this is the final step supported by VSOS
  DevHwSpiCreate(&mySpi, &myHwInfo, 0);

  // If you want to have a file system on your SPI memory, you'll get it with the following
  // steps.
  DevSpiFlashCreate(&mySpiFlash, &mySpi, 2048); // 2048 = 2048 KiBytes. Change as appropriate.
  // Finally, assign a drive letter to the memory.
  // Example: If assigning letter 'B', use 'B'-'A' here.
  vo_pdevices['B'-'A'] = &mySpiFlash;
	
	return S_OK;
}
Martin.

mar_tin
User
Posts: 14
Joined: Thu 2018-03-08 14:04

Re: How to use own memory with SPI hardware driver DevHwSpi

Post by mar_tin » Fri 2018-05-25 12:17

Hello,

some update on this - we have our own design ready, boards are working with only the internal system flash and external 4MByte flash for audio files connected on SPI1. Everything looks good so far, the only bug I have is in the function:

Code: Select all

DevSpiFlashCreate(&mySpiFlash, &mySpi, 512); // 2048 = 2048 KiBytes. Change as appropriate.
Problem is with the third parameter - if I use 4096, the flash disc appears as 16MByte drive on the PC. Using the 512 vlaue makes the disc appear as 4MByte as it should.

Any suggestions? I can probably leave it like this, but I'm quite unsure about the proper operation of the memory / data consistency etc.

Martin.

User avatar
Panu
VLSI Staff
Posts: 2586
Joined: Tue 2010-06-22 13:43

Re: How to use own memory with SPI hardware driver DevHwSpi

Post by Panu » Fri 2018-05-25 14:24

Umm.... which devSpiFlash.c are you using? Can you post it here (or copypaste as [ code ] text ?)

Seems that I or someone else has changed what the third parameter does.. let's see what it does exactly.

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

mar_tin
User
Posts: 14
Joined: Thu 2018-03-08 14:04

Re: How to use own memory with SPI hardware driver DevHwSpi

Post by mar_tin » Fri 2018-05-25 14:34

This one:
devSpiFlash.c
(9.95 KiB) Downloaded 28 times
EDIT: Ok, it will most likely have something to do with the hw->reservedSectors, which I tried to avoid, but my approach was not the right one, when I see it now..

User avatar
Panu
VLSI Staff
Posts: 2586
Joined: Tue 2010-06-22 13:43

Re: How to use own memory with SPI hardware driver DevHwSpi

Post by Panu » Fri 2018-05-25 15:13

It seems that hw->reservedSectors is not used in that version, it's replaced by a macro RESERVED_SECTORS which should amount to 128 kilobytes and is fixed at compile time. This produces faster code and the extraInfo parameter is used to set the storage size in kilobytes.

You MUST use the RESERVED_SECTORS macro consistently. It's set to 128 kilobytes (256 sectors) to reserve space for two copies of the kernel. If you really want to, you can set that macro to zero if you don't have a kernel in that flash, but you must not remove the use of that macro from the DevSpiFlashCreate function unless you modify all the other places too. I'd recommend to reserve those 128 kilobytes for the kernel to avoid surprises.

The size of the flash is reported by IOCTL_GET_GEOMETRY in the line ((DiskGeometry*)arg)->totalSectors = hw->totalBlocks; - this is what the PC sees as the storage size for formatting.

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

Post Reply