Nano Every Page

From bibbleWiki
Jump to navigation Jump to search

Introduction

I while ago I started my interest in the 6502 where it all began to me. This led me to Ben Eater and building an 8-bit computer. Which led me to building a EEPROM programmer and a Nano was required to build it. I had a bit of work to do and my interest seemed to be waning a little. Partly because of the time to get it to work and and because I just felt demotivated. So I solved my motivation by returning to rust and saw that it is possible to run it on a Nano Every. Let the games begin.

Ben's EEPROM

The Board

Here is the EEPROM. I think I made it look quite pretty with the colours. Funny how that seemed important at the time. EEPROM BEN.jpg

The Circuit

I ended up using the circuit from Ben's page. The nano D5 connected to the AT28C256
EEPROM Circuit.png

The Code

And of course the code.

#define SHIFT_DATA 2
#define SHIFT_CLK 3
#define SHIFT_LATCH 4
#define WRITE_EN 13

// 32 byte test pattern to verify the EEPROM device.  The pattern includes a walking one
// and a walking zero, which may help to detect pins that are tied together or swapped.
// byte data[] = {
//     'A',  'B',  'C',  'D',  'E',  'F',  'G',  'H',
//     0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
//     0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe,
//     0x00, 0xff, 0x55, 0xaa, '0',  '1',  '2',  '3'
// };


byte data[] = {
    'A',  'B',  'B',  'D',  'E',  'F',  'G',  'H',
    'A',  'B',  'C',  'D',  'E',  'F',  'G',  'H'
};

void enableWrite()      { digitalWrite(WRITE_EN, LOW);}
void disableWrite()     { digitalWrite(WRITE_EN, HIGH);}


// Read a byte from the data bus.  The caller must set the bus to input_mode
// before calling this or no useful data will be returned.
byte readDataBus() {
    return (PINB << 3) | (PIND >> 5);
}

// Read a byte from the EEPROM at the specified address.
byte readEEPROM(int address) {
    setDataBusMode(INPUT);
    setAddress(address, /*outputEnable*/ true);
    return readDataBus();
}

// Write a byte to the EEPROM at the specified address.
void writeEEPROM(int address, byte data) {
    setAddress(address, /*outputEnable*/ false);
    setDataBusMode(OUTPUT);
    writeDataBus(data);
    enableWrite();
    // delayMicroseconds(1);
    disableWrite();
    delay(10);
}

// Read the first 256 byte block of the EEPROM and dump it to the serial monitor.
void printContents(int size) {
    for (int base = 0; (base < size); base += 16) {
        byte data[16];
        for (int offset = 0; offset <= 15; offset += 1) {
            data[offset] = readEEPROM(base + offset);
        }

        char buf[80];
        sprintf(buf, "%04x:  %02x %02x %02x %02x %02x %02x %02x %02x   %02x %02x %02x %02x %02x %02x %02x %02x",
            base, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
            data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);
        Serial.println(buf);
    }
}
// Output the address bits and outputEnable signal using shift registers.
void setAddress(int addr, bool outputEnable) {
    // Set the highest bit as the output enable bit (active low)
    if (outputEnable) {
        addr &= ~0x8000;
    } else {
        addr |= 0x8000;
    }
    byte dataMask = 0x04;
    byte clkMask = 0x08;
    byte latchMask = 0x10;

    // Make sure the clock is low to start.
    PORTD &= ~clkMask;

    // Shift 16 bits in, starting with the MSB.
    for (uint16_t ix = 0; (ix < 16); ix++)
    {
        // Set the data bit
        if (addr & 0x8000)
        {
            PORTD |= dataMask;
        }
        else
        {
            PORTD &= ~dataMask;
        }

        // Toggle the clock high then low
        PORTD |= clkMask;
        // delayMicroseconds(3);
        PORTD &= ~clkMask;
        addr <<= 1;
    }

    // Latch the shift register contents into the output register.
    PORTD &= ~latchMask;
    // delayMicroseconds(1);
    PORTD |= latchMask;
    // delayMicroseconds(1);
    PORTD &= ~latchMask;
}

// Write a byte to the data bus.  The caller must set the bus to output_mode
// before calling this or no data will be written.
void writeDataBus(byte data) {
     PORTB = (PORTB & 0xe0) | (data >> 3);
     PORTD = (PORTD & 0x1f) | (data << 5);
}
// Set an address and data value and toggle the write control.  This is used
// to write control sequences, like the software write protect.  This is not a
// complete byte write function because it does not set the chip enable or the
// mode of the data bus.
void setByte(byte value, word address) {
    setAddress(address, false);
    writeDataBus(value);

    // delayMicroseconds(1);
    enableWrite();
    // delayMicroseconds(1);
    disableWrite();
}

// Set the I/O state of the data bus.
// The 8 bits data bus are is on pins D5..D12.
void setDataBusMode(uint8_t mode) {
    // On the Uno and Nano, D5..D12 maps to the upper 3 bits of port D and the
    // lower 5 bits of port B.
    if (mode == OUTPUT) {
        DDRB |= 0x1f;
        DDRD |= 0xe0;
    } else {
        DDRB &= 0xe0;
        DDRD &= 0x1f;
    }
}

void disableSoftwareWriteProtect() {
    disableWrite();
    setDataBusMode(OUTPUT);

    setByte(0xaa, 0x5555);
    setByte(0x55, 0x2aaa);
    setByte(0x80, 0x5555);
    setByte(0xaa, 0x5555);
    setByte(0x55, 0x2aaa);
    setByte(0x20, 0x5555);

    setDataBusMode(INPUT);
    delay(10);
}
void setup() {

  // put your setup code here, to run once:
  pinMode(SHIFT_DATA, OUTPUT);
  pinMode(SHIFT_CLK, OUTPUT);
  pinMode(SHIFT_LATCH, OUTPUT);
  disableWrite();
  pinMode(WRITE_EN, OUTPUT);

  Serial.begin(115200);

  Serial.print("\nDisabling EEPROM Software Data Protection(SDP)...");
  disableSoftwareWriteProtect();
  Serial.println(" done\n");

  // Read and print out the contents of the EERPROM
  Serial.println("Reading EEPROM");
  printContents(32);  

  // Program a test pattern and fill the remainder of the first block with 0xff
  Serial.print("Programming EEPROM...");
  for (word address = 0; (address < sizeof(data)); address++) {
      writeEEPROM(address, data[address]);
  }
  
  // for (word address = sizeof(data); (address < 256); address++) {
  //    writeEEPROM(address, 0xfe);
  // }
  Serial.println(" done\n");

  // Read and print out the contents of the EERPROM
  Serial.println("Reading EEPROM");
  printContents(32);  

}

