Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

Remote Update Component: Reading problems

Hello,

I am trying to implement a (hopefully failsafe) remote update

for a Cyclone III based board but have problems reading the

registers of the remote update component.

I've managed to download the user application over UART and

can trigger a reconfiguration.

When the system comes up and the factory configuration is started,

you don't know if the last update was successfull, so at startup

I try to read out the registers of the remote update component

and see if the last reboot was triggered due to a jump to a faulty configuration - and if that isn't the case I trigger a reconfiguration

to the user application.

My problem is, that I don't see, which register I could read in order

to find that out.

I thought, I could read 0x00 to see if I am currently using the

user (10/11) or factory (00) configuration.

And 0x1C (the 7th word) should yield the reboot trigger source

so 0x1 would be a scheduled reboot (see p.45 of ug_altremote.pdf),

0x10 a power up reboot and the rest would be errors...

Having done successfull and unsucessfull reconfiguration cycles (where

I deliberately set the address wrong before), I cannot find the register

with the trigger flags when I read from the remote update component.

Has anybody done this before?

Is there something, which I should watch out for?

Best regards,

Roman

PS: I haven't posted any posted anything till now, so please feel

free to correct me (formatting, missing data ...)

9 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Well,

    I've not used Cyclone III but I have used Stratix II. It looks like I read the AnF bit (maybe Stratix II only) to determine which image booted.

    I only read the status page if I'm in factory mode and not application mode. I don't think the status page is valid in application mode (I think you get all 0's). If I'm in factory mode, I use the status page to determine what was the source of the reconfig. Obviously if this is our first boot then we want to try and load the application image. If we already tried to load the application image and it failed, then there is no sense in trying to load the application image again.

    But I think the key is you can only read the status register if you're in factory mode.

    Jake
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I thought, I could read 0x00 to see if I am currently using the

    user (10/11) or factory (00) configuration.

    And 0x1C (the 7th word) should yield the reboot trigger source

    so 0x1 would be a scheduled reboot (see p.45 of ug_altremote.pdf),

    0x10 a power up reboot and the rest would be errors...

    --- Quote End ---

    The reboot trigger source is the 7th parameter, but I don't know where you get 0x1C from. To read the previous reboot trigger, I believe you should be reading from address 0x0F (read_source = 01, param = 111).

    For example:

    IORD(CYCLONEIII_BASE, 0x0F)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I am quite new to the NIOS programming and being a bit

    paranoid I use IORD_32DIRECT almost all of the time

    (thinking about the NIOS cache and anything else I barely heard of).

    Here the offset has to be given in bytes => 0x1C would be the 7.

    I thought that it had to be 0x7 since it's the most recent retrigger event

    but since I only see zeros there, you seem to be perfectly right.

    --------------------------------------------------

    Before my post I have done complete readouts of the

    memory content :

    after Factory->App@0x80000 (working)

    0x00000001 0x00000000 0x00000000 0x00000000

    0x00000008 0x00000000 0x00000000 0x00000000

    0x00000001 0x00000000 0x00000008 0x00000000

    0x00000008 0x00000000 0x00000000 0x00000010

    after App->Factory@0x00000 (working)

    0x00000000 0x00000000 0x00000000 0x00000000

    0x00000000 0x00000000 0x00000000 0x00000000

    0x00000000 0x00000000 0x05080000 0x00000000

    0x00080000 0x00000000 0x00000000 0x00000001

    after Factory->App@0xC0000 (nonWorking)->Factory

    0x00000000 0x00000000 0x00000000 0x00000000

    0x00000000 0x00000000 0x00000000 0x00000000

    0x00000000 0x00000000 0x010c0000 0x00000001

    0x000c0000 0x00000000 0x00000000 0x00000008

    --------------------------------------------------

    The first value is 1 in application mode and 0 in

    factory mode (seems to work).

    After the switch from application to factory mode (2nd)

    the trigger reason is 1 => runconfig => would be OK

    After the switch from factory mode to a faulty config (3rd)

    the trigger reason is 8 => crc_error => would be OK

    The problem I am having is that I made these tests

    and then I changed the addresses and repeated the

    test and I got all kinds of codes at the specified place

    0x1,0x2,0x4,0x8,0x10.

    .... <<< THINK THINK THINK THINK >>> ....

    I read out the values above in a row. Do I have to make

    pauses in between ? The update has the wait_us(...) so

    do you have to give the circuitry time ?

    I see different values when I read out 20 in a row and when

    I read them out one at a time.

    => I will look into that.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    >>> But I think the key is you can only read the status register

    >>> if you're in factory mode.

    Thanks for the enlightenment.

    I haven't found this information yet but I've seen it

    ... and it didn't make sense at the time.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    As a suggestion, I would recommend using the IORD macro instead of IORD_32DIRECT. You can accomplish the same thing but it's a little easier to think about.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Is your clock maybe too fast for the Remote Update component? On the Cyclone III, the max clock for the Remote Update component is 40 MHz.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I'll second that. Even on the Stratix II, I had similar issues trying to run the clock to fast. I didn't find out exactly where it broke. I could run it at 50MHz but not 100MHz.

    Jake
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I already heard, that you should place the component at 40MHz or lower.

    In my application it runs with 27MHz.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It seems to work now - yippie

    I had a bit of a problem with the flash programming

    (some mean "compressed" options burried in Quartus)

    which led me to flashing over the upper part of the

    factory configuration.

    That was more or less the biggest problem ...

    ... hopefully - since I didn't change much more ...

    -> It's running now and I can quit in the middle of the

    update, falling back to the factory configuration.

    Thanks for your help. I think it would surely have taken

    some more time wondering about the values in user_mode

    (which are just invalid) and staring at offset 0x7 for the

    trigger reason.

    ---- if someone is interested for the c-implementation: ---

    void upgrade_start_user_config () {

    UINT32 tmp;

    tmp = IORD(base_address_for_upgrade_controller, 0x0 );

    if (tmp != 0)

    return;

    tmp = IORD(base_address_for_upgrade_controller, 0xF );

    // when we are starting with a normal reboot

    if (tmp == 0x00) {

    IOWR( base_address_for_upgrade_controller, 0x3, 0 );

    wait_ms(1);

    IOWR( base_address_for_upgrade_controller, 0x4, (user_config_address >> 2) );

    wait_ms(1);

    IOWR( base_address_for_upgrade_controller, 0x20, 0x1 );

    wait_ms(1);

    }

    }

    ... is always called at the initialization and will

    * return immediately

    * if the code is placed in the user configuration (testing @offset 0)

    * if the trigger reason shows an error at the last boot

    * else trigger a reboot at the standard location for the user configuration

    -----------------------------------------------------