Coder Social home page Coder Social logo

dinau / nimonavr Goto Github PK

View Code? Open in Web Editor NEW
24.0 2.0 0.0 78 KB

Nim language test program for Arduino UNO/Nano or its compatibles

License: MIT License

Makefile 0.34% Nim 61.01% C 32.38% CMake 0.97% C++ 5.30%
arduino avr blink c2nim dimmer led nano nim nim-lang pwm

nimonavr's Introduction

Nim On AVR

Nim language test program for Arduino UNO/Nano

Prerequisite

  • nim-1.6.0
    • Important:
      • It must be used above nim version otherwise it won't work well.
  • avr-gcc v7.3.0 (inclued in arduino-1.8.16 IDE)
    • For example, if on Windows10 set executable path to
      d:\arduino-1.8.16\hardware\tools\avr\bin
  • make,rm and etc Linux tool commands
  • CMake version 3.13 or later

AVR peripheral register access

  • Load / Store operation
    • Load from peripheral register
       var 
          inData1 = PORTB.v
          inData2 = PORTB.ld  # same as above
    • Store to peripheral register
       PORTD.v = 123  
       PORTD.st 123   # same as above
       PORTD.st(123)  # same as above
  • Bit operation
    • 1 bit

      PORTB.b3 = 1             # bit set
      PORTB.b7 = 0             # bit clear 
      # Note: (bx: x = 0..7 )
      var 
          bitdata = PORTD.b2   # bit read
    • Multi bits

          # Set / clear multi bits at a time specifiying bit name.
          PORTC.bset [PORTC0,PORTC1,PORTC6,PORTC7]  
          SPCR.bclr [SPR0,SPR1] 
    • BV() function

      SPCR.v = BV(SPE) + BV(MSTR)
    • See also reg_utils.nim

    • Peripheral register definition file

Example1

LED blink

  • Simple LED blinker program.

    $ cd example1/led  
    $ make  
    
    $ make 
    ........................................................
    CC: stdlib_system.nim
    CC: delay.nim
    CC: main.nim
    Hint:  [Link]
    Hint: gc: arc; opt: speed; options: -d:danger
    51065 lines; 2.461s; 49.953MiB peakmem; proj: src\main; out: D:\nim-data\avr\nimOnAVR\example1\led\.BUILD\main.elf [SuccessX]
       text    data     bss     dec     hex filename
        234       0       0     234      ea .BUILD\main.elf

    You can use make command for build management as follows,

    $ make # build target
    $ make clean # clean target
    $ make w # upload to flash

    or,

    $ nim make # build target
    $ nim clean # clean target
    $ nim w # upload to flash
  • Artifacts (*.hex,*.lst files etc) would be generate to .BUILD folder.

  • Code: src/main.nim

    import iom328p,delay
    
    # LED setting
    proc led_setup() = DDRB.b5  = 1
    proc led_on()    = PORTB.b5 = 1
    proc led_off()   = PORTB.b5 = 0
    
    # main program
    proc main() =
        led_setup()
        while true:
            led_on()
            wait_ms(1000)
            led_off()
            wait_ms(1000)
    
    main()
  • Upload(write to Flash) the generated file to Arduino board

    • For instance Arduino Uno,
      $ make w 
      
      • Constant ARDUINO_VER, COM_PORT, AVRDUDE_BAUDRATE in config.nims must be properly set accoding to your envionment.
        See ./config.nims
        • cf.
            Arduino Uno:       AVRDUDE_BAUDRATE=115200
            Arduino Nano:      AVRDUDE_BAUDRATE=115200 
            Arduino Nano(old): AVRDUDE_BAUDRATE=57600 
          
      $ make w
      ........................................................
      Hint:  [Link]
      Hint: gc: arc; opt: speed; options: -d:danger
      51065 lines; 3.046s; 49.906MiB peakmem; proj: src\main; out: nimOnAVR\example1\led\.BUILD\main.elf [SuccessX]
         text    data     bss     dec     hex filename
          234       0       0     234      ea .BUILD\main.elf
      
      avrdude.exe: AVR device initialized and ready to accept instructions
      
      Reading | ################################################## | 100% 0.01s
      
      avrdude.exe: Device signature = 0x1e950f (probably m328p)
      avrdude.exe: erasing chip
      avrdude.exe: reading input file ".BUILD\main.elf"
      avrdude.exe: input file .BUILD\main.elf auto detected as ELF
      avrdude.exe: writing flash (234 bytes):
      
      Writing | ################################################## | 100% 0.10s
      
      avrdude.exe: 234 bytes of flash written
      avrdude.exe: verifying flash memory against .BUILD\main.elf:
      avrdude.exe: load data flash data from input file .BUILD\main.elf:
      avrdude.exe: input file .BUILD\main.elf auto detected as ELF
      avrdude.exe: input file .BUILD\main.elf contains 234 bytes
      avrdude.exe: reading on-chip flash data:
      
      Reading | ################################################## | 100% 0.08s
      
      avrdude.exe: verifying ...
      avrdude.exe: 234 bytes of flash verified
      
      avrdude.exe done.  Thank you.

