error in bootloader code for mega328.

Go To Last Post
82 posts / 0 new

Pages

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No I didn't use the ASP set up and my device is already manufactured so changes are out.  My device is based from this. 

I use a 12 mhz instead but that usb set up is the same. From what I know about usbASP is that its pretty much the same thing (This boot loader is similar to Thomas Fischl's avrusbboot, except that it is built on top of the HID device ) but I never worked with it. I think some changes may be needed to make your gui work but that really is nice. I plan to write my own firmware uploader so source code would be invaluable to me. Though again, not sure how USBASP does its bootloader, may be very different. I could not get that 4share to work kept bugging my about fackbook or something?

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S_K_U_N_X wrote:
not sure how USBASP does its bootloader

Does it have a bootloader then? I doubt that. It is is simply an ISP "data pipe". On the PC facing side it looks like a USB device (software simulated) and on the target AVR facing side it is an ISP programmer.

 

Your device appears to be "stand alone". The bootloader is there so it can program itself, not other AVR so it's nothing like a USBAsp is it (apart from the fact that both happen to use software simulated USB).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then what is the avrusbboot for? a non avr studio application? anyone can download avr studio and program via isp. Seems like an over kill to me? Also he said he wrote a boatloader. ISP software would write the entire chip right? 

Last Edited: Fri. May 5, 2017 - 03:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fischl is a very clever bloke. He recognized how useful Objective Development software implementation of USB was.

 

One project he used it for was USBasp. That (as I say above) uses the USB to interface to a PC then it uses the data channel to deliver data that is immediately programmed on the other side into a second AVR using ISP

 

A completely separate use for the software-USB he made was to make a standalone program that you can put into the top of an AVR so that it can not only program itself but it can receive the data to achieve that over USB - that project is called avrusbboot.

 

In fact when you look at:

 

http://www.fischl.de/projects/

 

You see USBAsp and avrusbboot listed as just two of quite a number of projects he has done. In the list there are several using soft-USB. I guess once you have use a great library like that you want to use it in as many different ways as you can think of!

 

USBasp is arguably the most important 3rd party piece of AVR development electronics/software there is (apart from Arduino). Via ebay I imagine the Chinese have now sold millions and millions of USBAsp to people all over the world who are now able to program their AVR projects with a $2 piece of electronics and a free copy of avrdude.exe. The cheapest offering from Atmel to "get started" has always been around the $50 mark. Sure that $50 thing may give you the luxury of being able to drive it from within Studio but loads of folks are happy to run avrdude separately or, as you can these days, set it up as a "tool" inside Studio so when you execute it, it just feels like it's working "inside" Studio anwyay.

Last Edited: Fri. May 5, 2017 - 04:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow, I  had no idea, very insightful. So no,  this will not work for me as I do plan to use a stand alone HID based bootloader.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My refer to USBASP is for the schematics only, not the USBASP itself, many of them have use it, so it's easier to start with, without making new hardware.

The point is, it can download the full application firmware size minus 2K bootloader, I believe that's what you're looking for.

 

 

S_K_U_N_X wrote:
Though again, not sure how USBASP does its bootloader, may be very different.

 

Of course it's very different, it's bootloader not ISP programmer.

So USBASP cannot be bootloader except you flash it with bootloader firmware. Then re-program the USBASP firmware in it using bootloader. And you got 2 USB device in a single device.

But that's is useless thing to do with bootloader.

 

I'm not sure using HID, the bootloader needs how much flash size.

There's BootloaderHID from Christian's with simple GUI. I'm not sure what's your problem with that.

I'm curious to find out making my own HID bootloader using your schematics enlightened

 

S_K_U_N_X wrote:
I could not get that 4share to work kept bugging my about fackbook or something?

 

Not sure with that, any suggestion for other site?

 

 

 

 

 

 

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Of course it's very different, it's bootloader not ISP programmer.\

I was never talking about ISP. I said "Though again, not sure how USBASP does its bootloader, may be very different." - meaning different from usbboothid.

 

I'm not sure what's your problem with that.

This is the entire point to my topic, the issue is that my bootloaders "seems" to be assuming I have a 4k boot. I have a 2k boot. No need to explain that you can read thru all the posts. I didn't really follow much of what you said here but more on point your last comment is what drives my curiosity.

I'm curious to find out making my own HID bootloader using your schematics 

This is also what I'm curios about. At home here I was able to get your download. I selected my chip and put in the vid/pid but it was not detected.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm sorry, I forgot to include the inf files for windows driver in the zip file, my bad.

I'll fix it as soon as when I get home.

I'm still working on the HID bootloader with your schematics, it still in progress.
Hope it will finish in few days.

But I had to add a boot switch in your schematics to make the device selectable.
And few leds to show the transaction progress.

Cheers

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is the new zip

https://www.4shared.com/zip/u7Dxr5Joei/AVRboot.html

 

Good luck

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, thx for the interest to help me. So this latest zip with the ini. I'm not sure I'm using it right since there is no find button. I put my device in bootloader mode and I put in the vip/pid but it always says no device found. When the right id is put it does it just say found? Or do I have to hit enter or something?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is the device manager looks like 

 

 

 

And the apps after device detected by windows

 

 

No need to change VID / PID, it detected automatically and ready to use.

I've been using it for years now and had no problem.

 

To enter the bootloader mode you have to connect jumper PINC3 to ground then plug in the device. (USBASP speed select)

No need to take off the jumper, if you done with bootloader, unplug the device and remove the jumper.

The device will execute application section when it's powered.

 

Do not use external supply, use together with USB supply instead, so when you plug / unplug the device it will on/off accordingly.

 

Good luck

 

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi ok I'm following what you are saying a bit better now. At this time I don't wish to try USBbootAVR. I want to stay focused on the bootloader I have and getting this source to compile. If you ever finish what you said here.

 

I'm still working on the HID bootloader with your schematics, it still in progress.
Hope it will finish in few days.

I'd be very interested to try it.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is the app

 

 

The schematic still using USBASP schematic because I don't want to make the new one.

The purpose of making this is my curiosity making HID device using VUSB.

It's my first try, so I need you to try it to help me find my mistake in it. I hope you don't mind.

Please don't ask for the source code, like another VUSB projects I had shared, I only intended to help people who interested in VUSB, not to do their job.

 

Good luck

 

 

Here is the zip file

https://www.4shared.com/zip/Qo9ZBIeHca/USBHIDBootAVR.html

I don't know why I'm still doing this hobby

Last Edited: Mon. May 8, 2017 - 12:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is too bad about source, I'd like to use that idea in my code. Would you consider helping me with my code at a later point? I'm not home right now but happy to test later.

Last Edited: Mon. May 8, 2017 - 12:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok so the hid app, there are two issues.
 

1) no 328 option any longer

