#Write on QuadSPI memory with SAM-BA

<abstract>
Microchip SAM-BA is a software that provides an open set of tools 
for in-system programming of internal and external memories connected 
to Microchip 32-MCUs and MPUs. This article illustrates how to use it to transfer the at91bootstrap 
bootloader on the QuadSPI memory mounted on the RoadRunner SOM 
</abstract>

In this article is used the command line version of SAM-BA version 3.3.1
that support the latest generations of Microchip MPUs.

The official version of SAM-BA is compatible with the QuadSPI memory used on the RoadRunner module
up to the 16MB size (ROADRUNNER-Q16). To manage the higher memory size models follow this article:

* @article='SAM-BA_applet_build'

## Installing SAM-BA 

Download the package from Microchip site:

	mkdir roadrunner
	wget http://ww1.microchip.com/downloads/en/DeviceDoc/sam-ba_3.3.1-linux_x86_64.tar.gz

Uncompress the tar.gz file:

	tar xvf sam-ba_3.3.1-linux_x86_64.tar.gz

Move inside the new directory created by tar

	cd sam-ba_3.3.1

## Using SAM-BA

SAM-BA comunicates with MCU via the USB client port of Roadrunner. It can be used only when 
on the MPU is running RomBOOT. When the CPU is running Linux
it is impossible to use SAM-BA to access the QuadSPI memory.

__RomBOOT__ is the first piece of code that runs on the SAMA5D27 MCU at startup. 
It is burned directly by the Microchip factory inside the ROM MPU. 

At startup RomBOOT looks for a bootable code from any possible supported external memory, 
if nothing is available, it waits for any 
serial commands incoming from the USB device port or from the serial debug port. This 
is the way used by SAM-BA to talk with RomBOOT.

If one the QuadSPI memory already contains boot code, it is possible to avoid 
to boot from it and remain on RomBOOT code closing the BOOT jumper on Berta board 
before the MPU reset.

The RoadRunner with QuadSPI on board (Model Q16/Q64/Q128) are already programmed
to boot from QuadSPI. The default code put on it is [at91bootstrap](/at91bootstrap).

In case you want to reflash it just press the push-button **BOOTOFF** on the 
[Berta D2 board](/roadrunner_devkit) and then press and release after one second the **RESET** button to restart the MPU.
Then release the  **BOOTOFF** pushbutton.

In this situation the RoadRunner MPU is inhibited to boot from the QuadSPI, it remains in RomBoot mode and 
a new USB device is announced on the USB port of your PC:

Be sure to have the line PA30/CD disconnected from ground in order to be able to enter in sam-ba mode. 


	lsusb
	...
	Bus 002 Device 004: ID <b>03eb:6124 Atmel Corp. at91sam SAMBA bootloader</b>
	...

and a new serial device is available with the name __/dev/ttyACM0__:

	dmesg
	...
	[ 4676.045662] cdc_acm 2-2.1:1.0: ttyACM0: USB ACM device
	[ 4676.046800] usbcore: registered new interface driver cdc_acm
	[ 4676.046803] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
	...

	ls -al /dev/ttyACM0
	crw-rw---- 1 root dialout 166, 0 Aug  2 12:53 /dev/ttyACM0

## Examples to use SAM-BA from command line 

### Erase the whole QuadSPI

	sudo ./sam-ba -p usb -b sama5d2-xplained -a qspiflash -c erase

### Write the bootloader

	sudo ./sam-ba -p usb -b sama5d2-xplained -a qspiflash -c writeboot:at91bootstrap.bin

### Write to memory from a file

    -c write:<filename>:[<addr>]

__Examples__: write and verify at91bootstrap.bin at begin of QuadSPI

    sudo ./sam-ba -p usb -b sama5d2-xplained -a qspiflash -c write:at91bootstrap.bin   
    sudo ./sam-ba -p usb -b sama5d2-xplained -a qspiflash -c verify:at91bootstrap.bin

### Read memory to file

    -c read:<filename>:[<addr>]:[<length>]

examples:

	-c read:firmware.bin              read all to firmware.bin
	-c read:firmware.bin:0x1000       read from 0x1000 to end into firmware.bin
	-c read:firmware.bin:0x1000:1024  read 1024 bytes from 0x1000 into firmware.bin
	-c read:firmware.bin::1024        read 1024 bytes from start of memory into firmware.bin