void loop()
{
    // put your main code here, to run repeatedly:
}

Disabling Software Protection (SDP)

I did not like the use of PORTC, PORTD etc as this suggested shortcuts and would obfuscate the code. But reading more I found that the code struggled to meet the timings to disable the AT28C256 protections which is why it took me so long to get this going. Many thanks to TommyPROM which was my last port of call. https://tomnisbet.github.io/TommyPROM/28C256-notes/
AT28C256.jpg

Arduino Nano

I also had trouble setting up the Nano, the every previous. Need to stop the brtty service running for it to connect

systemctl stop brltty-udev.service
sudo systemctl mask brltty-udev.service
systemctl stop brltty.service
systemctl disable brltty.service

Arduino and with Nano Every

I could not install the Arduino software using apt and with snap the directories were somewhere else. For me on Ubuntu 23.04 I instead downloaded, and extracted it. Make sure you make a directory to extract to. Then when you run the IDE you will be able to select Nano Every and there will be the 1.8.8 directory. Without 1.8.8 you will not be able to upload with VS Code. Here is my arduino.json setting.

{
    "port": "/dev/ttyACM1",
    "board": "arduino:megaavr:nona4809",
    "sketch": "blinkNative.ino",
    "programmer": "medbg",
    "configuration": "mode=on"
}

Blink and VS Code with Nano Every

Really do not like the Arduino IDE so was really happy VS Code not supports it with the Microsoft Extension. Just look at the colours and the status bar, board, usb port.
Ardunino VSCOD.jpg

Had to add the udev rules in /etc/udev/rules.d/99-arduino-nano.rules

 # Arduino nano
 SUBSYSTEM=="tty", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0058", PROGRAM="/usr/bin/arduino-udev-name -w 2 %k", SYMLINK+="%c", GROUP="plugdev"

These were generated by the plugin but here for reference. (Loving the nona) in arduino.json

{
    "port": "/dev/ttyACM0",
    "configuration": "mode=on",
    "board": "arduino:megaavr:nona4809",
    "sketch": "blinkNative.ino"
}

and c_cpp_properties.json