nimOnArduino

  • Simple LED blinker program.
    • Referred from 'Nim on Arduino'

      $ cd example1/nimOnArduino  
      $ make
      
      $ make
      ...................................................
      CC: led
      CC: stdlib_system.nim
      CC: blink.nim
      Hint:  [Link]
      Hint: gc: arc; opt: speed; options: -d:danger
      49796 lines; 2.468s; 49.953MiB peakmem; proj: .\blink; out: nimOnAVR\example1\nimOnArduino\.BUILD\blink.elf [SuccessX]
         text    data     bss     dec     hex filename
          234       0       0     234      ea .BUILD\blink.elf
      
    • Code: ./blink.nim , led.c

      {.compile: "led.c".}
      proc led_setup():   void {.importc.}
      proc led_on():      void {.importc.}
      proc led_off():     void {.importc.}
      proc delay(ms:int): void {.importc.}
      
      when isMainModule: 
          led_setup()
          while true:
              led_on()
              delay(1000)
              led_off()
              delay(1000)

UART

  • Simple UART test program with ChaN's xprintf() functions.
    • Set baudrate 38400bps to your terminal program.

      $ cd example1/uart  
      $ make
      
    • Code: src/main.nim

      ...
      # UART setting
      ...
      # main program
      proc main() =
          initUart(mBRate(BAUDRATE))
          var num = 0
          while true:
              xprintf("\n Number = %d", num)
              xputs("---")
              num += 1
              wait_ms(1000)
      main()

UART_LED

  • Just mixed UART and LED blinker test program.
    • Set baudrate 38400bps to your terminal program.
      $ cd example1/uart_led  
      $ make
      
    • Code: src/main.nim
      ...
      # UART setting
      ...
      # LED setting
      proc led_setup() = DDRB.b5  = 1
      proc led_on()    = PORTB.b5 = 1
      proc led_off()   = PORTB.b5 = 0
      
      # main program
      proc main() =
          led_setup()
          initUart(mBRate(BAUDRATE))
      
          var num = 0
          while true:
              led_on()
              wait_ms(500)
              led_off()
              wait_ms(500)
              xprintf("\n Number = %d", num)
              xputs("---")
              num += 1
      main()

Struct_Test_CMake

  • Simple test, object(struct) data interchanging between Nim and C language.
    • Set baudrate 38400bps to your terminal program.
      $ cd example1/struct_test_cmake  
      $ make
      
      • This project is using CMake to resolve dependency for C language files.
        • It's needed to install CMake v3.13 or later.
      • Artifacts (*.hex,*.lst files etc) would be generate to .build_cmake folder.
    • Type definition on Nim
      • Code src/main.nim
        type
            Student* {.byref.} = object
                age*:uint16
                cstringName*:cstring
                arrayName*: array[7,char]
        ...
        var
            std:Student
        ...
        show_and_modify_by_c_lang(std)
        ...
        
        proc show_and_modify_by_c_lang(std:var Student){.importc,cdecl.}
    • Type definition on C language
      • Code src/student.h
        typedef struct Student {
            uint16_t age;
            char *cstringName;
            char arrayName[7];
        } Student;
      • Code src/student.c
        void show_and_modify_by_c_lang(Student *std){
            ...
        }
    • Terminal output:
       === Showing std object in Nim ===
       Age         = 20
       cstringName = my_name_cstring
       arrayName   = ['A', 'B', '\x00', '\x00', '\x00', '\x00', '\x00']
      
       &std.age            = 0x000008d9
       &std.cstringName    = 0x000008db
       &std.arrayName      = 0x000008dd
       &std.cstringName[0] = 0x00000636
       &std.arrayName[0]   = 0x000008dd
      
      Calling C function: show_and_modify_by_c_lang(std)
      
       ======= Received the object pointer of std from Nim at C language function =======
          std.Age = 20
          std.cstrinName  = my_name_cstring
          std.arrayName   = AB
      
          &std.Age            = 0x000008d9
          &std.cstringNname   = 0x000008db
          &std.arrayName      = 0x000008dd
          &std.ctringNname[0] = 0x00000636
          &std.arrayName[0]   = 0x000008dd
      
          Now changing the object data as follows,
            std->age += 50;
            std->cstringName[0]='0';
            std->cstringName[1]='1';
            std->cstringName[2]='\0';
      
            std->arrayName[0]  ='1';
            std->arrayName[1]  ='2';
            std->arrayName[2]  ='3';
            std->arrayName[3]  ='4';
            std->arrayName[4]  ='5';
            std->arrayName[5]  ='\0';
      
       ============ in C language function end =======
      
      === Showing std object modified by C function ===
      Age         = 70
      cstringName = 01
      arrayName   = ['1', '2', '3', '4', '5', '\x00', '\x00']
      --- [ xprintf test ! ] ---
      

Example2

