Flashing a sketch from SD card using 2boot bootloader

Sure, it is FAT16, <2GB

Hi,
Martin thanks for starting this topic and pointing out 2boots!
I have also been having difficulty getting it to work. My platform has a different chip select, so I added the appropriate targets. The serial part of the bootloader works fine, but it never loads anything from SD. I've tried both 1GB and 2GB cards, formatting from Windows 7 explorer, Storage Manager, and on Linux using mkdosfs -F16, and the SD association's official formatter.

I dug in a little (I had to comment out the stk500v1 code to have room for debugging, I suppose I could have changed the linker arguments...)
and it's failing in this format test:

	mmc_start_read_block(mbr->sector.partition[0].sectorOffset);
	  
		if ((vbr->bsFileSysType[0] != 'F') || (vbr->bsFileSysType[4] != '6')){
		   return 2; // No FAT16 found
		}

The actual bytes in both those fields are zero.
Seems like it's sensitive to format, and that could be improved. After browsing the wikipedia article on the FAT "standard" I can see how that might be challenging!
Can anyone recommend a format utility or method (such as a dd-able image) that I can at least try this?

Here's a little more info on my card (as currently formatted, I tried a canon powershot this time.)
(parted) print
Model: SD SU01G (sd/mmc)
Disk /dev/mmcblk0: 988MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number Start End Size Type File system Flags
1 69.1kB 988MB 988MB primary fat16

I am playing with http://www.partitionwizard.com/ and trying to ensure the conditions you mention below are met; It allows me to set the file system type to 6, I am not sure about the 'F' , probably it is "F"AT ?

Can you try to re-compile the code with that section commented out?

mmc_start_read_block(mbr->sector.partition[0].sectorOffset);
	  
		if ((vbr->bsFileSysType[0] != 'F') || (vbr->bsFileSysType[4] != '6')){
		   return 2; // No FAT16 found <<<<<<<<<<<<<< REMOVE TO TEST
		}

From what I see here:

uint8_t bsFileSysType[8]; // 54-61 Filesystem type (E.g. "FAT12 ", "FAT16 ", "FAT ", or all zero.)

obviously that line is looking for a string 'FAT16' (positions 0 and 4 must be 'F' and '6' respectively) and not finding it, probably something that today's format tools omit?? strange indeed.

I did try removing it, and it failed somewhere further downstream. I'll have to poke some more
Here's a hex dump of the beginning of my card (formatted by a camera) The string is there, but probably in a different place...

00000000 eb 3e 90 50 77 72 53 68 6f 74 20 00 02 20 01 00 |.>.PwrShot .. ..|
00000010 02 00 02 00 00 f8 ec 00 3f 00 20 00 87 00 00 00 |........?. .....|
00000020 79 73 1d 00 80 00 29 ca 21 c5 50 43 41 4e 4f 4e |ys....).!.PCANON|
00000030 5f 44 43 20 20 20 46 41 54 31 36 20 20 20 33 ff |DC FAT16 3.|
00000040 8e df be 00 7c 8d 9c e4 01 8e 47 02 fc b9 00 02 |....|.....G.....|
00000050 f3 a4 c7 07 58 00 ff 2f 8c c8 fa 8e d0 bc 00 06 |....X../........|
00000060 fb 8b ec 83 ec 16 c5 36 78 00 89 76 f6 8c 5e f8 |.......6x..v..^.|
00000070 8d 7e ea b9 0b 00 57 f3 a4 5f 8e d9 be 78 00 89 |.~....W..
...x..|

BTW there is a sketch that formats the SD card, but didn't work form me.. no idea why

http://code.google.com/p/arisgames/source/browse/trunk/arduino/MP3_Player_Example/sdfatlib20110702/SdFat/examples/SdFormatter/SdFormatter.pde?spec=svn2144&r=2144

Thanks for that Martin,
I got the SDformatter to work, but no change in results from 2boots.
the SDfat library hasn't been converted to 1.0 yet, so I used Arduino-022
make sure you change:
const uint8_t chipSelect = SS_PIN;
to whatever your chip select is.
I also remembered that one of the current SD examples says that you have to set the SS pin to output even if you aren't using it:
pinMode(10,OUTPUT);

I'll try to walk through the 2boots fat code tonight... (I should really get back to work!)

I am checking the revision history of mmc_fat.c

and this one may be a tip:

The description reads "wait longer for cards to answer. Might solve problems at 16mhz."