{
    "version": 4,
    "configurations": [
        {
            "name": "Arduino",
            "compilerPath": "/home/iwiseman/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++",
            "compilerArgs": [
                "-w",
                "-std=gnu++11",
                "-fpermissive",
                "-fno-exceptions",
                "-ffunction-sections",
                "-fdata-sections",
                "-fno-threadsafe-statics",
                "-Wno-error=narrowing"
            ],
            "intelliSenseMode": "gcc-x64",
            "includePath": [
                "/home/iwiseman/.arduino15/packages/arduino/hardware/megaavr/1.8.8/cores/arduino/api/deprecated",
                "/home/iwiseman/.arduino15/packages/arduino/hardware/megaavr/1.8.8/cores/arduino",
                "/home/iwiseman/.arduino15/packages/arduino/hardware/megaavr/1.8.8/variants/nona4809",
                "/home/iwiseman/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/lib/gcc/avr/7.3.0/include",
                "/home/iwiseman/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/lib/gcc/avr/7.3.0/include-fixed",
                "/home/iwiseman/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/avr/include"
            ],
            "forcedInclude": [
                "/home/iwiseman/.arduino15/packages/arduino/hardware/megaavr/1.8.8/cores/arduino/Arduino.h"
            ],
            "cStandard": "c11",
            "cppStandard": "c++11",
            "defines": [
                "F_CPU=16000000L",
                "ARDUINO=10607",
                "ARDUINO_AVR_NANO_EVERY",
                "ARDUINO_ARCH_MEGAAVR",
                "AVR_NANO_4809_328MODE",
                "MILLIS_USE_TIMERB3",
                "NO_EXTERNAL_I2C_PULLUP",
                "__DBL_MIN_EXP__=(-125)",
                "__HQ_FBIT__=15",
                "__cpp_attributes=200809",
                "__UINT_LEAST16_MAX__=0xffffU",
                "__ATOMIC_ACQUIRE=2",
                "__SFRACT_IBIT__=0",
                "__FLT_MIN__=1.17549435e-38F",
                "__GCC_IEC_559_COMPLEX=0",
                "__BUILTIN_AVR_SLEEP=1",
                "__BUILTIN_AVR_COUNTLSULLK=1",
                "__cpp_aggregate_nsdmi=201304",
                "__BUILTIN_AVR_COUNTLSULLR=1",
                "__UFRACT_MAX__=0XFFFFP-16UR",
                "__UINT_LEAST8_TYPE__=unsigned char",
                "__DQ_FBIT__=63",
                "__INTMAX_C(c)=c ## LL",
                "__ULFRACT_FBIT__=32",
                "__SACCUM_EPSILON__=0x1P-7HK",
                "__CHAR_BIT__=8",
                "__USQ_IBIT__=0",
                "__UINT8_MAX__=0xff",
                "__ACCUM_FBIT__=15",
                "__WINT_MAX__=0x7fff",
                "__FLT32_MIN_EXP__=(-125)",
                "__cpp_static_assert=200410",
                "__USFRACT_FBIT__=8",
                "__ORDER_LITTLE_ENDIAN__=1234",
                "__SIZE_MAX__=0xffffU",
                "__WCHAR_MAX__=0x7fff",
                "__LACCUM_IBIT__=32",
                "__DBL_DENORM_MIN__=double(1.40129846e-45L)",
                "__GCC_ATOMIC_CHAR_LOCK_FREE=1",
                "__GCC_IEC_559=0",
                "__FLT_EVAL_METHOD__=0",
                "__BUILTIN_AVR_LLKBITS=1",
                "__cpp_binary_literals=201304",
                "__LLACCUM_MAX__=0X7FFFFFFFFFFFFFFFP-47LLK",
                "__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
                "__BUILTIN_AVR_HKBITS=1",
                "__BUILTIN_AVR_BITSLLK=1",
                "__FRACT_FBIT__=15",
                "__BUILTIN_AVR_BITSLLR=1",
                "__cpp_variadic_templates=200704",
                "__UINT_FAST64_MAX__=0xffffffffffffffffULL",
                "__SIG_ATOMIC_TYPE__=char",
                "__BUILTIN_AVR_UHKBITS=1",
                "__UACCUM_FBIT__=16",
                "__DBL_MIN_10_EXP__=(-37)",
                "__FINITE_MATH_ONLY__=0",
                "__cpp_variable_templates=201304",
                "__LFRACT_IBIT__=0",
                "__GNUC_PATCHLEVEL__=0",
                "__FLT32_HAS_DENORM__=1",
                "__LFRACT_MAX__=0X7FFFFFFFP-31LR",
                "__UINT_FAST8_MAX__=0xff",
                "__has_include(STR)=__has_include__(STR)",
                "__DEC64_MAX_EXP__=385",
                "__INT8_C(c)=c",
                "__INT_LEAST8_WIDTH__=8",
                "__UINT_LEAST64_MAX__=0xffffffffffffffffULL",
                "__SA_FBIT__=15",
                "__SHRT_MAX__=0x7fff",
                "__LDBL_MAX__=3.40282347e+38L",
                "__FRACT_MAX__=0X7FFFP-15R",
                "__UFRACT_FBIT__=16",
                "__UFRACT_MIN__=0.0UR",
                "__UINT_LEAST8_MAX__=0xff",
                "__GCC_ATOMIC_BOOL_LOCK_FREE=1",
                "__UINTMAX_TYPE__=long long unsigned int",
                "__LLFRACT_EPSILON__=0x1P-63LLR",
                "__BUILTIN_AVR_DELAY_CYCLES=1",
                "__DEC32_EPSILON__=1E-6DF",
                "__FLT_EVAL_METHOD_TS_18661_3__=0",
                "__UINT32_MAX__=0xffffffffUL",
                "__GXX_EXPERIMENTAL_CXX0X__=1",
                "__ULFRACT_MAX__=0XFFFFFFFFP-32ULR",
                "__TA_IBIT__=16",
                "__LDBL_MAX_EXP__=128",
                "__WINT_MIN__=(-__WINT_MAX__ - 1)",
                "__INT_LEAST16_WIDTH__=16",
                "__ULLFRACT_MIN__=0.0ULLR",
                "__SCHAR_MAX__=0x7f",
                "__WCHAR_MIN__=(-__WCHAR_MAX__ - 1)",
                "__INT64_C(c)=c ## LL",
                "__DBL_DIG__=6",
                "__GCC_ATOMIC_POINTER_LOCK_FREE=1",
                "__AVR_HAVE_SPH__=1",
                "__LLACCUM_MIN__=(-0X1P15LLK-0X1P15LLK)",
                "__BUILTIN_AVR_KBITS=1",
                "__BUILTIN_AVR_ABSK=1",
                "__BUILTIN_AVR_ABSR=1",
                "__SIZEOF_INT__=2",
                "__SIZEOF_POINTER__=2",
                "__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
                "__USACCUM_IBIT__=8",
                "__USER_LABEL_PREFIX__",
                "__STDC_HOSTED__=1",
                "__LDBL_HAS_INFINITY__=1",
                "__LFRACT_MIN__=(-0.5LR-0.5LR)",
                "__HA_IBIT__=8",
                "__FLT32_DIG__=6",
                "__TQ_IBIT__=0",
                "__FLT_EPSILON__=1.19209290e-7F",
                "__GXX_WEAK__=1",
                "__SHRT_WIDTH__=16",
                "__USFRACT_IBIT__=0",
                "__LDBL_MIN__=1.17549435e-38L",
                "__FRACT_MIN__=(-0.5R-0.5R)",
                "__AVR_SFR_OFFSET__=0x20",
                "__DEC32_MAX__=9.999999E96DF",
                "__cpp_threadsafe_static_init=200806",
                "__DA_IBIT__=32",
                "__INT32_MAX__=0x7fffffffL",
                "__UQQ_FBIT__=8",
                "__INT_WIDTH__=16",
                "__SIZEOF_LONG__=4",
                "__UACCUM_MAX__=0XFFFFFFFFP-16UK",
                "__UINT16_C(c)=c ## U",
                "__PTRDIFF_WIDTH__=16",
                "__DECIMAL_DIG__=9",
                "__LFRACT_EPSILON__=0x1P-31LR",
                "__AVR_2_BYTE_PC__=1",
                "__ULFRACT_MIN__=0.0ULR",
                "__INTMAX_WIDTH__=64",
                "__has_include_next(STR)=__has_include_next__(STR)",
                "__BUILTIN_AVR_ULLRBITS=1",
                "__LDBL_HAS_QUIET_NAN__=1",
                "__ULACCUM_IBIT__=32",
                "__UACCUM_EPSILON__=0x1P-16UK",
                "__BUILTIN_AVR_SEI=1",
                "__GNUC__=7",
                "__ULLACCUM_MAX__=0XFFFFFFFFFFFFFFFFP-48ULLK",
                "__cpp_delegating_constructors=200604",
                "__HQ_IBIT__=0",
                "__BUILTIN_AVR_SWAP=1",
                "__FLT_HAS_DENORM__=1",
                "__SIZEOF_LONG_DOUBLE__=4",
                "__BIGGEST_ALIGNMENT__=1",
                "__STDC_UTF_16__=1",
                "__UINT24_MAX__=16777215UL",
                "__BUILTIN_AVR_NOP=1",
                "__GNUC_STDC_INLINE__=1",
                "__DQ_IBIT__=0",
                "__FLT32_HAS_INFINITY__=1",
                "__DBL_MAX__=double(3.40282347e+38L)",
                "__ULFRACT_IBIT__=0",
                "__cpp_raw_strings=200710",
                "__INT_FAST32_MAX__=0x7fffffffL",
                "__DBL_HAS_INFINITY__=1",
                "__INT64_MAX__=0x7fffffffffffffffLL",
                "__ACCUM_IBIT__=16",
                "__DEC32_MIN_EXP__=(-94)",
                "__BUILTIN_AVR_UKBITS=1",
                "__INTPTR_WIDTH__=16",
                "__BUILTIN_AVR_FMULSU=1",
                "__LACCUM_MAX__=0X7FFFFFFFFFFFFFFFP-31LK",
                "__INT_FAST16_TYPE__=int",
                "__LDBL_HAS_DENORM__=1",
                "__BUILTIN_AVR_BITSK=1",
                "__BUILTIN_AVR_BITSR=1",
                "__cplusplus=201402L",
                "__cpp_ref_qualifiers=200710",
                "__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
                "__INT_LEAST32_MAX__=0x7fffffffL",
                "__USING_SJLJ_EXCEPTIONS__=1",
                "__DEC32_MIN__=1E-95DF",
                "__ACCUM_MAX__=0X7FFFFFFFP-15K",
                "__DEPRECATED=1",
                "__cpp_rvalue_references=200610",
                "__DBL_MAX_EXP__=128",
                "__USACCUM_EPSILON__=0x1P-8UHK",
                "__WCHAR_WIDTH__=16",
                "__FLT32_MAX__=3.40282347e+38F32",
                "__DEC128_EPSILON__=1E-33DL",
                "__SFRACT_MAX__=0X7FP-7HR",
                "__FRACT_IBIT__=0",
                "__PTRDIFF_MAX__=0x7fff",
                "__UACCUM_MIN__=0.0UK",
                "__UACCUM_IBIT__=16",
                "__BUILTIN_AVR_NOPS=1",
                "__BUILTIN_AVR_WDR=1",
                "__FLT32_HAS_QUIET_NAN__=1",
                "__GNUG__=7",
                "__LONG_LONG_MAX__=0x7fffffffffffffffLL",
                "__SIZEOF_SIZE_T__=2",
                "__ULACCUM_MAX__=0XFFFFFFFFFFFFFFFFP-32ULK",
                "__cpp_rvalue_reference=200610",
                "__cpp_nsdmi=200809",
                "__SIZEOF_WINT_T__=2",
                "__LONG_LONG_WIDTH__=64",
                "__cpp_initializer_lists=200806",
                "__FLT32_MAX_EXP__=128",
                "__SA_IBIT__=16",
                "__ULLACCUM_MIN__=0.0ULLK",
                "__BUILTIN_AVR_ROUNDUHK=1",
                "__BUILTIN_AVR_ROUNDUHR=1",
                "__cpp_hex_float=201603",
                "__GXX_ABI_VERSION=1011",
                "__INT24_MAX__=8388607L",
                "__UTA_FBIT__=48",
                "__FLT_MIN_EXP__=(-125)",
                "__USFRACT_MAX__=0XFFP-8UHR",
                "__UFRACT_IBIT__=0",
                "__BUILTIN_AVR_ROUNDFX=1",
                "__BUILTIN_AVR_ROUNDULK=1",
                "__BUILTIN_AVR_ROUNDULR=1",
                "__cpp_lambdas=200907",
                "__BUILTIN_AVR_COUNTLSLLK=1",
                "__BUILTIN_AVR_COUNTLSLLR=1",
                "__BUILTIN_AVR_ROUNDHK=1",
                "__INT_FAST64_TYPE__=long long int",
                "__BUILTIN_AVR_ROUNDHR=1",
                "__DBL_MIN__=double(1.17549435e-38L)",
                "__BUILTIN_AVR_COUNTLSK=1",
                "__BUILTIN_AVR_ROUNDLK=1",
                "__BUILTIN_AVR_COUNTLSR=1",
                "__BUILTIN_AVR_ROUNDLR=1",
                "__LACCUM_MIN__=(-0X1P31LK-0X1P31LK)",
                "__ULLACCUM_FBIT__=48",
                "__BUILTIN_AVR_LKBITS=1",
                "__ULLFRACT_EPSILON__=0x1P-64ULLR",
                "__DEC128_MIN__=1E-6143DL",
                "__REGISTER_PREFIX__",
                "__UINT16_MAX__=0xffffU",
                "__DBL_HAS_DENORM__=1",
                "__BUILTIN_AVR_ULKBITS=1",
                "__ACCUM_MIN__=(-0X1P15K-0X1P15K)",
                "__AVR_ARCH__=2",
                "__SQ_IBIT__=0",
                "__FLT32_MIN__=1.17549435e-38F32",
                "__UINT8_TYPE__=unsigned char",
                "__BUILTIN_AVR_ROUNDUK=1",
                "__BUILTIN_AVR_ROUNDUR=1",
                "__UHA_FBIT__=8",
                "__NO_INLINE__=1",
                "__SFRACT_MIN__=(-0.5HR-0.5HR)",
                "__UTQ_FBIT__=128",
                "__FLT_MANT_DIG__=24",
                "__LDBL_DECIMAL_DIG__=9",
                "__VERSION__=\"7.3.0\"",
                "__UINT64_C(c)=c ## ULL",
                "__ULLFRACT_FBIT__=64",
                "__cpp_unicode_characters=200704",
                "__FRACT_EPSILON__=0x1P-15R",
                "__ULACCUM_MIN__=0.0ULK",
                "__UDA_FBIT__=32",
                "__cpp_decltype_auto=201304",
                "__LLACCUM_EPSILON__=0x1P-47LLK",
                "__GCC_ATOMIC_INT_LOCK_FREE=1",
                "__FLT32_MANT_DIG__=24",
                "__BUILTIN_AVR_BITSUHK=1",
                "__BUILTIN_AVR_BITSUHR=1",
                "__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
                "__USFRACT_MIN__=0.0UHR",
                "__BUILTIN_AVR_BITSULK=1",
                "__ULLACCUM_IBIT__=16",
                "__BUILTIN_AVR_BITSULR=1",
                "__UQQ_IBIT__=0",
                "__BUILTIN_AVR_LLRBITS=1",
                "__SCHAR_WIDTH__=8",
                "__BUILTIN_AVR_BITSULLK=1",
                "__BUILTIN_AVR_BITSULLR=1",
                "__INT32_C(c)=c ## L",
                "__DEC64_EPSILON__=1E-15DD",
                "__ORDER_PDP_ENDIAN__=3412",
                "__DEC128_MIN_EXP__=(-6142)",
                "__UHQ_FBIT__=16",
                "__LLACCUM_FBIT__=47",
                "__FLT32_MAX_10_EXP__=38",
                "__BUILTIN_AVR_ROUNDULLK=1",
                "__BUILTIN_AVR_ROUNDULLR=1",
                "__INT_FAST32_TYPE__=long int",
                "__BUILTIN_AVR_HRBITS=1",
                "__UINT_LEAST16_TYPE__=unsigned int",
                "__BUILTIN_AVR_UHRBITS=1",
                "__INT16_MAX__=0x7fff",
                "__SIZE_TYPE__=unsigned int",
                "__UINT64_MAX__=0xffffffffffffffffULL",
                "__UDQ_FBIT__=64",
                "__INT8_TYPE__=signed char",
                "__cpp_digit_separators=201309",
                "__ELF__=1",
                "__ULFRACT_EPSILON__=0x1P-32ULR",
                "__LLFRACT_FBIT__=63",
                "__FLT_RADIX__=2",
                "__INT_LEAST16_TYPE__=int",
                "__BUILTIN_AVR_ABSFX=1",
                "__LDBL_EPSILON__=1.19209290e-7L",
                "__UINTMAX_C(c)=c ## ULL",
                "__INT24_MIN__=(-__INT24_MAX__-1)",
                "__SACCUM_MAX__=0X7FFFP-7HK",
                "__BUILTIN_AVR_ABSHR=1",
                "__SIG_ATOMIC_MAX__=0x7f",
                "__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
                "__cpp_sized_deallocation=201309",
                "__SIZEOF_PTRDIFF_T__=2",
                "__AVR=1",
                "__BUILTIN_AVR_ABSLK=1",
                "__BUILTIN_AVR_ABSLR=1",
                "__LACCUM_EPSILON__=0x1P-31LK",
                "__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
                "__INT_FAST16_MAX__=0x7fff",
                "__UINT_FAST32_MAX__=0xffffffffUL",
                "__UINT_LEAST64_TYPE__=long long unsigned int",
                "__USACCUM_MAX__=0XFFFFP-8UHK",
                "__SFRACT_EPSILON__=0x1P-7HR",
                "__FLT_HAS_QUIET_NAN__=1",
                "__FLT_MAX_10_EXP__=38",
                "__LONG_MAX__=0x7fffffffL",
                "__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
                "__FLT_HAS_INFINITY__=1",
                "__cpp_unicode_literals=200710",
                "__USA_FBIT__=16",
                "__UINT_FAST16_TYPE__=unsigned int",
                "__DEC64_MAX__=9.999999999999999E384DD",
                "__INT_FAST32_WIDTH__=32",
                "__BUILTIN_AVR_RBITS=1",
                "__CHAR16_TYPE__=unsigned int",
                "__PRAGMA_REDEFINE_EXTNAME=1",
                "__SIZE_WIDTH__=16",
                "__INT_LEAST16_MAX__=0x7fff",
                "__DEC64_MANT_DIG__=16",
                "__UINT_LEAST32_MAX__=0xffffffffUL",
                "__SACCUM_FBIT__=7",
                "__FLT32_DENORM_MIN__=1.40129846e-45F32",
                "__GCC_ATOMIC_LONG_LOCK_FREE=1",
                "__SIG_ATOMIC_WIDTH__=8",
                "__INT_LEAST64_TYPE__=long long int",
                "__INT16_TYPE__=int",
                "__INT_LEAST8_TYPE__=signed char",
                "__SQ_FBIT__=31",
                "__DEC32_MAX_EXP__=97",
                "__INT_FAST8_MAX__=0x7f",
                "__INTPTR_MAX__=0x7fff",
                "__QQ_FBIT__=7",
                "__cpp_range_based_for=200907",
                "__UTA_IBIT__=16",
                "__AVR_ERRATA_SKIP__=1",
                "__FLT32_MIN_10_EXP__=(-37)",
                "__LDBL_MANT_DIG__=24",
                "__SFRACT_FBIT__=7",
                "__SACCUM_MIN__=(-0X1P7HK-0X1P7HK)",
                "__DBL_HAS_QUIET_NAN__=1",
                "__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
                "AVR=1",
                "__BUILTIN_AVR_FMULS=1",
                "__cpp_return_type_deduction=201304",
                "__INTPTR_TYPE__=int",
                "__UINT16_TYPE__=unsigned int",
                "__WCHAR_TYPE__=int",
                "__SIZEOF_FLOAT__=4",
                "__AVR__=1",
                "__BUILTIN_AVR_INSERT_BITS=1",
                "__USQ_FBIT__=32",
                "__UINTPTR_MAX__=0xffffU",
                "__INT_FAST64_WIDTH__=64",
                "__DEC64_MIN_EXP__=(-382)",
                "__cpp_decltype=200707",
                "__FLT32_DECIMAL_DIG__=9",
                "__INT_FAST64_MAX__=0x7fffffffffffffffLL",
                "__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
                "__FLT_DIG__=6",
                "__UINT_FAST64_TYPE__=long long unsigned int",
                "__BUILTIN_AVR_BITSHK=1",
                "__BUILTIN_AVR_BITSHR=1",
                "__INT_MAX__=0x7fff",
                "__LACCUM_FBIT__=31",
                "__USACCUM_MIN__=0.0UHK",
                "__UHA_IBIT__=8",
                "__INT64_TYPE__=long long int",
                "__BUILTIN_AVR_BITSLK=1",
                "__BUILTIN_AVR_BITSLR=1",
                "__FLT_MAX_EXP__=128",
                "__UTQ_IBIT__=0",
                "__DBL_MANT_DIG__=24",
                "__cpp_inheriting_constructors=201511",
                "__BUILTIN_AVR_ULLKBITS=1",
                "__INT_LEAST64_MAX__=0x7fffffffffffffffLL",
                "__DEC64_MIN__=1E-383DD",
                "__WINT_TYPE__=int",
                "__UINT_LEAST32_TYPE__=long unsigned int",
                "__SIZEOF_SHORT__=2",
                "__ULLFRACT_IBIT__=0",
                "__LDBL_MIN_EXP__=(-125)",
                "__UDA_IBIT__=32",
                "__WINT_WIDTH__=16",
                "__INT_LEAST8_MAX__=0x7f",
                "__LFRACT_FBIT__=31",
                "__LDBL_MAX_10_EXP__=38",
                "__ATOMIC_RELAXED=0",
                "__DBL_EPSILON__=double(1.19209290e-7L)",
                "__BUILTIN_AVR_BITSUK=1",
                "__BUILTIN_AVR_BITSUR=1",
                "__UINT8_C(c)=c",
                "__INT_LEAST32_TYPE__=long int",
                "__BUILTIN_AVR_URBITS=1",
                "__SIZEOF_WCHAR_T__=2",
                "__LLFRACT_MAX__=0X7FFFFFFFFFFFFFFFP-63LLR",
                "__TQ_FBIT__=127",
                "__INT_FAST8_TYPE__=signed char",
                "__ULLACCUM_EPSILON__=0x1P-48ULLK",
                "__BUILTIN_AVR_ROUNDK=1",
                "__BUILTIN_AVR_ROUNDR=1",
                "__UHQ_IBIT__=0",
                "__LLACCUM_IBIT__=16",
                "__FLT32_EPSILON__=1.19209290e-7F32",
                "__DBL_DECIMAL_DIG__=9",
                "__STDC_UTF_32__=1",
                "__INT_FAST8_WIDTH__=8",
                "__DEC_EVAL_METHOD__=2",
                "__TA_FBIT__=47",
                "__UDQ_IBIT__=0",
                "__ORDER_BIG_ENDIAN__=4321",
                "__cpp_runtime_arrays=198712",
                "__WITH_AVRLIBC__=1",
                "__UINT64_TYPE__=long long unsigned int",
                "__ACCUM_EPSILON__=0x1P-15K",
                "__UINT32_C(c)=c ## UL",
                "__BUILTIN_AVR_COUNTLSUHK=1",
                "__INTMAX_MAX__=0x7fffffffffffffffLL",
                "__cpp_alias_templates=200704",
                "__BUILTIN_AVR_COUNTLSUHR=1",
                "__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
                "__FLT_DENORM_MIN__=1.40129846e-45F",
                "__LLFRACT_IBIT__=0",
                "__INT8_MAX__=0x7f",
                "__LONG_WIDTH__=32",
                "__UINT_FAST32_TYPE__=long unsigned int",
                "__CHAR32_TYPE__=long unsigned int",
                "__BUILTIN_AVR_COUNTLSULK=1",
                "__BUILTIN_AVR_COUNTLSULR=1",
                "__FLT_MAX__=3.40282347e+38F",
                "__cpp_constexpr=201304",
                "__USACCUM_FBIT__=8",
                "__BUILTIN_AVR_COUNTLSFX=1",
                "__INT32_TYPE__=long int",
                "__SIZEOF_DOUBLE__=4",
                "__FLT_MIN_10_EXP__=(-37)",
                "__UFRACT_EPSILON__=0x1P-16UR",
                "__INT_LEAST32_WIDTH__=32",
                "__BUILTIN_AVR_COUNTLSHK=1",
                "__BUILTIN_AVR_COUNTLSHR=1",
                "__INTMAX_TYPE__=long long int",
                "__BUILTIN_AVR_ABSLLK=1",
                "__BUILTIN_AVR_ABSLLR=1",
                "__DEC128_MAX_EXP__=6145",
                "__AVR_HAVE_16BIT_SP__=1",
                "__ATOMIC_CONSUME=1",
                "__GNUC_MINOR__=3",
                "__INT_FAST16_WIDTH__=16",
                "__UINTMAX_MAX__=0xffffffffffffffffULL",
                "__DEC32_MANT_DIG__=7",
                "__HA_FBIT__=7",
                "__BUILTIN_AVR_COUNTLSLK=1",
                "__BUILTIN_AVR_COUNTLSLR=1",
                "__BUILTIN_AVR_CLI=1",
                "__DBL_MAX_10_EXP__=38",
                "__LDBL_DENORM_MIN__=1.40129846e-45L",
                "__INT16_C(c)=c",
                "__cpp_generic_lambdas=201304",
                "__STDC__=1",
                "__PTRDIFF_TYPE__=int",
                "__LLFRACT_MIN__=(-0.5LLR-0.5LLR)",
                "__BUILTIN_AVR_LRBITS=1",
                "__ATOMIC_SEQ_CST=5",
                "__DA_FBIT__=31",
                "__UINT32_TYPE__=long unsigned int",
                "__BUILTIN_AVR_ROUNDLLK=1",
                "__UINTPTR_TYPE__=unsigned int",
                "__BUILTIN_AVR_ROUNDLLR=1",
                "__USA_IBIT__=16",
                "__BUILTIN_AVR_ULRBITS=1",
                "__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
                "__DEC128_MANT_DIG__=34",
                "__LDBL_MIN_10_EXP__=(-37)",
                "__BUILTIN_AVR_COUNTLSUK=1",
                "__BUILTIN_AVR_COUNTLSUR=1",
                "__SIZEOF_LONG_LONG__=8",
                "__ULACCUM_EPSILON__=0x1P-32ULK",
                "__cpp_user_defined_literals=200809",
                "__SACCUM_IBIT__=8",
                "__GCC_ATOMIC_LLONG_LOCK_FREE=1",
                "__LDBL_DIG__=6",
                "__FLT_DECIMAL_DIG__=9",
                "__UINT_FAST16_MAX__=0xffffU",
                "__GCC_ATOMIC_SHORT_LOCK_FREE=1",
                "__BUILTIN_AVR_ABSHK=1",
                "__BUILTIN_AVR_FLASH_SEGMENT=1",
                "__INT_LEAST64_WIDTH__=64",
                "__ULLFRACT_MAX__=0XFFFFFFFFFFFFFFFFP-64ULLR",
                "__UINT_FAST8_TYPE__=unsigned char",
                "__USFRACT_EPSILON__=0x1P-8UHR",
                "__ULACCUM_FBIT__=32",
                "__QQ_IBIT__=0",
                "__cpp_init_captures=201304",
                "__ATOMIC_ACQ_REL=4",
                "__ATOMIC_RELEASE=3",
                "__BUILTIN_AVR_FMUL=1",
                "USBCON"
            ]
        }
    ]
}