2) no way to specify the pid.vid.

 

I tried anyways no luck.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

The bootloader hex is for mega 8 (USBASP schematic), you cannot just program it to mega 328, very different size and setting.

And I don't have mega 328 at the moment.

 

As I said it's my first HID app so I haven't completed the device list and changeable VID/PID yet.

I haven't test it for some other chips either.

Still long way to go. I must buy all the chips and make the board to test. I can only do it when I got spare time and budget.

It's only to test the implementing of VUSB for HID bootloader device, not a real product. 

 

I had provided you two working example above.

It's up to you either you want to try it or not.

 

May the Force be with you angel

 

 

 

 

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I dont have any mega8 projects or v-usb code around at the moment. Thx for the candor though.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know the topic went a bit off here but I'm back on topic. Hope I still have a few watchers out there?

 

So I have the source compiled and now I see there is some type of issue here. At first look the error thrown is

 fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err));  - err says communication error...

but it should be

fprintf(stderr, "Data (%d bytes) exceeds remaining flash size!\n", endAddr);

or at least that makes more sense to me. But really I should not have any errors....

 

 

The endaddr is 28800 minus the bootloader size that's  26752 (6880)hex.

 

so I'm guessing the size is not the issue here... Looking closer at the error.

when  startAddr = 0x07000 and  startAddr + (int)sizeof(buffer.data.data) = 0x7080 It throws the comm error.

