VS1000b, SPI LOAD

Writing software that controls the system and peripherals such as displays, SD cards, Buttons, LEDs, Serial Ports etc.
HeLiO
Senior User
Posts: 94
Joined: Thu 2011-04-14 12:47

Re: VS1000b, SPI LOAD

Post by HeLiO » Thu 2013-02-14 13:54

Panu wrote:Hi,
I just realized that without taking special precautions, you can't run SpiLoad from RAM because (if you use multiload) you'll probably be writing over that RAM so it's sure to crash. If you're very careful, you could write SpiLoad in assembly language to force it to a location somewhere in IRAM where you'd never link any other code... :oops:

If you were using overlays, I would be able to help but now I must get Pasi to look at this.

how much over the 64K are you exactly?

-Panu
Our engineer says that we are currently based onthe project with firmware image size (TOTAL) = 139, 264 bytes (136 Kb) and can grow even larger.
We also can't afford to use non native function in evry placve where SpiLoad now works so we are thinking of making the another firmware module (that is places in 16-bit area addressing) that will only do the work with loading from Spi Flash at the addresses > 16 bit.
But the fucntion code itself is missed , so we ask you to give us some example code or provide the fuction at full code.

Tnank you for fast response

HeLiO
Senior User
Posts: 94
Joined: Thu 2011-04-14 12:47

Re: VS1000b, SPI LOAD

Post by HeLiO » Wed 2013-02-20 10:27

Panu wrote:Hi!

Often the 24-bit support just pads the 16-bit address with an extra zero. ("if (24 bit mode) then spiput(0)".) I think that may be the case here.
i cant yet figure out why fucntion declared in vs1000.h (void SpiLoad(register __i2 short startAddr, register __i0 short m24);) have short input address type ??
The reason ( :o ) is that for IC production test reasons, the bootloader must also work in a chip that has a broken RAM. That's why the bootloader is written in assembler, never reads from RAM (only uses registers) and is kept as simple as possible. The address is 16 bits only because that's more than enough for the bootloader. For other uses, you'll need to load functions that can use the higher addresses in the flash. Many of our example files contain such functions.

-Panu
In continuation i want to clear out the information hided in this post:
the bootloader must also work in a chip that has a broken RAM.
What is meaned by that statement , could you please give some comments ?
For other uses, you'll need to load functions that can use the higher addresses in the flash. Many of our example files contain such functions.
What means i need to load functions? Could you please point some on

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

Re: VS1000b, SPI LOAD

Post by Panu » Thu 2013-02-21 11:03

"the bootloader must also work in a chip that has a broken RAM."

What is meaned by that statement , could you please give some comments ?
In IC manufacturing, at the IC factory, at the chip tester, after scanning that the logic of the chip is valid, the SPI boot is used to load a test program into the VS1000b. The loading of this program should behave predictably even in bad chips so that it does not "jam" the chip tester. Later on, the bad chips will be discarded by the tester and thrown away.

"For other uses, you'll need to load functions that can use the higher addresses in the flash. Many of our example files contain such functions."

What means i need to load functions?
Means that you need to load custom functions to the IRAM and run them from the IRAM.
Could you please point some on
For example functions such as these from spiusb.c at http://www.vlsi.fi/en/support/software/ ... tions.html

Code: Select all

// Block Read for SPI EEPROMS with 24-bit address e.g. up to 16MB 
u_int16 EeReadBlock(u_int16 blockn, u_int16 *dptr) {
  SpiWaitStatus();
  
  EePutReadBlockAddress(blockn);
  {
    int n;
    for (n=0; n<256; n++){
      *dptr++ = SpiSendReceive(0);
    }
  }
  SPI_MASTER_8BIT_CSHI;
  return 0;
}
void EePutReadBlockAddress(register u_int16 blockn){
  SPI_MASTER_8BIT_CSLO;
  SpiSendReceive(SPI_EEPROM_COMMAND_READ);
  SpiSendReceive(blockn>>7);            // Address[23:16] = blockn[14:7]
  SpiSendReceive((blockn<<1)&0xff);     // Address[15:8]  = blockn[6:0]0
  SpiSendReceive(0);                    // Address[7:0]   = 00000000
  SPI_MASTER_16BIT_CSLO;
}
We're still working on finding the smallest possible form of this kind of function for VS1000b.

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

User avatar
pasi
VLSI Staff
Posts: 1764
Joined: Thu 2010-07-15 16:04

Re: VS1000b, SPI LOAD

Post by pasi » Thu 2013-02-21 13:24

Here is a completely untested version of the spi boot for 24-bit SPI memory. Hoever, it compiles and I'm fairly certain I made the necessary changes correctly. The prototype for C is:

void SpiLoad24(register __d u_int32 startAddr); //never returns

One note though: any code/data to be loaded should not cross 64kB boundaries, because the next record address is calculated with a 16-bit addition. You can fix this by adding addc d1,null,d1 to the two places. We'll, perhaps I'll add them for you... But you can save 2 words by taking them out.

spiload24.s:

Code: Select all

#ifndef ASM
#define ASM
#endif/*!ASM*/
#include <vs1000.h>

#define SPI_WREN  0x06
#define SPI_WRDI  0x04
#define SPI_RDSR  0x05
#define SPI_WRSR  0x01
#define SPI_READ  0x03
#define SPI_WRITE 0x02


//u_int16 SpiSendReceive(register __a0 u_int16 data);
//void SpiDelay(register __a0 u_int16 wait);

	.import _SpiSendReceive	//A0, uses i7
	.import _SpiDelay