Rust on Nano Every

Next up is trying to get Rust to run on the nano every which has a atmega4809. This was a weekend journey and probably could be done faster in the person driving had better skills. I document it here so people can may find this page and learn from the problems I have experienced.

Create Cargo Project

First off let create a new project

cargo new project_mecargo newcargo new project_me project_me

Add HAL (hardware abstraction layer) to project

Add the embedded-hal to project by going to the Cargo.toml and adding embedded-hal as a dependency. It is a generic layer and you will need a chip specific one as well.

[dependencies]
embedded-hal = "0.1.2"

Using cargo build resulted in the following error

error[E0554]: `#![feature]` may not be used on the stable release channel

This is because we cannot use the stable toolchain which is the default. To list the toolchains available you can use.

rustup toolchain list

In my case, because I have already installed other toolchains, the output was

stable-x86_64-unknown-linux-gnu (default)
nightly-x86_64-unknown-linux-gnu
snowgoons

To install the nightly toolchain use the rustup command.

rustup install nightly

We can set this as the default with

rustup default stable-x86_64-unknown-linux-gnu

Now we can run the cargo build and it completes successfully. We can set the toolchain to use in the an override file in the root directory rust-toolchain.toml. You find this in the overrides section of the rustup book. An example is shown below.

[toolchain]
#The name of the toolchain to use. We are using snowgoons as this is
channel = "nightly-x86_64-unknown-linux-gnu"
components = ["rust-src"]