so I added a print above the error

[buffer.bytes]         [sizeof(buffer.data)]

2553172 ..................... 132

 

if usbSetReport is trowing this error I think the issue is in the bootloader hid code, no? If so my guess would be the usbFunctionWrite section because the set up is done.

 

setup looks like this

uchar   usbFunctionSetup(uchar data[8])
{
usbRequest_t    *rq = (void *)data;
static uchar    replyBuffer[7] = {
        1,                              /* report ID */
        SPM_PAGESIZE & 0xff,
        SPM_PAGESIZE >> 8,
        ((long)FLASHEND + 1) & 0xff,
        (((long)FLASHEND + 1) >> 8) & 0xff,
        (((long)FLASHEND + 1) >> 16) & 0xff,
        (((long)FLASHEND + 1) >> 24) & 0xff
    };

    if(rq->bRequest == USBRQ_HID_SET_REPORT){
        if(rq->wValue.bytes[0] == 2){
            offset = 0;
            return USB_NO_MSG;
        }
#if BOOTLOADER_CAN_EXIT
        else{
            exitMainloop = 1;
        }
#endif
    }else if(rq->bRequest == USBRQ_HID_GET_REPORT){
        usbMsgPtr = replyBuffer;
        return 7;
    }
    return 0;
}

 

while it sends data it will use the write function.

 

 


uchar usbFunctionWrite(uchar *data, uchar len)
{
union {
    addr_t  l;
    uint    s[sizeof(addr_t)/2];
    uchar   c[sizeof(addr_t)];
}       address;
uchar   isLast;

    address.l = currentAddress;
    if(offset == 0){
        DBG1(0x30, data, 3);
        address.c[0] = data[1];
        address.c[1] = data[2];
#if (FLASHEND) > 0xffff /* we need long addressing */
        address.c[2] = data[3];
        address.c[3] = 0;
#endif
        data += 4;
        len -= 4;
    }
    DBG1(0x31, (void *)&currentAddress, 4);
    offset += len;
    isLast = offset & 0x80; /* != 0 if last block received */
    do{
        addr_t prevAddr;
#if SPM_PAGESIZE > 256
        uint pageAddr;
#else
        uchar pageAddr;
#endif
        DBG1(0x32, 0, 0);
        pageAddr = address.s[0] & (SPM_PAGESIZE - 1);
        if(pageAddr == 0){              /* if page start: erase */
            DBG1(0x33, 0, 0);
#ifndef TEST_MODE
            cli();
            boot_page_erase(address.l); /* erase page */
            sei();
            boot_spm_busy_wait();       /* wait until page is erased */
#endif
        }
        cli();
        boot_page_fill(address.l, *(short *)data);
        sei();
        prevAddr = address.l;
        address.l += 2;
        data += 2;
        /* write page when we cross page boundary */
        pageAddr = address.s[0] & (SPM_PAGESIZE - 1);
        if(pageAddr == 0){
            DBG1(0x34, 0, 0);
#ifndef TEST_MODE
            cli();
            boot_page_write(prevAddr);
            sei();
            boot_spm_busy_wait();
#endif
        }
        len -= 2;
    }while(len);
    currentAddress = address.l;
    DBG1(0x35, (void *)&currentAddress, 4);
    return isLast;
}

nothing stands out? Only a guess here but maybe the usb descriptor is expecting a smaller size chip? Though I do see this comment about timers. /* compatibility with ATMega88 and other new devices: */ So I have to assume the author expects 328's here.

 

Also I see a few cli's in the bootload code, I wonder if its taking too long and dropping? - doubtful.

 

interestingly changing  to  if(endAddr > deviceSize - 1024) didnt change a thing, so I'm sure this it not a size issue. Really confused at this point.

 

Two more additional points of interest.  I tried adding a loop to slow it down and it still failed at the same point. Also if I interrupt the usb transfer I can the same error. The failing at the same point every time is what makes thing confusing. Though this is a clue to what is causing the issue and should be easier to track down and fix as its religiously repeatable. 

 

 

 

 

 

 

 