### Verify memory from a file

	-c verify:<filename>:[<addr>]

examples:

	verify:firmware.bin         verify that start of memory matches firmware.bin
	verify:firmware.bin:0x1000  verify that memory at offset 0x1000 matches firmware.bin

To generate different size sample files use these examples:

	dd bs=1K count=64  < /dev/urandom > test64KB.bin
	dd bs=1M count=16  < /dev/urandom > test16MB.bin
	dd bs=1M count=64  < /dev/urandom > test64MB.bin
	dd bs=1M count=128 < /dev/urandom > test128MB.bin

## Using SAM-BA with QML script files 

SAM-BA can execute scripts written in QML to do automaticaly complex functions.

With the following QML script for example it is possible to write and verify at91bootloader 
on the QuasSPI.

	import SAMBA 3.2
	import SAMBA.Connection.Serial 3.2
	import SAMBA.Device.SAMA5D2 3.2

	SerialConnection {
		port: "ttyACM0"
		baudRate: 115200
	
		device: SAMA5D2 {
		}
	
		// read and display current BSCR/BUREG/FUSE values
		function printBootConfig() {
			var bscr = applet.readBootCfg(BootCfg.BSCR)
			print("BSCR=" + Utils.hex(bscr, 8) + " / " + BSCR.toText(bscr))
			var bureg0 = applet.readBootCfg(BootCfg.BUREG0)
			print("BUREG0=" + Utils.hex(bureg0, 8) + " / " + BCW.toText(bureg0))
			var bureg1 = applet.readBootCfg(BootCfg.BUREG1)
			print("BUREG1=" + Utils.hex(bureg1, 8) + " / " + BCW.toText(bureg1))
			var bureg2 = applet.readBootCfg(BootCfg.BUREG2)
			print("BUREG2=" + Utils.hex(bureg2, 8) + " / " + BCW.toText(bureg2))
			var bureg3 = applet.readBootCfg(BootCfg.BUREG3)
			print("BUREG3=" + Utils.hex(bureg3, 8) + " / " + BCW.toText(bureg3))
			var fuse = applet.readBootCfg(BootCfg.FUSE)
			print("FUSE=" + Utils.hex(fuse, 8) + " / " + BCW.toText(fuse))
		}
	
	
		onConnectionOpened: {
			// initialize QSPI applet
			initializeApplet("qspiflash")
	
			// erase all memory
			applet.erase(0, applet.memorySize)
	
			// write files
			applet.write(0x00000, "at91bootstrap.bin", true)
	
			// verify files
			applet.verify(0x00000, "at91bootstrap.bin", true)
	
			// initialize boot config applet
			initializeApplet("bootconfig")
	
			// Use BUREG0 as boot configuration word
			applet.writeBootCfg(BootCfg.BSCR, BSCR.fromText("VALID,BUREG0"))
	
			// Write flags in RAM
			applet.writeBootCfg(BootCfg.BUREG0, BCW.fromText("EXT_MEM_BOOT,QSPI0_IOSET3"))
	
			// Write flags on FUSES
			//applet.writeBootCfg(BootCfg.FUSE, BCW.fromText("EXT_MEM_BOOT,QSPI0_IOSET3"))
	
			printBootConfig();	             
		}
	}	

save it in a file called for example mytest.qml then lauch it by typing:

	sudo ./sam-ba -x mytest.qml

More info about SAM-BA is availabe in __doc/index.html__ to read it type inside the SAM-BA directory:

	cd doc
	python -m SimpleHTTPServer 8000	

then access to this url <http://localhost:8000> from your web browser.

## Time required for QuadSPI operation

| Memory size in MB | Write all (mm:ss) | Verify all (mm:ss) |
|-------------------|-----------|------------|
|        16 |      2:12 |       2:25 |
|        64 |      8:50 |       0:11 |
|       128 |     17:38 |       0:19 |

## Links

* [Microchip Developer Help - SAM-BA In-System Programmer](https://microchipdeveloper.com/32mpu:sam-ba-intro)
* @article='SAM-BA_applet_build'
* [Limit in 16MiB for QSPI Flash n25q512ax3](https://github.com/atmelcorp/atmel-software-package/issues/64)

@include='adv_roadrunner'