Adding Chip Specific HAL

In the videos by Vers Binarii it mentions finding the hal for an STM32F103C8T6 and guides you to lib.rs to get the board specific hal. Unfortunately this does not exist for the ATMega4809. So from there I made my way back to snowgoons where I first started. He suggested, at least to me, instead of stm32f1xx-hal I should use ruduino for my ATMega4809 (nano every). This gave the error

error: cannot find macro `llvm_asm` in this scope

Googling led me to running the rustup update command

rustup update

Was not hopeful as I assume that I am already at the latest. After the version shown was (rustc 1.71.0-nightly). So I reran the build and...

error[E0635]: unknown feature `llvm_asm`

Looking at this, and not that familiar with rust, I think they have renamed llvm_asm to asm and this appears avr_delay presumably used by ruduino. This went into the too hard basket and I went looking for a different hal. Next up is avr-oxide. Putting in the latest version at the time 0.4.0 ( nothing is version 1.0.0 :grinning: ). So running the build gives new and more fun problems.

   |
22 | compile_error!("A clockspeed feature (\"16MHz\", \"20MHz\") must be enabled for this crate");
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I remember when watching Vers you can enable and disable features. Lets see what we need. We know that the nano every is 20MHz. So lets put that in and the chip which it also spat out on the error

[dependencies.avr-oxide]
version = "0.4.1"
features = ["20MHz","atmega4809"]

