ATTiny1627 - Programmer and Debugger - Best practice/available solutions

Hello,

This is my very first post here and I'm relatively new to the MCU hobby (but not to software development).
Around Christmas I started out experimenting with a few Arduino Nanos and created some devices which I want to use permanently and on batteries.
Given both features and chip shortage I quickly stumbled upon the ATTiny1627 and ordered a "couple".
I plan on using Arduino IDE with MegaTinyCore to write the software.

I have questions in regards to programming and debugging the MCU.
So there are two ways of cheaply/conveniently programming the MCU, either using a Nano (jtag2updi), or using a USB to Serial adapter (SerialUPDI).
In regards to debugging, I would love to adhere to the current workflow I have with the Nanos and have a UART-connection to send back data to the computer just like the serial interface of the Nanos allows.

My questions are:

  1. Nano and jtag2updi, or an adapter and SerialUPDI (the MegaTinyCore does seem to favor SerialUPDI but I remember from searching around that there at least used to be some controversy in the past)?
  2. Is there a device or an established and well tested (and supported) schematic and code that does both programming over UPDI and sending data back over UART so I have only one device to program and debug the MCU?

Bonus topic:
I read in the datasheet that (which is supposedly new) the 2 series of the ATTiny MCUs have an alternate Reset pin which supposedly has some advantages. I'm a bit confused on how the UPDI pin behaves in that regard. According to the datasheet the UPDI pin is both the UPDI pin and the default reset pin. Is that true and how would I implement it to function as both? I also read somewhere that the UPDI pin must be interfaced with 12V (for specific purposes I don't remember). Can someone fill me in on that?

Thank you for your time and answers!

You have incorrectly identified the "two ways." Should be:

  1. Upload using the UPDI debug/upload protocol, on the ATtiny's UPDI pin. This requires a UPDI programmer of some kind. (JTAG2UPDI and SerialUPDI are two examples of UPDI programmers.)
  2. Upload using the bootloader, with a (regular) serial port connected to (one of) the ATtiny's UART ports. This is the same process that is typical on Nano and etc, and of course it requires that you have already uploaded a bootloader using some sort of UPDI programmer. Since the bootloader uses a standard UART port, it can be used for Serial.xx() communications after a sketch is uploaded (just like a Nano.)

If you have a USB/Serial Adapter already, you can easily convert it to a SerialUPDI programmer for the purpose of burning the bootloader, and then move the connections to the UART pins for "normal operation." There are a couple of proposals for how to do this switching "automatically" or at least "semi-automatically", so that you can use the same USB/Serial device for both UPDI and UART communications, but ... they're a bit inelegant, IMO.

