5 Replies Latest reply on Aug 2, 2016 3:51 AM by aschaller

    D2000: Enable UART in rom (QMSI)

    aschaller

      Dear all,

       

      I am working with QMSI from GitHub - quark-mcu/qmsi . My goal is to communicate with the rom binary. Thus, I am trying to enabled UART functionality in soc/quark_d2000/rom/rom_startup.c: void rom_startup(void). The datasheet as well as this thread mention that UART is available once the main clock is enabled, which I think is done by clock_setup(); in this very function. However, simply using QM_PRINTF("TEST\n"); at the very end of this function doesn't show anything on my terminal. Thus, I added the code below code at the end of rom_startup(void). However, it still does not show anything on minicom/putty.

      Thus my question: how is it possible to enable UART functionality for the rom code?

       

           clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_UARTA_REGISTER);

          stdout_uart_cfg.baud_divisor = BOOTROM_UART_115200;

          stdout_uart_cfg.line_control = QM_UART_LC_8N1;

       

          qm_uart_set_config(STDOUT_UART, &stdout_uart_cfg);

       

      Thanks

       

        • 1. Re: D2000: Enable UART in rom (QMSI)
          PabloM_Intel

          Hi aschaller,

           

          Let us investigate your case a little bit more. We are running some tests to replicate the behavior you’re getting. We’ll get back to you soon.

           

          Regards,

          -Pablo

          • 2. Re: D2000: Enable UART in rom (QMSI)
            PabloM_Intel

            Hi aschaller,

             

            Could you please provide your whole rom code?

            Also, I’m thinking that a possible solution would be to check the “hello world” example, as it makes use of the UART to send the message to the terminal. So if you debug the code you could see which commands are being called to enable the UART functionality and then add those lines to your code. After that you could add the line that you added before, QM_PRINTF("TEST\n"), and see what you get.

             

            Regards,

            -Pablo

            • 3. Re: D2000: Enable UART in rom (QMSI)
              aschaller

              Dear Pablo,

               

              I am using the standard rom code for the D2000 ($QMSI_DIR/soc/quark_d2000/rom/*). The only modified is function void rom_startup(void) in rom_startup.c (see below).

               

              I already used the "hello world" example in order to see how UART is enabled. However, UART initialization procedure is common to every example project:

               

              1.) in function $QMSI_DIR/sys/app_entry.c there is a function _start(void) which calls stdout_uart_setup(BOOTROM_UART_115200).

              2.) However, although this function is supposed to setup the UART clk and baut settings, UART functionality is available even before this function is called, as UART is implicitly enabled once the main clock is enabled (see this thread).

               

              So, I used the code from stdout_uart_setup() and used it in rom_startup() but without success (again, the same code as in this thread). Here is my modified code:

               

              /*

              * C runtime initialization.

              * This will be called from rom_startup.s

              */

              void rom_startup(void)

              {

                  void (*app_entry)(void) = (void *)LMT_APP_ADDR;

               

                  extern uint32_t __bss_start[];

                  extern uint32_t __data_vma[];

                  extern uint32_t __data_lma[];

                  extern uint32_t __data_size[];

                  extern uint32_t __bss_end[];

               

                

                  /* Zero out bss */

                  memset(__bss_start, 0x00, (uint32_t)__bss_end - (uint32_t)__bss_start);

               

                  /* Copy initialised variables */

                  memcpy(__data_vma, __data_lma, (size_t)__data_size);

               

                  power_setup();

                  clock_setup();

               

                  boot_sense_jtag_probe();

               

                  /* Interrupt initialisation */

                  irq_setup();

                  idt_init();

                  boot_aon_handle_spurious_irq();

              #if (DEBUG)

                  qm_int_vector_request(QM_INT_VECTOR_DOUBLE_FAULT, double_fault_isr);

              #endif

                  mvic_init();

                  __asm__ __volatile__("sti");

              #if (SYSTEM_UPDATE_ENABLE)

                  qm_flash_set_config(QM_FLASH_0, &cfg_wr);

                  bl_data_sanitize();

                  /* Check if the system update mode sticky bit is set */

                  if (DM_STICKY_BIT_CHK()) {

                      DM_STICKY_BIT_CLR();

                      /* run the device management code; dm_main() never returns */

                      dm_main();

                  }

                  /* Set up ISR to enter DM mode */

                  dm_hook_setup();

              #endif

               

                  boot_services_setup();

               

                  /*** This code was added to enable UART functionality in ROM ***//

                  clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_UARTA_REGISTER);

                  stdout_uart_cfg.baud_divisor = BOOTROM_UART_115200;

                  stdout_uart_cfg.line_control = QM_UART_LC_8N1;

               

                  qm_uart_set_config(STDOUT_UART, &stdout_uart_cfg);

                  

                  QM_PUTS("rom_startup()...\n\r");

                  QM_PRINTF("rom_startup()...\n\r");

               

                  /*** End of added code ***//

               

                  /* Execute application, provided that it has been programmed. */

                  if (0xffffffff != *(uint32_t *)LMT_APP_ADDR) {

                      app_entry();

                  }

              }

              • 4. Re: D2000: Enable UART in rom (QMSI)
                tanminger

                I also try to print something in rom, write the following code and it does work:

                And you also need to copy the pico_puts() and putuint() functions from sys/newlib-syscalls.c.

                And you also add the "#include "qm_uart.h"" in the file head, after "#include "power_states.h"".

                 

                    /* Execute application, provided that it has been programmed. */

                    if (0xffffffff != *(uint32_t *)LMT_APP_ADDR) {

                            // stdout_uart_setup(BOOTROM_UART_115200);

                            qm_pmux_select(QM_PIN_ID_12, QM_PMUX_FN_2);

                            stdout_uart_cfg.baud_divisor = BOOTROM_UART_115200;

                            stdout_uart_cfg.line_control = QM_UART_LC_8N1;

                            clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_UARTA_REGISTER);

                            qm_uart_set_config(STDOUT_UART, &stdout_uart_cfg);

                 

                            pico_puts("ROM verion: ");

                            putuint(*((unsigned int *)(0x1FFC)), 10, false);

                            pico_puts("\n");

                            pico_puts("Prepare for lunch the program\n");

                 

                        app_entry();

                    }

                • 5. Re: D2000: Enable UART in rom (QMSI)
                  aschaller

                  Dear tanminger,

                   

                  thanks a bunch for your hints, they helped my enabling UART functionality in ROM:

                   

                  i) I already had #include "qm_uart.h" added to rom_startup.c

                  ii) I further added the following code:

                  1. #define FORMAT_BUF_SIZE 32
                  2. the full implementation of static __inline__ int pico_putchar(int c) (from sys/newlib-syscalls.c),
                  3. the full implementation of static __inline__ char last_digit_to_char(unsigned int n, int base, bool upcase) rom sys/newlib-syscalls.c),
                  4. the full implementation of static __inline__ int putuint(unsigned int n, int base, bool upcase) (from sys/newlib-syscalls.c),
                  5. the full implementation of static __inline__ int pico_putchars(const char *s) (from sys/newlib-syscalls.c)
                  6. and moved the code to enable UART clock and setup baudrate etc. within the if (0xffffffff != *(uint32_t *)LMT_APP_ADDR) statement just as you proposed.