// void SpiLoad24(register __d u_int32 startAddr); //never returns

	.sect code,SpiLoad24
	.export _SpiLoad24
_SpiLoad24:
	call _SpiDelay
	ldc 40/4,a0	// wait 40 cycles = 2.44us

	ldc SPI_CF_MASTER | SPI_CF_DLEN8 | SPI_CF_FSIDLE0,b0
	ldc SPI0_CONFIG,i4
	STP b0,(i4)	/* assert /CS (drop FSYNC) */
	call _SpiSendReceive
	ldc SPI_READ,a0			// Send READ

	call _SpiSendReceive
	add d1,null,a0		// d1 = high 8 bits of 24-bit address

	ldc SPI_CF_MASTER | SPI_CF_DLEN16 | SPI_CF_FSIDLE0,b0
	call _SpiSendReceive
	add d0,null,a0	; STP b0,(i4)	// d0 = low 16 bits of 24-bit address

	ldc SPI_CF_MASTER | SPI_CF_DLEN8 | SPI_CF_FSIDLE0,b0 // 8-bit mode
	call _SpiSendReceive
	and null,null,a0 ; STP b0,(i4)	// Receive byte: type -> c0

	call _SpiReceiveWord2
	add a0,null,c0		//type->c0
	call _SpiReceiveWord2		//addr -> b0
	mv b0,i4		//length -> i4
	// advance to next record d = d + 5
	ldc 5,a0
	add d0,a0,d0
	addc d1,null,d1 // advance to next 64kB if needed

	mv b0,i4 ; mv i4,b0
	// i4=addr, c0=type, b0=length

	ldc 0x00ff,a0	// POj: 20050502
	and c0,a0,c0	// mask upper bits, do not require pull-down on MISO

	// advance to next record d = d + b0
	add d0,b0,d0
	addc d1,null,d1	// advance to next 64kB if needed
	lsr b0,a0	// a0: length in words
	add c0,null,c0
	ldc 0x01,a1
	jzs spii	//0->Imem
	sub a1,c0,a1
	ldc 0x02,a1
	jzs spix	//1->Xmem
	sub a1,c0,a1
	ldc 0x03,a1
	jzs spiy	//2->Ymem
	sub a1,c0,a1
	nop
	jzs spiexec	//3->exec
	nop
	// unknown -> Skip record
end:	ldc SPI_CF_MASTER | SPI_CF_DLEN8 | SPI_CF_FSIDLE1,b0
	ldc SPI0_CONFIG,i4
	j _SpiLoad24
	STP b0,(i4)	/* de-assert /CS (raise FSYNC) */

	.export spiexec
spiexec:
	ldc SPI_CF_MASTER | SPI_CF_DLEN8 | SPI_CF_FSIDLE1,b0
	mv i4,lr0	//address is execute address
	ldc SPI0_CONFIG,i4
	jr
	STP b0,(i4)	/* de-assert /CS (raise FSYNC) */

spix:	add a0,ones,a0	// length in 16-bit words -1
	// addr: i4, len: a0
	loop a0,$0-1
	nop
	call _SpiReceiveWord2
	nop
	stx b0,(i4)+1
$0:
	jmpi end

	.export spiy
spiy:	add a0,ones,a0	// length in 16-bit words -1
	// addr: i4, len: a0
	loop a0,$0-1
	nop
	call _SpiReceiveWord2
	nop
	sty b0,(i4)+1
$0:
	jmpi end

spii:	lsr a0,a0	// length in 32-bit words
	add a0,ones,a0
	loop a0,$0-1
	nop
	call _SpiReceiveWord2
	nop
	call _SpiReceiveWord2
	mv b0,b1
	add b0,null,b1 ; mv b1,b0
	sti b,(i4)+1
	nop	// NOP so that call or jmpi is not the next instruction
$0:
	jmpi end

	.sect code,SpiReceiveWord2
//register __b0 u_int16 SpiReceiveWord2(void);
	.export _SpiReceiveWord2
_SpiReceiveWord2:
	ldx (i6)+1,null
	stx lr0,(i6)+1	; sty a0,(i6)
	call _SpiSendReceive			//receive low -> b0
	and null,null,a0	; sty a1,(i6)
	call _SpiSendReceive
	and null,null,a0 ; mv a0,b0		//receive high -> a0

	ldc 8,a1
	ashl a0,a1,a0	; ldy (i6)-1,a1
	ldx (i6),lr0
	jr
	or a0,b0,b0	; ldy (i6)-1,a0

	.end

Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

HeLiO
Senior User
Posts: 94
Joined: Thu 2011-04-14 12:47

Re: VS1000b, SPI LOAD

Post by HeLiO » Tue 2013-03-12 11:10

Pasi, Panu, thank you a lot for lead and support here on forum nad in this thread particularly.
Your examples made the deal - we managed to "port" our project(s) on a new hardware base (SPI FLASH as bootloader and multi boot storage), and you r help was coming out jus tand time and in the right direction


Tnank you!

User avatar
pasi
VLSI Staff
Posts: 1764
Joined: Thu 2010-07-15 16:04

Re: VS1000b, SPI LOAD

Post by pasi » Wed 2013-03-13 17:52

HeLiO wrote:Your examples made the deal - we managed to "port" our project(s) on a new hardware base
You're welcome. I guess the SpiLoad24() function works then? :D
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

shayanjameel08
User
Posts: 5
Joined: Sat 2013-10-12 10:20

Re: VS1000b, SPI LOAD

Post by shayanjameel08 » Mon 2013-10-14 14:17

you'll need to load functions that can use the higher addresses in the flash

Post Reply