LPC2148 USB Bootloader Tutorial – Bootloader does not work

LPC2148 USB Bootloader Tutorial – Bootloader does not work

http://www.sparkfun.com/commerce/tutori … ials_id=94

I’m trying to get the bootloader working on an OLIMEX LPC-P2148 development board.

I’ve got it running as a USB drive (I wired SPI0 signals to the SD card viewtopic.php?t=12032 )

The bootloader tries to open the root directory and gets stuck in an infinite loop.

Does anyone have a complied hex file I could use to see if it is a problem with my compilation?

I’m Using Eclipse SDK with CYGWIN/GNUARM C++/C compiler

I get the following ERRORS when compiling (but USB drive works)

Severity Description Resource In Folder Location Creation Time

2

/cygdrive/ blah-blah / arm-elf/bin/ld lpc2138.cmd

40: warning: memory region test not declared

SFEUSBBoot line 0 September 17, 2008 8:03:49 PM

2 Assembling * crt.S SFEUSBBoot line 0 September 17, 2008 8:03:49 PM

Severity Description Resource In Folder Location Creation Time

1 comparison is always true due to limited range of data type fat16.c SFEUSBBoot/System line 711 September 17, 2008 8:03:49 PM

1 comparison is always true due to limited range of data type fat16.c SFEUSBBoot/System line 849 September 17, 2008 8:03:49 PM

1 declaration of ‘reset’ shadows a global declaration rootdir.h SFEUSBBoot/System line 20 September 17, 2008 8:03:49 PM

1 implicit declaration of function ‘delay_ms’ rprintf.c SFEUSBBoot/System line 87 September 17, 2008 8:03:49 PM

1 in inclusion SYSTEM/rootdir.h:20 main.c SFEUSBBoot line 19 September 17, 2008 8:03:49 PM

1 memory region test not declared lpc2138.cmd SFEUSBBoot line 40 September 17, 2008 8:03:49 PM

1 nested extern declaration of ‘delay_ms’ rprintf.c SFEUSBBoot/System line 87 September 17, 2008 8:03:49 PM

1 shadowed declaration is here system.h SFEUSBBoot line 23 September 17, 2008 8:03:49 PM

If you read the tutorial, you’ll see that the code for the bootloader was written and compiled using WinARM. I’ve never used the Eclipse SDK, but apparently the libraries and memory definitions are different.

The bootloader does work, it’s used on about 5 different products at Sparkfun, and I’ve used it in my own projects. If I were you, I’d start at the beginning of the tutorial, follow all of the instructions, and make sure the hardware is set up properly. Most importanly, for the hardware, make sure the the chip select line for the SD card is connected to P0.7.

I’d say it’s cross platform issue though. You’ll need to compile the code in WinARM. I saw in another thread that when you plug a USB cable in a drive opens and you can transfer files. The USB mass storage code runs the same fat16 code as the bootloader, so it’s definately not a code problem or the drive wouldn’t open up in the first place.

I downloaded the uberboard main.hex bootloader and it worked fine (I’d rewired the SD card to match the tutorial).

When investigating the crt.s error I realized the make files were using WinARM flags and maybe even calling WinARM which I had installed a few years ago prior to Eclipse/CYGWIN/GNUARM.

There’s probably an incompatibility between Eclipse and WinARM

I’m going to convert the make files to use CYGWIN/GNUARM and hope it works. If not, I try using WinARM for any boot loader mods.

Well I discovered a couple of things which put me back to my first post.

USB Drive works great, but it does not call routines like open root or open partition which seems to be where the boot loader fails.

The uberboard main.hex did not work. I’m using the LPC flash utility and it seems it doesn’t always upload the file, even though it says it does.

I have to erase flash before uploading the hex file to get it to always work properly.

I followed the tutorial and used WinARM to compile the source and I get the same errors as before.

I added some rprintf statements in the code to see where the problem is.

The boot loader gets stuck in the partition.c and never returns from the partition assignment in the if statement.

Any ideas would be greatly appreciated!


ROOTDIR.C:


int openroot(void)
{
    /* open first partition */
    partition = partition_open((device_read_t) sd_raw_read,
                               (device_read_interval_t) sd_raw_read_interval,
                               (device_write_t) sd_raw_write,
                               0);

    if(!partition)
    {
        /* If the partition did not open, assume the storage device
             *      * is a "superfloppy", i.e. has no MBR.
             *           */
        partition = partition_open((device_read_t) sd_raw_read,
                                   (device_read_interval_t) sd_raw_read_interval,
                                   (device_write_t) sd_raw_write,
                                   -1);
        if(!partition)
        {
            rprintf("opening partition failed\n\r");
            return 1;
        }
    }
    ....

PARTITION.C:


struct partition_struct* partition_open(device_read_t device_read, device_read_interval_t device_read_interval, device_write_t device_write, int8_t index0)
{
    struct partition_struct* new_partition = 0;
    uint8_t buffer[0x10];

    if(!device_read || !device_read_interval || index0 >= 4)
        return 0;

    if(index0 >= 0)
    {
        /* read specified partition table index */
        if(!device_read(0x01be + index0 * 0x10, buffer, sizeof(buffer)))
            return 0;

        /* abort on empty partition entry */
        if(buffer[4] == 0x00)
            return 0;
    }

    /* allocate partition descriptor */
    new_partition = malloc(sizeof(*new_partition));
    if(!new_partition)
        return 0;
    memset(new_partition, 0, sizeof(*new_partition));

    /* fill partition descriptor */
    new_partition->device_read = device_read;
    new_partition->device_read_interval = device_read_interval;
    new_partition->device_write = device_write;

    if(index0 >= 0)
    {
        new_partition->type = buffer[4];
        new_partition->offset = ((uint32_t) buffer[8]) |
                                ((uint32_t) buffer[9] << 8) |
                                ((uint32_t) buffer[10] << 16) |
                                ((uint32_t) buffer[11] << 24);
        new_partition->length = ((uint32_t) buffer[12]) |
                                ((uint32_t) buffer[13] << 8) |
                                ((uint32_t) buffer[14] << 16) |
                                ((uint32_t) buffer[15] << 24);
    }
    else
    {
        new_partition->type = 0xff;
    }

    return new_partition;
}

The USB Drive uses the SPIInit() function in lpc2000_spi.c

The Boot loader uses the sd_raw_init() function in sd_raw.c

The SPI speed registers are set to different values in these routines. When I get some more time I’ll see the differences matter.

I checked the SSP registers. They have same value in sd_raw_init and spi_init. i put some print statements and found that the call device_read(index, buffer, sizeof(buffer)) gives a problem. code hangs over the call.

I’ve had no success getting this to work.