diff --git a/articles/nim.html b/articles/nim.html index 8f3445a12..30def1a46 100644 --- a/articles/nim.html +++ b/articles/nim.html @@ -81,10 +81,9 @@
  • 13 usleep
  • 14 Documentation
  • 15 Fix the RISC-V Timer with OpenSBI
  • -
  • 16 LED Driver for Ox64 BL808
  • -
  • 17 What’s Next
  • -
  • 18 Appendix: Build NuttX for QEMU
  • -
  • 19 Appendix: Build NuttX for Ox64
  • 📝 7 Jan 2024

    +
  • 16 What’s Next
  • +
  • 17 Appendix: Build NuttX for QEMU
  • +
  • 18 Appendix: Build NuttX for Ox64
  • 📝 7 Jan 2024

    Apache NuttX RTOS on Ox64 BL808 RISC-V SBC: Works great with Nim!

    Happy New Year! 2024 is here and we’re running Apache NuttX RTOS (Real-Time Operating System) on Single-Board Computers with plenty of RAM

    Like Pine64 Ox64 BL808 RISC-V SBC with 64 MB RAM! (Pic below)

    @@ -409,7 +408,10 @@ Hint: used config file '/workspaces/bookworm/apps/config.nims' [Conf] .................................................................................................................................... Hint: mm: orc; opt: size; options: -d:danger 92931 lines; 1.214s; 137.633MiB peakmem; proj: /workspaces/bookworm/apps/examples/hello_nim/hello_nim_async.nim; out: /workspaces/bookworm/apps/.nimcache/hello_nim_async.json [SuccessX] -

    7 LED Driver for Ox64

    + +

    GPIO 29 in BL808 Reference Manual (Page 119)

    +

    GPIO 29 in BL808 Reference Manual (Page 119)

    +

    7 LED Driver for Ox64

    Our Nim Experiment needs an LED Driver for Ox64…

    What’s the Quickest Way to create a NuttX LED Driver?

    U-Boot Bootloader can help! Power up Ox64 and press Enter a few times to reveal the U-Boot Command Prompt.

    @@ -450,48 +452,47 @@ $ md 0x20000938 1

    How did we figure out the Magic Bits for GPIO 29?

    -

    TODO

    -

    From BL808 Reference Manual Page 56, “Normal GPIO Output Mode”…

    +

    From BL808 Reference Manual Page 56, “Normal GPIO Output Mode”…

    -

    TODO: (GPIO Bits are listed in the pic above)

    +

    (GPIO Bits are listed in the pic above)

    Which means…

    -

    TODO

    -

    How to flip the GPIO in our NuttX LED Driver?

    -

    This is how we flip the GPIO in our NuttX LED Driver: bl808_userleds.c

    -
    // Switch the LEDs On and Off according to the LED Set
    +

    And we write the above values to GPIO 29 Register at 0x2000 0938 (gpio_cfg29)

    +

    How to flip the GPIO in our LED Driver?

    +

    We do this in our NuttX LED Driver: bl808_userleds.c

    +
    // Flip the LEDs On and Off according to the LED Set
     // (Bit 0 = LED 0)
     void board_userled_all(uint32_t ledset) {
     
    @@ -504,16 +505,16 @@ void board_userled_all(uint32_t ledset) {
         // If this is LED 0...
         if (i == 0) {
     
    -      // Switch it On or Off?
    +      // Flip it On or Off?
           if (val) {
     
    -        // Switch LED 0 (GPIO 29) to On:
    +        // Flip LED 0 (GPIO 29) to On:
             // Set gpio_cfg29 to (1 << 6) | (11 << 8) | (0 << 30) | (0 << 4) | (1 << 24)
             // mw 0x20000938 0x1000b40 1
             *(volatile uint32_t *) 0x20000938 = 0x1000b40;
           } else {
     
    -        // Switch LED 0 (GPIO 29) to Off:
    +        // Flip LED 0 (GPIO 29) to Off:
             // Set gpio_cfg29 to (1 << 6) | (11 << 8) | (0 << 30) | (0 << 4) | (0 << 24)
             // mw 0x20000938 0xb40 1
             *(volatile uint32_t *) 0x20000938 = 0xb40;
    @@ -1148,198 +1149,7 @@ void up_timer_initialize(void) {
     

    Now the sleep command works correctly in NuttX Shell!

    Here’s the log (ignore the errors)

    -

    16 LED Driver for Ox64 BL808

    -

    TODO

    -

    We wish to blink an LED with Nim on Ox64…

    - -

    But first we need a barebones NuttX LED Driver for Ox64.

    -

    How to create the NuttX LED Driver?

    -

    We assume LED is connected to GPIO 29, Pin 21. (See the Pinout)

    -

    (With a 47 Ohm Resistor, yellow-purple-black-gold)

    -

    How do we flip a BL808 GPIO High and Low?

    -

    From BL808 Reference Manual Page 56, “Normal GPIO Output Mode”…

    -
      -
    • -

      Set reg_gpio_xx_oe (Bit 6) to 1 to enable the GPIO output mode
      -= (1 << 6)

      -
    • -
    • -

      Set reg_gpio_xx_func_sel (Bits 8 to 12) to 11 to enter the SWGPIO mode
      -= (11 << 8)

      -
    • -
    • -

      Set reg_gpio_xx_mode (Bits 30 to 31) to 0 to enable the normal output function of I/O
      -= (0 << 30)

      -
    • -
    • -

      Set reg_gpio_xx_pu (Bit 4) and reg_gpio_xx_pd (Bit 5) to 0 to disable the internal pull-up and pull-down functions
      -= (0 << 4)

      -
    • -
    • -

      Set the level of I/O pin through reg_gpio_xx_o (Bit 24)
      -= Either (0 << 24) Or (1 << 24)

      -
    • -
    -

    (GPIO Bit Definitions are below)

    -

    Which means…

    -
      -
    • -

      Set GPIO Output to 0
      -= (1 << 6) | (11 << 8) | (0 << 30) | (0 << 4) | (0 << 24)
      -= 0xb40

      -
    • -
    • -

      Set GPIO Output to 1
      -= (1 << 6) | (11 << 8) | (0 << 30) | (0 << 4) | (1 << 24)
      -= 0x1000b40

      -
    • -
    -

    How to test this?

    -

    GPIO 29 Base Address gpio_cfg29 is 0x20000938.

    -

    For testing, we run U-Boot Bootloader Commands to set GPIO 29 to High and Low…

    -
    ## Dump gpio_cfg29 at 0x20000938
    -$ md 0x20000938 1
    -20000938: 00400803                             ..@.
    -
    -## Set GPIO Output to 0: (1 << 6) | (11 << 8) | (0 << 30) | (0 << 4) | (0 << 24)
    -## = 0xb40
    -$ mw 0x20000938 0xb40 1
    -$ md 0x20000938 1
    -20000938: 00000b40                             @...
    -
    -## Set GPIO Output to 1: (1 << 6) | (11 << 8) | (0 << 30) | (0 << 4) | (1 << 24)
    -## = 0x1000b40
    -$ mw 0x20000938 0x1000b40 1
    -$ md 020000938 1
    -20000938: 01000b40                             @...
    -
    -

    And U-Boot switches the LED On and Off correctly yay!

    -

    How to flip the GPIO in our NuttX LED Driver?

    -

    This is how we flip the GPIO in our NuttX LED Driver: bl808_userleds.c

    -
    // Switch the LEDs On and Off according to the LED Set
    -// (Bit 0 = LED 0)
    -void board_userled_all(uint32_t ledset)
    -{
    -  _info("ledset=0x%x\n", ledset);////
    -  int i;
    -
    -  // For LED 0 to 2...
    -  for (i = 0; i < BOARD_LEDS; i++)
    -    {
    -      // Get the desired state of the LED
    -      bool val = ((ledset & g_led_setmap[i]) != 0);
    -      _info("led=%d, val=%d\n", i, val);////
    -
    -      // If this is LED 0...
    -      if (i == 0)
    -        {
    -          // Switch it On or Off?
    -          if (val)
    -            {
    -              // Switch LED 0 (GPIO 29) to On:
    -              // Set gpio_cfg29 to (1 << 6) | (11 << 8) | (0 << 30) | (0 << 4) | (1 << 24)
    -              // mw 0x20000938 0x1000b40 1
    -              *(volatile uint32_t *) 0x20000938 = 0x1000b40;
    -            }
    -          else
    -            {
    -              // Switch LED 0 (GPIO 29) to Off:
    -              // Set gpio_cfg29 to (1 << 6) | (11 << 8) | (0 << 30) | (0 << 4) | (0 << 24)
    -              // mw 0x20000938 0xb40 1
    -              *(volatile uint32_t *) 0x20000938 = 0xb40;
    -            }
    -        }
    -      ////TODO: a64_pio_write(g_led_map[i], (ledset & g_led_setmap[i]) != 0);
    -    }
    -}
    -
    -

    And our LED Driver works OK with Nim: It blinks our LED on Ox64 BL808 SBC!

    - -

    Later we’ll replace the (awful) code above by the BL808 GPIO Driver. Which we’ll copy from NuttX for BL602.

    -

    How did we get the GPIO Bit Definitions?

    -

    From BL808 Reference Manual Page 119…

    -
    4.8.30 gpio_cfg29
    -Base Address:0x20000938
    -
    -Bits Name Type Reset Description
    -
    -31:30 reg_gpio_29_mode r/w 0 When GPIO Function Selected to SWGPIO
    -00 (Output Value Mode): GPIO Output by reg_gpio_x_o
    -Value
    -01 (Set/Celar Mode ) :GPIO Output set by reg_gpio_x_set
    -and clear by reg_gpio_x_clr
    -10 : SWGPIO Source comes from GPIO DMA (GPIO DMA
    -Mode), GPIO Output value by gpio_dma_o
    -11: SWGPIO Source comes from GPIO DMA (GPIO DMA
    -Mode), GPIO Outout value by gpio_dma_set/gpio_dma_clr
    -
    -29 RSVD
    -
    -28 reg_gpio_29_i r 0
    -
    -27 RSVD
    -
    -26 reg_gpio_29_clr w1p 0 When SWGPIO @ Set/Clear Mode
    -Set this bit will clear GPIO output value to 0,when set/clr at
    -the same time, only set take effect
    -
    -25 reg_gpio_29_set w1p 0 When SWGPIO @ Set/Clear Mode
    -Set this bit will set GPIO output value to 1,when set/clr at
    -the same time, only set take effect
    -
    -24 reg_gpio_29_o r/w 0 When SWGPIO @ Output Value Mode
    -00 : GPIO Value changes according to this value
    -01 : GPIO Value Set by this register and clr by clr_reg
    -
    -23 RSVD
    -
    -22 reg_gpio_29_int_mask r/w 1 mask interrupt (1)
    -
    -21 gpio_29_int_stat r 0 interrupt status
    -
    -20 reg_gpio_29_int_clr r/w 0 clear interrupt
    -
    -19:16 reg_gpio_29_int_mode_set r/w 0 0000 : sync falling edge trigger
    -0001 : sync rising edge trigger
    -0010 : sync low level trigger
    -0011 : sync high level trigger
    -01xx : sync rising & falling edge trigger
    -1000 : async falling edge trigger
    -1001 : async rising edge trigger
    -1010 : async low level trigger
    -1011 : async high level trigger
    -
    -15:13 RSVD
    -
    -12:8 reg_gpio_29_func_sel r/w 5’hB GPIO Function Select (Default : SW-GPIO)
    -
    -7 RSVD
    -
    -6 reg_gpio_29_oe r/w 0 Register Controlled GPIO Output Enable (Used when GPIO
    -Function select to Register Control GPIO)
    -
    -5 reg_gpio_29_pd r/w 0 GPIO Pull Down Control
    -
    -4 reg_gpio_29_pu r/w 0 GPIO Pull Up Control
    -
    -3:2 reg_gpio_29_drv r/w 0 GPIO Driving Control
    -
    -1 reg_gpio_29_smt r/w 1 GPIO SMT Control
    -
    -0 reg_gpio_29_ie r/w 0 GPIO Input Enable
    -

    17 What’s Next

    +

    16 What’s Next

    TODO

    Many Thanks to my GitHub Sponsors (and the awesome NuttX Community) for supporting my work! This article wouldn’t have been possible without your support.

      @@ -1364,9 +1174,9 @@ Function select to Register Control GPIO)

    Got a question, comment or suggestion? Create an Issue or submit a Pull Request here…

    lupyuen.github.io/src/nim.md

    -

    18 Appendix: Build NuttX for QEMU

    +

    17 Appendix: Build NuttX for QEMU

    TODO

    -

    19 Appendix: Build NuttX for Ox64

    +

    18 Appendix: Build NuttX for Ox64

    TODO: ox64-1