No joy just more errors. But we have learned a fair bit about the rust build system

error: ~const can only be applied to `#[const_trait]` traits
--> /home/iwiseman/.cargo/registry/src/index.crates.io-6f17d22bba15001f/avr-oxide-0.4.1/src/oserror.rs:194:22

Next up I found avr-hal. This mentions nano but not nano every. Lets give it a go.

git clone https://github.com/Rahix/avr-hal avr-hal
cd examples/arduino-nano/
cargo build
...
   Compiling avr-device v0.5.1
   Compiling nb v0.1.3
   Compiling embedded-hal v0.2.7
   Compiling atmega-hal v0.1.0 (/home/iwiseman/dev/projects/at4809/avr-hal/mcu/atmega-hal)
   Compiling arduino-hal v0.1.0 (/home/iwiseman/dev/projects/at4809/avr-hal/arduino-hal)
   Compiling arduino-nano-examples v0.0.0 (/home/iwiseman/dev/projects/at4809/avr-hal/examples/arduino-nano)
WARN rustc_codegen_ssa::back::link Linker does not support -no-pie command line option. Retrying without.
WARN rustc_codegen_ssa::back::link Linker does not support -no-pie command line option. Retrying without.
    Finished dev [optimized + debuginfo] target(s) in 22.28s