According to the datasheet the UPDI pin is both the UPDI pin and the default reset pin. Is that true and how would I implement it to function as both? I also read somewhere that the UPDI pin must be interfaced with 12V (for specific purposes I don't remember).

There is a fuse (RSTPINCFG in System Config 0) that controls the function of the PA0 pin. It can be either GPIO (PA0), RESET, UPDI, or (theoretically) UPDI with an alternate RESET pin. There are consequences:
I1. f the pin is set to be anything other than UPDI, you will need a UPDI programmer that is capable of that "12V HV UPDI programming" to access the chip with UPDI for programming or debugging. Such programmers are pretty rare, so it's usually recommended that you leave the pin as UPDI (which can be a bit painful on the low pin count chips...)
2. If there is no RESET functionality, the "auto-reset and upload" function of the IDE won't work, and you'll have to power-cycle your board before each upload to enter the bootloader (or do something in the sketch.)
3. The 14pin varieties of the Tiny2 series don't have the alternate reset pin.

1 Like

I built such a programmer for my ATtiny1614 experiments and it works for me and I find it useful for doing the development on the target device, which you may not want cluttered up with a boot loader with the possible attendant recovery with a high voltage programmer if you decide to assign a reset pin etc.

Having said all that, it is often better to consider doing the bulk of the development on something bigger and more convenient to use then, in the final stage of testing, migrate the development to the target device. The newer series AVR chips with unified peripherals make this approach a relatively safe option without too many nasty surprises.

Anyway, I wanted something which I could also power projects at 3.3v/5v depending on what external peripherals were attached and could tolerate. Most of the USB/UART adapters can provide a max of around 50mA as 3.3v.
It is here: Yet Another UPDI Programmer . It is "semi-automatic" because you flip a switch/jumper to change its mode from/to a UPDI programmer. That is not nice (or "inelegant" as @westfw put it) but would require considerable resources to improve.

Is it supported ? Well, there is anyway not much to support. You may anyway have to experiment with resistor values/diodes to get the basic SerialUPDI working and, in the worst case, depending on what you use as a USB/UART adapter, remove LEDs.

1 Like

Hello,

First of all thank you for your responses.

I completely forgot about optiboot. I remember setting up the IDE to get a broad overview and after installing MegaTinyCore just moving on and digging through the datasheet and working on designs already.
So my understanding thanks to you westfw and reading through optiboot's wiki is that I need two serial adapters. One to do the initial flash/burning of the bootloader using udpi, and one that interfaces with the bootloader using uart so that I can now send debug messages using the known Serial-library and can flash firmware over that as well.
I am a bit confused about what settings to use for both of these requirements, as I actually need to use the pins used for UART0 for my project and would like to move UART to UART1 in that case.
I saw on some other post that there is a Serial.swap() function that does this for me inside my program, but I'm wondering how to burn the bootloader so that it uses UART1 for flashing the firmware (and I assume that would also make a Serial.swap() call moot?).
In the boards manager I can select my MCU with the optiboot option and without.
I would assume that I would have to use the option without at first to burn the bootloader since then the menu also/still has the "burn bootloader" option listed. But in that case I don't see a "UART for bootloader" option listed, which means I would end up with UART0 for the bootloader.
I feel like the "burn bootloader" option when optiboot is not chosen in the boards manager is just a remnant the arduino ide has by default, and that I should immediately pick the "w optiboot" option, set the "UART for bootloader", set the programmer, and then use "burn bootloader", is that correct?

Furthermore, I am still confused about the reset pin. I understand that there is a fuse to control the setting of that pin, and that if you don't set it to anything with UPDI, then the 12V programming sets in.
What confuses me is that in the datasheet this pin is by default both the UPDI and reset pin. Can this be explained with settings I see in the arduino ide ("updi, optiboot for 8 sec. after power on & reset")? Does this mean the pin by default is updi in the beginning for a predefined amount of time (or when it is pulled to a specific level upon power up), then the bootloader takes over, and then it functions as a reset pin? I'm also confused about the 8 seconds, or rather, what they mean specifically, since it seems different from the "startup time" one can configure?
Given that my assumption is somewhat correct, and the pin is UPDI in the beginning, and then has reset functionality, what would a good hardware implementation look like? I see the Reset pin according to the datasheet wants a extra 100nf capacitor (unless that happens to be the one already used for the power up pin), and a 330Ohm debouncing(?) resistor. However I have seen a report of this wiring causing issues with UPDI functionality which I conveniently now cannot find in between my pile of bookmarks. The datasheet of the 1627 (I managed to screw up, and just now realized I kept writing 1624 even though I have the 1627) just shows the two capacitors for the power supply and shows to just wire up UPDI directly (for programming).
Oh, and in accordance to your mentioning of the pin count and alternate reset pin, I have the chip in the VQFN-24 package, so I should have an alternate reset pin.

Oh, and also, I'm a bit unsure about the correct modification of a UART adapter. The wiki lists multiple options, one using a diode, one a resistor. I don't have schottky diodes at hand, and it would influence where I place my order, should I have both resistors and diodes at hand because my mileage with a just resistor solution could vary and I might have to use a diode?

And another question. How does the flashing actually work in regards to powering on the device?
Does the serial adapter power cycle the device in the beginning of the flashing, or do I have to do that before and then hurry up in a predefined(?) amount of time and start the flashing process, or does it not matter at all (for example with optiboot and it always listens for a specific data sequence and then starts flashing)?

In regards to your expertise and solution 6v6gt:
I was under the (wrong) assumption that I could not use serial to flash the MCU due to my misinformation and insufficient knowledge about optiboot. Given that I apparently only need to flash the MCU using UPDI once and then can resort to a different UART adapter that serves as both my serial debugging output as well as my flashing device, for my workflow it seems somewhat moot to have a combined device now. But I'll keep that in mind if actually doing it this way seems to be a bit bothersome and I would end up preferring a solution of a 2in1 device.

No need for a powercycle before programming. The UPDI pin will detect the "fairly exotic combination of signals" to know that you want to program and start the programming sequence.

I find it most practical to leave two adapters connected. One serial adapter with just a diode and another one for serial debugging. Though debugging with a blinking led is what I do most. When programming 2K parts I hardly have space to add some serial debugging code.

1 Like

Thank you for your reply.

And what is the workflow when I am done flashing optiboot over UPDI and want to flash over UART? Is powercycling needed? And if so what timeframe do I have from cycling to flashing? Is that the configurable time in "UPDI/Reset Pin and Optiboot Entry"?

Can't help you there. I have honestly never used the bootloader on these parts. I find it very convenient to only breakout the UPDI pin to an empty solder pad, so I can update firmware later by just soldering one wire to the pad (or use one springloaded pogo pin, that is easy to keep connected by hand)

1 Like

I'm curious how you debug your code then? This would not be an option for me.

I leave the UPDI "programmer" always attached and upload using that. It is fast when using "turbo" speed and I never had a failure.

I do not program 2K chips and always have a little spare memory. I connect an I2C LCD screen and use that for debugging.

1 Like

If it is something simple to debug, like checking if an ISR gets triggered I hook up a led and/or my frequency counter to a pin and toggle it in the ISR. So I can read if, and how often the ISR gets triggered.

If I need more debugging info (like a measured value) I usually add a small UART routine just using the TX or TX* pin to send debugging info.

Below example (adds around 340 bytes) I use for debugging on the Attiny412. It can print a value or a few words.

// example ATtiny412 pins
//                                     _____
//                             VDD   1|*    |8  GND
//       (TXD) (DAC) (AIN6) PA6  0   2|     |7  4~  PA3 (AIN3)(SCK)(EXTCLK)
//       (RXD)       (AIN7) PA7  1   3|     |6  5   PA0 (nRESET/UPDI)
// (MOSI)(TXD*)(SDA) (AIN1) PA1  2   4|_____|5  3   PA2 (AIN2)(MISO)(RXD*)(SCL)
//
//
// If using another part than Attiny412 you may need to define other pins for TXD and TXD* !

#include <util/delay.h> 
//#define USE_ALTERNATE_TXD  //  uncomment if you want to use the alternate TXD* / RXD* pins

int main(void) {
  // reconfigure CPU clock prescaler
  CCP = CCP_IOREG_gc;    // enable write to protected IO registers (timed sequence)
  CLKCTRL_MCLKCTRLB = 0; // turn off prescaler (and the default factor 6 division)
  USART_init(9600);      //Call the USART initialization code and choose ( baudrate )

  char printbuffer[7];   //The ASCII of the integer will be stored in this char array
  const static uint8_t Sometext[] = " and counting !\r\n"; // A string array with some fixed text

  while (1) {      //Infinite loop
    int8_t a = a + 1; // increasing value that will be printed
    itoa(a, printbuffer, 10);    //(integer, yourBuffer, base)
    USART_putstring(printbuffer); // print the 
    USART_putstring(Sometext);
    _delay_ms(200);          
  }
}

void USART_init(uint16_t BAUDRATE) {
  USART0_BAUD = (F_CPU * 64 / (BAUDRATE * 16UL));
#ifdef USE_ALTERNATE_TXD
  PORTMUX_CTRLB = PORTMUX_USART0_bm; // activate alternate RXD* / TXD* pins
  VPORTA_DIR |= PIN1_bm;   // set pin PA1 as output
#else
  VPORTA_DIR |= PIN6_bm;   // set pin PA6 as output
#endif
  USART0_CTRLB |= USART_TXEN_bm ; //enable tx only
}

void USART_send(unsigned char data) {
  while (!(USART0_STATUS & USART_DREIF_bm));
  USART0_TXDATAL = data;
}

void USART_putstring(char* StringPtr) {
  while (*StringPtr != 0x00) {
    USART_send(*StringPtr);
    StringPtr++;
  }
}
1 Like

Oh, wow, I'm incredibly sorry.
Reading the manual of MegaTinyCore again, I realized that in arduino ide, again, I garbled up a digit and selected 1617 instead of 1627. Now the alternate reset option shows.
I also read up on autoreset.
Just to clarify, the manual says "any diode will do". Is a BAT43 okay?

Other than that, no questions.
I'm sorry for missing some of the information in the readmes, and misunderstanding some more.
I actually found an incorrect link in MegaTinyCore's readme and will do a PR to fix this.

Thank you all!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.