Maybe the bootloader was originally designed for a 8Mhz speed and timing issues could be the root of the problem.

I've messed around with delays, but haven't gotten one that works. The MMC card isn't replying properly, so the routine to read the boot sector returns all zeros. I have pulled all the mmc_fat code out into a sketch so I can do prints, etc.

My next step (though I haven't had much time) is to try to adapt the code from the SD library.

I tried it on an 8mhz arduino pro (sparkfun) and it still fails. I confirmed the sd library (and sdfat) work fine.

As this has obviously stalled,

here is another similar project using Petit-FatFs, theck out the sample project download link on the bottom of the page, inside there is a "AVR BOOT" example.

I don't have the experience to deal with bootloader modifications yet, but that one seems pretty straighforward and only requires adjustment of the makefile to work on atmega328

Disadvantages are that it is a 4K bootloader and lacks the option to upload a sketch over the FTDI, but hey: I can live with that.

Thanks Martin,
That works.
You need to also change asmfunc.s for the SPI pin assignment. Here are the settings I used for the sparkfun micro-sd card:
#define DDR_CS _SFR_IO_ADDR(DDRB), 0 // MMC CS pin (DDR, PORT)
#define PORT_CS _SFR_IO_ADDR(PORTB), 0

#define DDR_CK _SFR_IO_ADDR(DDRB), 5 // MMC SCLK pin (DDR, PORT)
#define PORT_CK _SFR_IO_ADDR(PORTB), 5

#define DDR_DI _SFR_IO_ADDR(DDRB), 3 // MMC DI pin (DDR, PORT)
#define PORT_DI _SFR_IO_ADDR(PORTB), 3

#define PIN_DO _SFR_IO_ADDR(PINB), 4 // MMC DO pin (PIN, PORT)
#define PORT_DO _SFR_IO_ADDR(PORTB), 4

The CS pin is the one that changes with different shields.

also, to convert the sketch output to binary:
avr-objcopy -I elf32-avr -O binary BlinkWithoutDelay.cpp.elf app.bin
(note, originally this post had a typo with hex instead of elf...)

Also, you need to change the boot fuses to accomodate the 4k bootloader:

-U lfuse:w:0xff:m -U hfuse:w:0xd8:m -U efuse:w:0xfd:m

martin_bg:
As this has obviously stalled,

here is another similar project using Petit-FatFs, theck out the sample project download link on the bottom of the page, inside there is a "AVR BOOT" example.

Petit FAT File System Module

I se the link to the FAT module, but where is the bootloader?

inside this archive:

http://elm-chan.org/fsw/ff/pfsample.zip

look in the AVR_BOOT folder

hi everyone!,

just a few days ago I also tried to use 2boots bootloader without success... This forum has been very helpfull to me in order to know that the problem is not only mine! I also tried to format the micro SD from Linux with gParted and fdisk. With os x with disk utility and sdFormatter (and app from the micro SD website). For windows I tried with the normal format app and the "format" terminal order. Each time i made a hexdump and I found that depending on SIZE and OS, the headder is different every time (always respecting the FAT16 (0x06) format.

So, I give up, Im trying to move to petitFat as you recomend but, I really dont know wich value I have to put in the BOOT_ADR field. Im using an Atmega328p, do you happen to know wich config params I have to use?

Thanks!!!

I haven't had time to write it up yet, but I can send you a zip with the code. What Chip select are you using for the SD card?

Im using pin number 4 (ethernet shield for arduino) which is PD4 on the Atmega328p.
If you have the code, please send me it to: *********************** <-edited for privacy

THANKS!

osbock sent me a compiled hex for arduino ethernet (CS is digital 4) but it didn't work for me, here is the HEX so you give it a try as well.

http://dl.dropbox.com/u/18771283/ArduinoEthernetSD.hex

Don't forget that the sketch to be uploaded has to be in .BIN not .HEX and that this is a 4K bootloader so you need to change fuses accordingly.

Here are the avrdude commands that worked for me. Unfortunately I don't have an arduino ethernet to test:

avrdude -c usbtiny -p m328p -e -u -U lock:w:0x3f:m -U efuse:w:0x05:m -U hfuse:w:0xD8:m -U lfuse:w:0xFF:m
avrdude -c usbtiny -p m328p -U flash:w:ArduinoEthernetSD.hex -U lock:w:0x0f:m

of course change the -c option if you have a different programmer (and add baud and other things if you need em.)