Built but not running

To run the we do the following

cargo run --bin nano-blink
WARN rustc_codegen_ssa::back::link Linker does not support -no-pie command line option. Retrying without.
    Finished dev [optimized + debuginfo] target(s) in 0.03s
     Running `ravedude nano -cb 57600 /home/iwiseman/dev/projects/at4809/avr-hal/target/avr-atmega328p/debug/nano-blink.elf`
       Board Arduino Nano
Error: no matching serial port found, use -P or set RAVEDUDE_PORT in your environment

So we know how to solve this one, it is looking for the device my nano is on /dev/ttyACMO.

export RAVEDUDE_PORT=/dev/ttyACMO

So lets give it a whirl

WARN rustc_codegen_ssa::back::link Linker does not support -no-pie command line option. Retrying without.
    Finished dev [optimized + debuginfo] target(s) in 0.03s
     Running `ravedude nano -cb 57600 /home/iwiseman/dev/projects/at4809/avr-hal/target/avr-atmega328p/debug/nano-blink.elf`
       Board Arduino Nano
 Programming /home/iwiseman/dev/projects/at4809/avr-hal/target/avr-atmega328p/debug/nano-blink.elf => /dev/ttyACM0
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00

I found that avr-hal is running something called ravedude which appears to be a wrapper for avrdude which is what I noticed the native blink example runs when using vscode and the arduino plugin uses. We are using the same software and we know it works so what is the problem. So lets see which version of avrdude it is using.