Last Edited: Thu. May 11, 2017 - 01:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After doing some research of HIDBoot with 328p (thanks to my curiosity) , here's what I found:

 

First, I'm not really sure what's going on so I hope someone can explained to me.

 

Erasing page before writing task...

With page erase function:

boot_page_erase(address.l);

will stuck at address.l = 0x7000 which give error report.

0x7000 is the address of bootloader size 4K.

It's related or not I don't know.

 

When I use this

boot_page_erase((address.l >> 8) || address.l);

It's working until the last page of 328p which is 0x7780, no error thrown.

My guess is the matter of casting?

 

 

Now we are talking about writing the flash...

     do{
        ... 
         
        cli();
        boot_page_fill(address.l, *(short *)data);
        sei();
        prevAddr = address.l; <-- here is the problem!
        address.l += 2;       
        data += 2;

        ...
        
        if(pageAddr == 0){
        cli();
        boot_page_write(prevAddr); <-- use in here
        sei();      
       
        ...
        
       }while(len);

                 

With above prevAddr setup,  "boot_page_write(prevAddr)"  will always write to the next page of  "boot_page_erase(address.l)".

So erase page 1 but writing at page 2, that's ridicuolus is it?.

Then I moved prevAddr setup right after "boot_page_erase(address.l)".

Now everything goes smoothly.

 

 

Here I tried to write 0x81 at entire last page of 328p which at 0x7780 with above setup, and it succeeded. No complain thrown.

 

 

Hope someone correct me if I done something wrong.

 

Good luck.

 

 

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, I feel like the most stupid people in the world because ignoring datasheet sad

 

 

Ignore my above post about erase and writing at 0x7000 and above it. It was not suppose to happen!

 

As the datasheet clearly written:

 

 

 

The max rww is 224 pages, which mean 224 * 128 = 28672 bytes !!! Case closed !

 

So better use 4K bootloader than 2K, same result anyway smiley

 

After 70 post frown

 

 

BTW, the "prevAddr setup" is still a good progress. Ignoring that will sometimes cause getting garbage data if the application size is changed less than previous size.

And as datasheet said: erase and write at the same page!

 

 

May the Force be with you enlightened

Cheers

 

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But you are wrong. SPM can write to ALL the pages in the device. It's just a question of whether the page data remains readable during the operation. In the first 28K it does not (while sector writes are happening the page reads back as 0xFFs) but in the top section the code remains visible even while the write occurs.

 

In fact most bootloaders have an address check to ensure that there is not a rogue record in the data or that it is too long so that it might inadvertently write over the bootloader itself.

 

In fact in the preceding 70 posts the question has been whether the limit being used in such a check has used the wrong boundary.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
In fact in the preceding 70 posts the question has been whether the limit being used in such a check has used the wrong boundary.

Then I must be misinterpret the question. My bad english.

 

clawson wrote:
SPM can write to ALL the pages in the device.

I'm aware of that. But looking at the datasheet I asume the last 32 pages is not suppose to touch because it is bootloader boundary.

And yet I am wrong. Bootloader can also being updated using SPM.

Have to dig deeper then.

 

 

Thank you mr Clawson.

 

And forgive my bad english :)

 

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi MicroGyro, thx again for helping... The "bad English" ( as you said) and my limited experience is not helping me follow easily at all. I thinking I have surmised that you are implying using a 4k boot would help me in my case? Your last post implies you're not %100 and you are looking further in to it? In that case may the force be with you ;) i'll remain a padawan for now.

 

Clawson, what do you make of all of this? I gather your experience to v-usb is only relevant in the preceding 70 posts? Though you have helped me thru so many battle in the last 7 years... Is my confusion shared? Does it make sense to receive a com error because of a hex size? Is the problem still possibly within the bootlaod code and not the v-usb HID data code? I know Christian well enough to say he generally does not make a mistake. Though I have found a pretty significant bug in his firmware only usb code so he is not infallible. :) What confuses things yet a bit further is that the two apps bootloadhid(command line) and boothidflash(gui) produce the same error. But it is very possible the gui was copped from the command tool. In that case it makes sense. 