Intr_Test

  • Simple Interrupt/SPI/PWM/UART test program with ChaN's xprintf() functions.
    • Set baudrate 38400bps to your terminal program.
      $ cd example2/intr_test
      $ make
      
      • Terminal output:
        • If you wires D11(MOSI) with D12(MISO), SPI error will be gone away (=>0) because of loopback connection established.
          ...
          [00181]
               45504 Hz: PWM [44100 Hz] period interrupt freq.(Approximately)
            8282546:     SPI [D11->D12] error count in PWM period interrupt.
          ...
      • SPI pins
        • Chip select: D8(PB0) and D4(PD4)
        • MISO: D12(PB4), MOSI: D11(PB3)
        • SCK: D13(PB5)
      • If you have oscilloscope, it could be observed PWM signal(period=44.1kHz) at D9,D10 pin.
    • Code: src/main.nim
      # main program
      proc main() =
          initPort()
          initSystick()
          when UART_INFO:
              initUart(mBRate(UART_BAUDRATE)) # 38400bps
          initSpi()                           # SCK=8MHz
      
          initPwm()                           # PWM setting
          setPwmPeriod(PWM_FREQ)              # PWM frequency = 44100 Hz
          enablePwmPeriodIntr()               # Enable PWM period interrupt
          pwm_period_timer_start()            # PWM period Timer start
      
          pwm_dutyL(200)                      # D9
          pwm_dutyR(50)                       # D10
      
          setUserTicks(1000)
          ei()                                # Enable all interrupt
      
          var
              ix:int16 = 0
              prev:int32 = 0
          while true:
              if isTickTrigger():
                  clearTickTrigger()
                  disablePwmPeriodIntr()
                  let pwmCounter = pwmIntrCounter # int32
                  enablePwmPeriodIntr()
                  xprintf("\n[%05d]",ix)
                  xprintf("\n     %5ld Hz: PWM [44100 Hz] period interrupt freq.(Approximately)", pwmCounter - prev)
                  prev = pwmCounter
                  xprintf("\n    %9ld:     SPI [D11<-D12] error count in PWM period interrupt.",spi_err)
                  inc(ix)
      # Run main
      main()

SD_Card

  • This program shows SD card low-level initialize info and file list in root folder.
    • Set baudrate 38400bps to your terminal program.

      $ cd example2/sd_card
      $ make
      
    • Code src/main.nim

      when UART_INFO:
          {.compile:"xprintf.c".}
      
      template initPort*() =
      # set pull up to i/o port.
          PORTB.v = 0xFF
          PORTC.v = 0xFF
          PORTD.v = 0xFF
          DDRB.v =  0xEF # all output except PB4
          DDRD.v =  0xFF # all output port
      
      # main program
      proc main() =
          initPort()
          initSystick()
          when UART_INFO:
              initUart(mBRate(UART_BAUDRATE)) # 38400bps
          initSpi()                       # SCK=8MHz
          ei()                            # enable all interrupt
      
          while not sd_init():            # SDSC,SDHC initialize
              wait_ms(1500)
          FAT_init()                      # Accept FAT16 and FAT32
          for _ in 1..3:                  # Show the information of first 3 files.
              searchNextFile()
      
      # Run main
      main()
    • Terminal output: (Full output)

      [sd_card.nim] Start SD card init
      --- Found: SDv2 !
      --- --- ACMD41 OK
      --- --- --- Found: SDSC None Block Mode : CMD58
      [Finished!]: OK!  SD card init
      [fat_lib.nim/FAT_init()] Start MBR/FAT read
      MBR is:
       0000:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0010:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0020:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0030:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0040:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0050:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0060:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0070:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0080:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0090:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       00A0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       00B0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       00C0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       00D0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       00E0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       00F0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0100:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0110:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0120:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0130:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0140:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0150:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0160:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0170:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0180:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       0190:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       01A0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       01B0:00 00 00 00 00 00 00 00 FD 3D DE 19 00 00 00 03
       01C0:3F 00 06 17 D7 D7 FB 00 00 00 05 7F 3C 00 00 00
       01D0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       01E0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
       01F0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA
      BPB_Sector[0x01C6] = 0x00FB [th sector]
      BPB_Info is:
       EB 00 90 4D 53 57 49 4E 34 2E 31 00 02 40 01 00 02 00 02 00 00 F8 F2 00 3F 00 40 00 FB 00 00 00
          dwBPB_SecPerFats32 = 242
          bBPB_NumFATs       = 2
          wBPB_RsvdSecCnt    = 1
          dwBPB_HiddSec      = 251
          lgdwRootdir_sector = 736
          lgwSize_of_root    = 16384
          lgwBPB_RootEntCnt  = 512
          lgbBPB_SecPerClus  = 64
          lgwBPB_BytesPerSec = 512
      File entries(FENT) of 32byte are:
      FENT: 42 20 00 49 00 6E 00 66 00 6F 00 0F 00 72 72 00 6D 00 61 00 74 00 69 00 6F 00 00 00 6E 00 00 00
      asci:  B        I     n     f     o           r  r     m     a     t     i     o           n
      File entries(FENT) of 32byte are:
      ....
      ....
      skip the rest
    • SD card setup procedure

      1. Format SD card using SDFormatter program.
      2. Copy sample files to root folder on your PC.
    • FAT Filesystem reference FAT Filesystem

Other links1

Other links2

nimonavr's People

Contributors

dinau avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.