which avrdude 
/usr/bin/avrdude

avrdude -v
avrdude: Version 6.3-20171130

Lets see what arduino is using. In my case this was going to home directory and look for a likely hidden folder.

ls -la |grep ".ard"
drwxr-xr-x  6 iwiseman iwiseman     4096 May 13 17:25 .arduino15
drwxrwxr-x  7 iwiseman iwiseman     4096 May 13 17:25 .arduinoIDE

Looking in .arduino15 showed a version of avrdude exists and was 6.3-20171130 so this clearly was not the issue. Getting there I promise. So I looked at he parameters being used with avrdude by making a fake script replacing avrdude

#!/bin/bash 
echo $@ >/tmp/fred.txt

Looking an the output we have. So I change the avr-hal/examples/arduino-nano/.cargo/config.toml to have these

-C/home/iwiseman/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf -v -V -patmega4809 -cjtag2updi -P/dev/ttyACM0 -b115200 -e -D -Uflash:w:/tmp/arduino/sketches/6F5689DFFC2E237B65FDBBAD8847D814/blinkNative.ino.hex:i -Ufuse2:w:0x01:m -Ufuse5:w:0xC9:m -Ufuse8:w:0x00:m {upload.extra_files}

So here is the config.toml. Note I need to change the command to use an elf rather than the hex file. I went to TOML cheat sheet for the multiline command

[build]
target = "../../avr-specs/avr-atmega328p.json"

[target.'cfg(target_arch = "avr")']
#runner = "ravedude nano -cb 57600"
runner = """/home/iwiseman/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude \
          -C /home/iwiseman/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf \
          -v \
          -V \
          -patmega4809 \
          -cjtag2updi \
          -P/dev/ttyACM0 \
          -b115200 \
          -e \
          -D \
          -Uflash:w:./target/avr-atmega328p/debug/nano-blink.elf
          -Ufuse2:w:0x01:m \
          -Ufuse5:w:0xC9:m \
          -Ufuse8:w:0x00:m"""

[unstable]
build-std = ["core"]

This gave the following output and was the final issue to solve.

avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1

I googled avrdude: jtagmkII_getsync() and found this. It appears you need to set the baud rate at 1200 bps briefly before attempting to upload. I am a idiot and know nothing so back to google on how to do this. Googling "avrdude 1200 rust" I find I am back to snowgoons and indeed there is a script showing how to do this. Here it is. Had to change stty -f to stty -F' probably a windows thing and I am on linux

#!/bin/bash

# Gimme the name of a file to load
ELFFILE=${1}

# We need to use the `avrdude` that comes with the Arduino IDE, it seems
# to have some custom changes not in the version we installed from Brew, that
# work with the UPDI-over-USB bootloader on the Arduino Nano Every
AVRDUDE=~/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude
AVRCONF=~/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf

# Chip option fuses
FUSE_OSCCFG=0x82    # 20 MHz
FUSE_SYSCFG0=0xC9   # No CRC, Reset is Reset, don't erase EEPROM
FUSE_BOOTEND=0x00   # Whole Flash is boot

# Device specific flags
PART=atmega4809
PROGRAMMER=jtag2updi
BAUDRATE=115200

# Where to find it
PORT=$(find /dev/cu.usbmodem* | head -n 1)

# We reset the Arduino (and put it into UPDI mode) by opening & closing the
# serial port at 1200baud (this is some kind of 'backdoor' reset process
# built into the USB software that runs on the Nano Every's coprocessor
# for handling USB-to-UPDI.
stty -F "${PORT}" 1200

# Wait for the port to be available again
while [ 1 ]; do
    sleep 0.5
  [ -c "${PORT}" ] && break
done


# NOW, finally, we can actually upload our code
${AVRDUDE} \
   -C ${AVRCONF} \
   -v -p${PART} \
   -c${PROGRAMMER} \
   -P${PORT} -b${BAUDRATE} \
   -e -D \
   -Uflash:w:${ELFFILE}:e \
   -Ufuse2:w:${FUSE_OSCCFG}:m -Ufuse5:w:${FUSE_SYSCFG0}:m -Ufuse8:w:${FUSE_BOOTEND}:m

Working at Last

So putting it all together

cargo install cargo-generate
cargo generate --git https://github.com/Rahix/avr-hal-template.git

Go into your project and here is the blink code

#![no_std]
#![no_main]

use panic_halt as _;

#[arduino_hal::entry]
fn main() -> ! {
    let dp = arduino_hal::Peripherals::take().unwrap();
    let pins = arduino_hal::pins!(dp);

    let mut led = pins.d13.into_output();

    loop {
        led.set_high();
        arduino_hal::delay_ms(500);
        led.set_low();
        arduino_hal::delay_ms(500);
    }
}

Build and upload

cargo build
arduino-nano-every-upload.sh ./target/avr-atmega328p/debug/blink-me.elf

Atmega4809 rust.gif

First PR For years

So looked at how to streamline this and amended Rahix code to support the arduino approach.

git clone https://github.com/bibble235/avr-hal
export RAVEDUDE_PORT=/dev/ttyACM0
export RAVEDUDE_AVRDUDE_ROOT=/home/iwiseman/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17
cd examples/nano-every
cargo run