none
How to pass parameters to a function in assembly (pipeline code)? RRS feed

  • Question

  • My MCU (at91samg20) has a problem with reset controller described in an errata document, it needs to disable SDRAM before a reboot.

    The workaround is to trap the user reset with an interrupt to diasble SDRAM, but Assembly code is mandatory for the sequence bellow as ARM instructions need to be pipelined, but how can I access the registers such as "AT91C_SDRAMC_TR" directly without OALPAtoVA?

    Am I correct assuming that I have to resolve the address using "OALPAtoVA" if the handler code is inside the Kernel IOCTL?

    How do I pass a register pointer to the following function (sorry, don't know arm assembly)? and How do I load r0 if I am passing a pointer?

    AREA TEST, CODE
    INCLUDE AT91SAM9xxx.inc
    EXPORTsoft_user_reset
    soft_user_reset
    ;disable IRQs
    MRS r0, CPSR
    ORR r0, r0, #0x80
    MSR CPSR_c, r0
    ;change refresh rate to block all data accesses
    LDR r0, =AT91C_SDRAMC_TR
    LDR r1, =1
    STR r1, [r0]
    ;prepare power down command
    LDR r0, =AT91C_SDRAMC_LPR
    LDR r1, =2
    ;prepare proc_reset and periph_reset
    LDR r2, =AT91C_RSTC_RCR
    LDR r3, =0xA5000005
    ;perform power down command
    STR r1, [r0]
    ;perform proc_reset and periph_reset (in the ARM pipeline)
    STR r3, [r2]
    END

    Tuesday, March 27, 2012 9:54 PM

Answers

  • You may find some examples in other BSP on how to call a function written in assembler.

    If you are going to use the workaround somewhere in you C code you could create a pointer as you mentioned using OALPAtoVA to access the registers that you need to modify to disable the SDRAM.

    Best regards,

    Mike


    Digi International Inc http://www.digi.com

    • Marked as answer by Uri Kluk Wednesday, March 28, 2012 11:21 AM
    Wednesday, March 28, 2012 7:53 AM

All replies

  • You may find some examples in other BSP on how to call a function written in assembler.

    If you are going to use the workaround somewhere in you C code you could create a pointer as you mentioned using OALPAtoVA to access the registers that you need to modify to disable the SDRAM.

    Best regards,

    Mike


    Digi International Inc http://www.digi.com

    • Marked as answer by Uri Kluk Wednesday, March 28, 2012 11:21 AM
    Wednesday, March 28, 2012 7:53 AM
  • Thanks Mike,

    Maybe I should post a new thread, but it is connected so I will just reply:

    I enable a source for Interrupt (the reset button on my board). For the AT91SAM it is done as follows:

    pResetCtrl->RMR = (AT91C_RSTC_URSTIEN | (0xA5 <<24));

    I am expecting the interrupt to be catched by the Kernel and exposed to OEMInterruptHandler with ID_SYS (as the watchdog does) but it is never going there.

    So I want to know how to map my source of interrupt to OEMInterruptHandler with High Priority and System ID?

    If you have some sample code I will appreciate it.

    Friday, March 30, 2012 4:53 PM
  • I don' t know the CPU your are using but you normally need to initialise your interrupt to the system (InterruptInitalise) or request a SYSINTR with KernelIOControl. If it is some interrupt that you do not control through a driver you maybe could initialise the interrupt in the OALIntrInit function.

    Hope that can help you.

    Best regards,

    Mike


    Digi International Inc http://www.digi.com

    Monday, April 2, 2012 1:04 PM
  • What does happen when you press the reset button?   Does the board reset?   If so, then you probably need to do more to configure the input pin.

    Bruce Eitman (eMVP)
    Senior Engineer
    Bruce.Eitman AT Eurotech DOT com
    My BLOG http://geekswithblogs.net/bruceeitman

    Eurotech Inc.
    www.Eurotech.com

    Monday, April 2, 2012 1:09 PM
    Moderator