Last Edited: Fri. May 12, 2017 - 01:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S_K_U_N_X wrote:
What confuses things yet a bit further is that the two apps bootloadhid(command line) and boothidflash(gui) produce the same error.
No, they do not produce the same error.

S_K_U_N_X wrote:
But it is very possible the gui was copped from the command tool.
The GUI tool you used first explicitly states that it is "not taking advantage of the Fischl BootloadHID.exe".

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry didn't mean to say same error, but both error out based on the same cause. Hex file too big. 

 

The GUI tool you used first explicitly states that it is "not taking advantage of the Fischl BootloadHID.exe".

Ah very good then. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi I'm back

 

Here is what my conclusion stick to datasheet:

 

 

The first 224 pages is RWW section, so using Christian HIDBoot code no problem will exist.

His code sequence doing:  "Erase Page" then fill page buffer and after SPM_PAGESIZE achived execute "Write Page".

This sequence don't give error because doing RWW section do not cause CPU halting.

That section is 0 to 0x7000.

 

 

The diagram shows better

 

 

Now how about NRWW section...

 

 

With HIDBoot code, this CPU halt will give error while the CPU doing "Erase Page" task, because HIDBoot code expect return value every 8 bytes data processed by usbfunctionwrite().

With CPU halt, the return value will never return or return USB_Stall thus the code can't continue to do fill buffer and writing flash, so this was how the error start. 

 

What to do then?

The previous sequence not suitable for this 16 pages in NRWW section.

To erase one page, send one set_request, let the CPU halt while doing page erase, don't expect return value.

This can be done for 16 times or one at a time follow by set_request for page write.

According to datasheet doing erase and write causing CPU halt, so erasing and writing this 16 pages needs 32 set_request with ignored return value.

 

So HIDBoot needs adjustment to cover this. And so the GUI. But if only the NRWW section need.

If not, HIDBoot  prety good.

 

Regarding the HEX size error, I never use debug from Christian. I prefer return the value I suspect using get_request.

So my explaination related to the OP question or not I don't know.

 

What I spotted is 32K-2K is 30K, not 28K.

224*128 + 16*128 = 30720 bytes.

 

 

May the ...

Good luck

 

 

 

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'll have to go over this a few times but I think I follow you here.

 

This is the relevant code

 

 

 

/* Name: main.c
 * Project: AVR bootloader HID
 * Author: Christian Starkjohann
 * Creation Date: 2007-03-19
 * Tabsize: 4
 * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
 * License: Proprietary, free under certain conditions. See Documentation.
 * This Revision: $Id$
 */


static int uploadData(char *dataBuffer, int startAddr, int endAddr)
{
usbDevice_t *dev = NULL;
int         err = 0, len, mask, pageSize, deviceSize;
union{
    char            bytes[1];
    deviceInfo_t    info;
    deviceData_t    data;
}           buffer;

    if((err = usbOpenDevice(&dev, IDENT_VENDOR_NUM, IDENT_VENDOR_STRING, IDENT_PRODUCT_NUM, IDENT_PRODUCT_STRING, 1)) != 0){
        fprintf(stderr, "Error opening HIDBoot device: %s\n", usbErrorMessage(err));
        goto errorOccurred;
    }
    len = sizeof(buffer);
    if(endAddr > startAddr){    // we need to upload data
        if((err = usbGetReport(dev, USB_HID_REPORT_TYPE_FEATURE, 1, buffer.bytes, &len)) != 0){
            fprintf(stderr, "Error reading page size: %s\n", usbErrorMessage(err));
            goto errorOccurred;
        }
        if(len < sizeof(buffer.info)){
            fprintf(stderr, "Not enough bytes in device info report (%d instead of %d)\n", len, (int)sizeof(buffer.info));
            err = -1;
            goto errorOccurred;
        }
        pageSize = getUsbInt(buffer.info.pageSize, 2);
        deviceSize = getUsbInt(buffer.info.flashSize, 4);
        printf("Page size   = %d (0x%x)\n", pageSize, pageSize);
        printf("Device size = %d (0x%x); %d bytes remaining\n", deviceSize, deviceSize, deviceSize - 2048);
        if(endAddr > deviceSize - 2048){
            fprintf(stderr, "Data (%d bytes) exceeds remaining flash size!\n", endAddr);
            err = -1;
            goto errorOccurred;
        }
        if(pageSize < 128){
            mask = 127;
        }else{
            mask = pageSize - 1;
        }
        startAddr &= ~mask;                  /* round down */
        endAddr = (endAddr + mask) & ~mask;  /* round up */
        printf("Uploading %d (0x%x) bytes starting at %d (0x%x)\n", endAddr - startAddr, endAddr - startAddr, startAddr, startAddr);
        while(startAddr < endAddr){
            buffer.data.reportId = 2;
            memcpy(buffer.data.data, dataBuffer + startAddr, 128);
            setUsbInt(buffer.data.address, startAddr, 3);
            printf("\r0x%05x ... 0x%05x", startAddr, startAddr + (int)sizeof(buffer.data.data));
            fflush(stdout);
            if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0){
                fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err));
                goto errorOccurred;
            }
            startAddr += sizeof(buffer.data.data);
        }
        printf("\n");
    }
    if(leaveBootLoader){
        /* and now leave boot loader: */
        buffer.info.reportId = 1;
        usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.info));
        /* Ignore errors here. If the device reboots before we poll the response,
         * this request fails.
         */
    }
