Ftdi upload fails with error : (22, 'Invalid argument')

TBH I am little unclear what the “invalid argument” could be.
The configuration is

[env:pro16MHzatmega328]
platform = atmelavr
board = pro16MHzatmega328
framework = arduino
;debug_tool = ftdi
upload_protocol = ftdi
;upload_speed = 115200

Here is the log of the failed upload.

$ pio run -t upload
Processing pro16MHzatmega328 (platform: atmelavr; board: pro16MHzatmega328; framework: arduino)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/pro16MHzatmega328.html
PLATFORM: Atmel AVR (3.4.0) > Arduino Pro or Pro Mini ATmega328 (5V, 16 MHz)
HARDWARE: ATMEGA328P 16MHz, 2KB RAM, 30KB Flash
DEBUG: Current (avr-stub) On-board (avr-stub, simavr)
PACKAGES: 
 - framework-arduino-avr 5.1.0 
 - tool-avrdude 1.60300.200527 (6.3.0) 
 - toolchain-atmelavr 1.70300.191015 (7.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 5 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Checking size .pio/build/pro16MHzatmega328/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   0.4% (used 9 bytes from 2048 bytes)
Flash: [          ]   3.0% (used 924 bytes from 30720 bytes)
Configuring upload protocol...
AVAILABLE: ftdi
CURRENT: upload_protocol = ftdi
Looking for upload port...
Auto-detected: /dev/cu.usbserial-00000000
*** [upload] error : (22, 'Invalid argument')
Traceback (most recent call last):
  File "/Users/tcurdt/.platformio/packages/tool-scons/scons-local-4.3.0/SCons/Action.py", line 1279, in execute
    result = self.execfunction(target=target, source=rsources, env=env)
  File "/Users/tcurdt/.platformio/platforms/atmelavr/builder/main.py", line 80, in BeforeUpload
    env.FlushSerialBuffer("$UPLOAD_PORT")
  File "/Users/tcurdt/.platformio/packages/tool-scons/scons-local-4.3.0/SCons/Util.py", line 742, in __call__
    return self.method(*nargs, **kwargs)
  File "/opt/homebrew/Cellar/platformio/5.2.5/libexec/lib/python3.9/site-packages/platformio/builder/tools/pioupload.py", line 36, in FlushSerialBuffer
    s = Serial(env.subst(port))
  File "/opt/homebrew/Cellar/platformio/5.2.5/libexec/lib/python3.9/site-packages/serial/serialutil.py", line 244, in __init__
    self.open()
  File "/opt/homebrew/Cellar/platformio/5.2.5/libexec/lib/python3.9/site-packages/serial/serialposix.py", line 332, in open
    self._reconfigure_port(force_update=True)
  File "/opt/homebrew/Cellar/platformio/5.2.5/libexec/lib/python3.9/site-packages/serial/serialposix.py", line 517, in _reconfigure_port
    termios.tcsetattr(
termios.error: (22, 'Invalid argument')

What’s going on?

Do you want to upload via the regular serial just like the standard in the Arduino IDE? Then you should remove the upload_protocol = ...

2 Likes

I guess less is more. That worked!
How come pio doesn’t need to know it is via ftdi?

I am a little surprise - but a happy camper.
Thanks!

Hm. Maybe I spoke too soon.

CURRENT: upload_protocol = arduino
BeforeUpload(["upload"], [".pio/build/pro16MHzatmega328/firmware.hex"])
Auto-detected: /dev/cu.usbserial-210
avrdude -v -p atmega328p -C /Users/tcurdt/.platformio/packages/tool-avrdude/avrdude.conf -c arduino -b 57600 -D -P /dev/cu.usbserial-210 -U flash:w:.pio/build/pro16MHzatmega328/firmware.hex:i

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Users/tcurdt/.platformio/packages/tool-avrdude/avrdude.conf"
         User configuration file is "/Users/tcurdt/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbserial-210
         Using Programmer              : arduino
         Overriding Baud Rate          : 57600
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
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00

avrdude done.  Thank you.

RX,TX,GND,VCC should be enough, right?

DTR and reset must be connected in a special way. See first “unit test” in programming an arduino mini pro | ramin assadollahi and auto reset an Arduino using ftdi - DTR signal stays low and needs to go high after 1-50ms - Electrical Engineering Stack Exchange. Is a bootloader (Optiboot) already burned on your chip? Without it you can’t upload via serial.

1 Like

Not all my FTDIs have a DTR. But I can switch to one that does.
I guess if the FTDI does not have a DTR I’d need the workaround with the capacitor?

As for the bootloader - no idea. Ideally I would like to learn to flash that, too.
Just not sure how with the Pro Mini. How would one connect a usbtinyISP?

No if you have a regular Pro Mini then that already has the needed cap + resistor.

Connect a FTDI programmer that exposes DTR like that. The board is actually made so that you can just connect an FTDI which has male header pins solders onto it into the Pro Mini (even without soldered headers).

Interesting! I have only now realised I have two different boards.

Board1
GRN
TXD
RXD
VCC
GND
BLK

Which the exact opposite of the diagram. But rotating the FTDI works.

That’s the board I had my Eureka moment with above. All is good here.

I didn’t immediately noticed the next board was different.

This (to me) suggests a connection to the FTDI as such:

Board2     FTDI
GND        GND
GND        CTS
VCC        VCC
RXD        TXD
TXD        RXD
DTR        DTR

but that still gives:

CURRENT: upload_protocol = arduino
BeforeUpload(["upload"], [".pio/build/pro16MHzatmega328/firmware.hex"])
Auto-detected: /dev/cu.usbserial-00000000
avrdude -v -p atmega328p -C /Users/tcurdt/.platformio/packages/tool-avrdude/avrdude.conf -c arduino -b 57600 -D -P /dev/cu.usbserial-00000000 -U flash:w:.pio/build/pro16MHzatmega328/firmware.hex:i

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Users/tcurdt/.platformio/packages/tool-avrdude/avrdude.conf"
         User configuration file is "/Users/tcurdt/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbserial-00000000
         Using Programmer              : arduino
         Overriding Baud Rate          : 57600
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
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00

avrdude done.  Thank you.

*** [upload] Error 1

This looks good. CTS in an input on the FTDI’s side, so it just receives GND there but shouldn’t try to drive it.

Does the power LED on the bottom right corner of the board light up when you press then FTDI into it as shown? Maybe a bad connection? Or, a missing bootloader, or worst case a blown chip.

The LED briefly lights up when connected.
And when trying an upload it also seems to light up.

I tested all the 6 boards I have of that type. They all show a similar behaviour.
So I am sceptical on the blown chip.

Missing bootloader could totally be. Just not sure how to flash it on these boards.
Is it possible with pio?

Usually with Pro Mini the bootloader is preflashed to save the user the trouble… You can use PlatformIO or the Arduino IDE or the commandline to flash the bootloader. However, burning the bootloader must be done via the SPI connections with an ISP-capable programmer (USBASP, TinyISP) or an Arduino (Uno) with the ArduinoAsAISP sketch. This is detailed in Pro-Mini-Klone: Bootloader flashen | Hausautomation mit Arduino.

I got this USBtinyISP

and will try that tomorrow.

I assume programming would be done with avrdude?
Could I use the one that comes with pio somehow?

Thanks for all the help!

Yes, pick the code for the USBtinyISP at Atmel AVR — PlatformIO v6.1 documentation, which should just be adding upload_protocol = usbtiny.

Then as the docs say, , you can then e.g. open a CLI and execute pio run -t bootloader (or additionally with -v to see more output). This will push the bootloader as defined in the board to the board.

On step forth one step back.
I managed to successfully upload the bootloader with

pio run -v -t bootloader

using

[env:pro16MHzatmega328]
platform = atmelavr
board = pro16MHzatmega328
framework = arduino
upload_protocol = usbtiny

It seems like it’s even running a blink program now.

Afterwards I tried the upload via FTDI.

[env:pro16MHzatmega328]
platform = atmelavr
board = pro16MHzatmega328
framework = arduino

and

pio run -v -t upload

but that still fails to upload.

Any further ideas?

Ah if you’ve uploaded another program to the chip after burning the bootloader, that erased the bootloader again. Uploading with a programmer takes over the whole programming space.

Can you try to burn the bootlaoder and directly after that switch to FTDI based programming? Or is that what you’re already doing.

I’ve uploaded the bootloader via ISP and unless I was mistaken the blink program was already running afterwards. My assumption: It just wrote the bootloader and the blink was already in the program space.

I then switched to a FTDI upload and tried that.
After flashing a couple of the boards I have

2 boards where ISP flashing and then FTDI flashing works
2 boards where ISP flashing worked, but then FTDI flashing still fails

…and I am surprised why there is a difference between the boards that should be from the same batch.

Do both these boards have a crystal on them saying 16.000 or 8.000?

Uh! Good thought.

Turns out the ones working seem to say “Am” (?) and the ones not working “8.0”.

But if these have a 8 MHz crystal, your config

Is wrong for those. Try using pro8MHzatmega328 with them.

(You can create a second environment within your platformio.ini and use pio run -e pro8MHzatmega328 -t bootloader -v etc.)

1 Like

Yeah - I just totally didn’t expect the crystal to be different.
They were all bought in the same batch. Never trust.

So “Am” means 16MhZ?

Just switching to pro8MHzatmega328 didn’t allow for a FTDI upload - but after reflashing the bootloader with the correct board all seems to be working OK now.

Thanks a ton!

1 Like