errorOccurred:
    if(dev != NULL)
        usbCloseDevice(dev);
    return err;
}

this is the error session that hauls.

 

if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0){
                fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err));
                goto errorOccurred;

 

If I understand you correctly I need to deny the code sending the error on some condition?

 

if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0 && someCondition ){
                fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err));
                goto errorOccurred;
Last Edited: Fri. May 12, 2017 - 03:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S_K_U_N_X wrote:
if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0 && someCondition ){ fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err)); goto errorOccurred;

 

Adding "someCondition " like that won't solve your problem. 

while(startAddr < endAddr)

Will executed with no error, but you only "erase the page" (16 pages in NRWW section) not follow by "writing the page" (16 pages in NRWW section).

It will give you 0xFF result inside those pages.

 

 

I'll try to give you brief explanation how the VUSB works, hope it helps.

 

Once this code excecute

if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0){
                fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err));
                goto errorOccurred;

The 328p device will get into this sequence:

Erase page + (16+1) times loop to fill page buffer + writing page.  All of it done in usbfunctionwrite().

 

 

16+1 loop got from :

 

usbfunctionwrite() only process 8 bytes at each call, then give the return value back as the result.

 

The "Report length" setup in the device is 131 bytes as you can see in HID Descriptor setup (at above part of HIDBoot.c)

So this 131 bytes will be divide by 8 which is 16 times usbfunctionwrite() call + 1 call to process the remaining 3 bytes. 131= 16*8 + 3.

 

Again: once usbSetReport executed, 131 bytes will transfered to device (which will trigger 16 times usbfunctionwrite() call + 1 extra call for remaining 3 bytes).

 

 

 

Now back to the error part:

 

As I said when usbSetReport get into address which is at NRWW section(7000~7800), the driver will get into CPU halt condition while "erasing page" at the given address.

 

 above line I wrote:

 The 328p device will get into this sequence:

 Erase page + (16+1) times loop to fill page buffer + writing page.  All of it done in usbfunctionwrite().

 

That page will indeed being erase by SPM, but halting condition makes  usbfunctionwrite() get into error result.

 

So  usbfunctionwrite() which should be call for 16 times, now only called once because usbfunctionwrite() returns error and all the loop canceled.

 

That's the reason why at above line of this post I wrote  only "erase the page" (in NRWW section). The next sequence after "erase part" won't be executed!

 

MicroGyro wrote:
What to do then? The previous sequence not suitable for this 16 pages in NRWW section. To erase one page, send one set_request, let the CPU halt while doing page erase, don't expect return value. This can be done for 16 times or one at a time follow by set_request for page write. According to datasheet doing erase and write causing CPU halt, so erasing and writing this 16 pages needs 32 set_request with ignored return value.

 

 

Cheers

 

 

 

 

I don't know why I'm still doing this hobby

Last Edited: Sat. May 13, 2017 - 01:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I feel I have a better understanding now. 

 

This is the issue

Erase page + (16+1) times loop to fill page buffer + writing page.  All of it done in usbfunctionwrite().​ does not return 

 

 

this is the solution. 

The previous sequence not suitable for this 16 pages in NRWW section.

To erase one page, send one set_request, let the CPU halt while doing page erase, don't expect return value.

This can be done for 16 times or one at a time follow by set_request for page write.

 

 

So I loop  while(startAddr < endAddr) I need to add a for loop (16 oscillation) ignore return + page write.

 

 

I tried this code and it worked, feel like it was too easy. the flash succeeded without err and the code it running. I guess ill make a change in the hex  code to verify. 

 

Device size = 32768 (0x8000); 30720 bytes remaining
Uploading 28800 (0x7080) bytes starting at 0 (0x0)
0x07000 ... 0x07080

D:\bootloadHID.2012-12-08\commandline\bootloadhid\Debug>

 

 

 while(startAddr < endAddr){
            buffer.data.reportId = 2;
            memcpy(buffer.data.data, dataBuffer + startAddr, 128);
            setUsbInt(buffer.data.address, startAddr, 3);
            printf("\r0x%05x ... 0x%05x", startAddr, startAddr + (int)sizeof(buffer.data.data));
            fflush(stdout);

            for (i=0;i<16;i++)//do 16 sets ???(step size may need startAddr += (sizeof(buffer.data.data) / 16);
                usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data));startAddr += sizeof(buffer.data.data);
                usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data));//page write

            if(0){

                //fprintf(stderr, "---Error uploading data block: %s\n", usbErrorMessage(err));
                goto errorOccurred;
            }
            startAddr += sizeof(buffer.data.data);
        }

Side effect, takes 16 times as long to flash, but I don't see a way around this because I have to wait for HID to finish. Going to cause many issue for users. 

 

No, my conclusion is that is didn't work. My planted change didn't show up.  I think it just flashed over one scion of code, over and over. Still really surprised the device still works. I'll look over it again.

 

 

Last Edited: Sat. May 13, 2017 - 08:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S_K_U_N_X wrote:
No, my conclusion is that is didn't work.

 

Of course it didn't work as expected ! 

 

 

S_K_U_N_X wrote:
while(startAddr < endAddr){

 

Above code execute 240 pages loops for full flash size;

 

And inside that each loops you do:

 

for (i=0;i<16;i++)//do 16 sets ???(step size may need startAddr += (sizeof(buffer.data.data) / 16);
                usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data));startAddr += sizeof(buffer.data.data);
                usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data));//page write

 

Another 16 loops ?

That means...  each loops *16 ? It will takes forever for those 240 pages ! Are you serious ?surprise

 

 

You can't just change only your command line code to do this nrww task, because the problem was also inside HIDBoot.c too.

The sequence inside it is always "Page erase + Fillbuffer + Write page".

 

MicroGyro wrote:
The previous sequence not suitable for this 16 pages in NRWW section.
 

So that sequence task need to be split up for "Page erase" task and "Fillbuffer + Write page" task while entering nrww section.

I guess you misunderstanding what this "sequence" point to. smiley Sorry for my unclear explanation. 

 

 

And your command line code changing should follow it.

 

MicroGyro wrote:
To erase one page, send one set_request, let the CPU halt while doing page erase, don't expect return value. This can be done for 16 times or one at a time follow by set_request for page write.
 

 

 

So with your "planted change", it  do nothing beside erasing nrww section again and again + burning those innocent rww section. indecision

Ignore above comment, I just want to scare you devil

 

 

 

Good luck

 

 

 

 

 

I don't know why I'm still doing this hobby

Last Edited: Sun. May 14, 2017 - 04:07 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I figured tiring it was the only way for you to explain what I needed to know. This last post did just hat.  Since the device is already in production there is no way I can change the HID code. So all hope is lost.

Pages