Program conversion Arduino Pro Mini ATMega328P to ATtiny202

Go To Last Post
32 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I did a program, running well, for Arduino Pro Mini ATMega328P 3.3V 8MHz in Arduino IDE with Wisol SigFox BRKWS01 modem and Holtec voltage regulator HT7533-1 (AREF 3.3V, VCC@328P and  VCC@BRKWS01).

Now I would like to reprogram it for ATtiny202 by using MPLAB X IDE and MPLAB Snap (Part Number: PG164100). Unfortunately I am beginner to MPLAB X IDE and I was unable to reproduce examples "gettin" Getting STARTed AVR Events for ATtiny817 Xplained Mini board with ATtiny202-SSNR (CS8 Compiler) on start.atmel.com

Which pins to use at ATtiny202: USART Pin 2, PA76 (TXT), Pin 3, PA7 (RXD); Pin 6, PA0 (Analog input for voltage measurement) and Pin 5, PA1 (digital output to wake up Wisol modem). Hardware USART communication.

 

Remark: Rename extension of attached file from TXT to INO

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Will your program even fit in a tiny202?

How much flash and ram did it use in a 328?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think it should fit easily by using hardware commands for USART in 202. In a 328 the program use 7 339 bytes and variables are 181 bytes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Arduino 328P working prototype pictures:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Kevil wrote:
I think it should fit easily by using hardware commands for USART in 202. In a 328 the program use 7 339 bytes and variables are 181 bytes.
Go on. How do you fit 7339 bytes of code into a micro with 2048 bytes of flash ??

 

If you've got almost 8K of code you need to be in this part of the picture:

 

Last Edited: Mon. Sep 9, 2019 - 12:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I created the program on Arduino IDE which use SOFTWARE serial i.e. lot of bytes. Note I am experienced ASM x64 programmer in Intel i7. The program for 202 needs to be rewritten with shorter code:

 

  1. Initialize 202 digital pin to HIGH (ready to wake up Wisol modem)
  2. Initialize 202 USART 9600bit/s
  3. Initialize Watchdog timer for 8s and use volatile one uint_16t variable to count 440x (1 hour) and second uint_8t flag variable inside ISR.
  4. Enable 202 Watchdog timer interrupt
  5. Initialize deep sleep 202 & Wisol Modem (HW serial "AT$P=2\r")
  6. When flag variable in the main loop is set to 0xFFh do:

 

  1. Disable Watchdog Timer interrupt
  2. Disable 202 sleep
  3. ADC single conversion
  4. Multiply the result by 100
  5. Store Lo and Hi byte to tmp char buffer
  6. Wake up Wisol modem (digital pin of 202 for 100 ms to LOW, then test if modem is ready (HW serial "AT\r", response "OK")
  7. Send voltage, 2 bytes in tmp char buffer to Wisol ("AT$SF=" + Lo + Hi HEX byte in the tmp char buffer)
  8. Check if send OK
  9. Reset or set again Watchdog Timer
  10. Initialize deep sleep 202 & Wisol Modem (HW serial "AT$P=2\r")
  11. Wait (for the flag variable 0xFF) in the main loop

 

That's all.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Replacing all the obvious Arduino stuff is the first thing to do; the easiest ones are delay() and pinMode().

Then, I would replace the SoftwareSerial class by a dummy class and make Sigfox an instance of this dummy class. Create dummy member functions until there are no compile errors.

Finally, flesh out the dummy functions until the program works with the hardware USART.

 

I think it might fit on a tiny402, on a 202 I have serious doubts.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:
I think it might fit on a tiny402, on a 202 I have serious doubts.
Agree - the Serial.println() support from Arduino probably accounts for a good proportion of the size of the original code. If you can trim that back to simple uart_putc()/uart_puts() and maybe an itoa() or a (non float) sprintf() or something you might get stuff into a 4K chip.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It would help me to know how to configure it at start.atmel.com for ATtiny202. When I add components to ATtiny202: Event System, WDT, ADC and USART the Event System can't set WDT to trigger the event. The Events System shows PORTA, B, C only.

 

Part  of the /utils/main.c code from the example at start.atmel.com how to use HW commands for USART
Category, Getting Started

  • Name: Getting started events ATtiny817 assigment2 RTC USART
  • Description: This application performs RTC interrupt triggering USART string print to Terminal
  • Board: ATtiny817 Xplained Pro

 

When I start to reproduce the example above from scratch by selecting the ATtiny817 Xplained Pro board I am unable to get into Dashboard first black component in the tree "Getting started events ATtiny817 assigment2 RTC USART".

 

const char hello[] = "Hello World!\n";
#define HELLO_LEN 13
volatile uint8_t sendflag = 0;
const char hello[] = "Hello World!\n";
#define HELLO_LEN 13
volatile uint8_t sendflag = 0;
const char hello[] = "Hello World!\n";
#define HELLO_LEN 13
volatile uint8_t sendflag = 0;
const char hello[] = "Hello World!\n";
#define HELLO_LEN 13
volatile uint8_t sendflag = 0;
  
...

const char hello[] = "Hello World!\n";
#define HELLO_LEN 13
volatile uint8_t sendflag = 0;

...

// USART Functions
void usart_put_string(const char str[], const uint8_t STR_LEN)
{
    for (int i = 0; i < STR_LEN; i++) {
        while (!USART_0_tx_empty())
            ;
        USART_0_putc(str[i]);
    }
}

int main(void)
{
    /* Initializes MCU, drivers and middleware */
    atmel_start_init();

    usart_put_string(hello, HELLO_LEN);

    /* Replace with your application code */
    while (1) {
        // usart_put_string(hello, HELLO_LEN);
        if (sendflag) {
            usart_put_string(hello, HELLO_LEN);
            sendflag = 0;
        }
    }
}

 

Any advice?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Exactly how much code do you think you can get into a 2K micro? Or did you buy the one with the TARDIS core ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A few minutes ago I just got ATtiny202 and MPLAB-SNAP Programmer. I will let you know when I get some experience with it ;-).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First program blinking LED has 204 bytes (MPLAB X IDE). I need to test it but I don't know how to connect MPLAB Snap to 202 yet.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


 

Check this file:

 

http://ww1.microchip.com/downloa...

 

 

The 202 is a tiny 0 series, broadly speaking they only require three pins for programming and debugging. That is:

 

- Vdd

- GND

- UPDI

 

from the side of snap, we have the following:

 

Now for the UPDI pin, if you check the previous link you will see that you can use the Pin 4 (PGD) as the UPDI pin. remember that the SNAP does not provide power to your target, hence, you have to power your board externally.

 

PS: check the assembly marking of your SNAP, if its assembly#02-10381-R1 then you might have to do some changes that is to remove the pull-up resistor R48 from the board manually.

 

Regards,

Moe

 

EDIT: From the side of tiny 202, you will also need to Connct the Vdd, GND & UPDI(PA0). you dont need any other external components or pull-up resistors.

 

Last Edited: Wed. Sep 11, 2019 - 08:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kevil wrote:
First program blinking LED has 204 bytes
Fair enough but my 2K comment related to the bit where you said:

Kevil wrote:
I add components to ATtiny202: Event System, WDT, ADC and USART
How big does that Start project build to be?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Many thanks for your help. I will test it and let you know.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Moe123 wrote:
you dont need any other external components or pull-up resistors.

Well you will need a VCC bypass cap, 100nf connected close to the VCC pin!

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NO, you dont. We are not speaking here about the decoupling capacitors (100nF to Vcc to GND ) which obviously is there in almost any AVR MCU. we are speaking about the line itself that is directly connected to the Vcc from SNAP.

 

SO, Jim, please read and then you can comment!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Moe123 wrote:
which obviously is there in almost any AVR MCU

If only that were true! Sorry if I misunderstood the discussion, I'll try to be more careful in the future.

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Although t the MPLAB Snap is recognized by MPLAB X IDE without connecting it to ATtiny202, I am getting error 10121. What's wrong?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

See if this thread is any help: https://www.avrfreaks.net/commen...

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Finally I got MPLAB Snap to work with ATtiny202. Removed R48 resistor from Snap, added 1K resistor between PGD & VDD, re-flashed the Snap by means of MPLAB IDE Hardware Toll Emergency Boot Firmware Recovery (courtesy of microchip expert advice from Chandler, AZ) and lowered the default UPDI speed from 0.5MHz to 0.3MHz. Connection from Snap, pins 4 (PGD), 3 (GND) and 2 (VDD) connected to ATtiny202 pins 6 (UPDI), 8 (GND) and 1 (VDD supplied from external 3.3V HT7533 voltage regulator).

Last Edited: Sat. Sep 14, 2019 - 08:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I generated the simply code for bare ATtiny202 on start.atmel.com, just to set pin 4 as LED0, digital output and set it to High. Than I added two lines to main.c code to toggle LED and delay. Unfortunately the LED0 is not flashing and when I try to debug it the program didn't continue to PORTA_toogle_pin_level(2) command. It looks like the program is looped in atmel_start_init() command. What's wrong?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have a while loop AFTER the led toggle and delay. I'm not sure why you have to figure out your own delay values, why not just use <util/delay.h> so you can use _delay_ms(). You also have a broken breakpoint that will do no good, and its hard telling where you are 'stuck' but I would guess you are simply 'stuck' in the while loop with nothing to do. You can add asm("nop"); in places where you want to break, as it is about the only reliable way to put a breakpoint where you want it.

 

This was done for a tiny416 and takes about 1100 bytes, so a 202 may work ok unless you start adding things like sprintf, etc.-

//ATTiny 416 Xplained Nano
#include <stdint.h>

#include "Port.hpp"
#include "Usart.hpp"
#include "Rtc.hpp"
#include "Slpctrl.hpp"
#include "Adc.hpp"

#define F_CPU 3333333   //reset value for 20M
#include <util/delay.h> //using simple delay
#include <stdlib.h>     //itoa

//led on nano board
PB5_OUTL_t ledpin;
PA0_OUTL_t wakepin;
PA1_ANA_t adcpin;

//usart0 alternate pins, no buffer
Usart< Usart0_Alt, 0 > uart0;
Rtc rtc;
Pit pit;
Adc0 adc;

void shutdown(){
    rtc.clksel( rtc.INT1K );        // clk src = int 1khz
    pit.period( pit. CYC32K );      // /32768 = 32.768sec
    //just need an isr to clear pit flag
    Cpuint::set_func( Cpuint::RTC_PIT,
            [](){ pit.flagclr(); }
    );
    uart0.putstr("AT$P=2\r");       //modem powerdown, takes ~7ms to send
    while( not u.tx_complete() );   //wait until tx done
    pit.irq( true );
    Cpuint::on( true );
    uint8_t count = 110;            // 1H = 3600 / 32.768 = 109.86
    //powerdown for an hour 32sec at a time
    for( ; count--; Slpctrl::sleep( Slpctrl::POWERDOWN ) );
    //an hour has passed
    pit.irq( false );
    Cpuint::on( false );
}

int main() {

    //tx only, don't care what module has to say
    //if no response, nothing we can do about it anyway
    uart0.setupUART( 9600, u.TX_NORMAL );

    for(;;){
        //wakeup modem
        wakepin.on();
        _delay_ms(100);
        wakepin.off();

        ledpin.on();

        //read voltage
        uint16_t v = 0;
        for( uint8_t i = 32; i--; v += adc.adc_val( adcpin ) );
        v /= 32;
        v = v * 1552ul / 1024; // 3.3*4.703*100=1552
        //char buf[8];
        //itoa((uint8_t)v, buf, 16);  //Low byte
        //itoa(v>>8, &buf[2], 16);    //High byte
        //or with simple leading 0 support
        char buf[8] = {'0','0','0','0'}; 
        uint8_t L = v, H = v>>8; 
        itoa(L, buf+(L<16), 16); //Low byte 
        itoa(H, buf+2+(H<16), 16); //High byte

        //send
        uart0.putstr("AT$SF=");
        uart0.putstr(buf);
        uart0.putch('\r');
        //wait until all done before sleep
        //(my putch always clears txc flag before sending)
        while( not uart0.tx_complete() );

        //done
        ledpin.off();
        shutdown();
    }
}

This is my own c++ drivers, but similar c code will be about the same or smaller. Its probably not what you are doing, but I think its close enough to say that a 202 will probably work ok.

 

edit- I would roll my own itoa or similar as you will need leading 0 support, and bringing in sprintf will most likely not fit in a 202.

Last Edited: Sun. Sep 15, 2019 - 01:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's great. Appreciate your help. Note __delay_ms() is not recognized by XC8 AVR compiler so that's why I used __builtin_avr_delay_cycles() which works fine. See link here https://www.microchip.com/forums/m1112167.aspx too.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> __delay_ms() is not recognized by XC8 AVR compiler

 

That's because its _delay_ms() and _delay_us() - only 1 leading underscore. Check out uitil/delay.h 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You could write the whole algorithm described above in AVR assembly language and have it fit in a few hundred bytes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>You could write the whole algorithm described above in AVR assembly language and have it fit in a few hundred bytes.

 

Whether you use 1k/1.5k/0.5k of a 2k part, it makes no difference. If I was bumping up against the 2K, I would simply find a couple spare pennies laying around to get a tiny402 with 4K (1ea qty is another 2 cents). If 4K is not enough, I would go from 8 pin to 14 pin where you can currently get up to 16K (where you will need to find a couple spare dimes).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your advice. <util/delay.h> and _delay_ms(500); is runnig well.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The LED is flashing smiley. But I don't understand that LED is flashing at pin 5 of ATtiny202 and not at pin 4 as defined on start.atmel.com surprise.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AVR assembly would be nice. I am experienced in Intel x64 assembly but not in AVR. Any suggestion where to look for same examples? The new asm project in MTLAB X IDE with newpic_8b_asm_func.s template compiles with errors.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PORTA_toggle_pin_level(2)

 

If they are thinking this is a bitmask, then 2 would be 1<<1 (PA1), instead of 1<<2 (PA2).

Go look at the Atmel Start source code they provided, I imagine they have a bitmask version and a pin version to toggle a pin (or pins). I think I took a look recently, and I think you seem to be using the the right one (_pin_level), but who knows. When I looked, I don't think their function comments were correct (copy/paste errors find their way into everything).

 

There are other options available, but I add this to the execute after build option-

${MP_CC_DIR}/avr-objdump -dhSC ${ImageDir}/${PROJECTNAME}.${IMAGE_TYPE}.elf > list.txt; 

(I use xcx8, but have a toolchain option pointed at the binary folder so I can use c++, so the above path's are not correct for 'normal' xc8)

I always keep this file open, just to gain an understanding of what the compiler is up to. As a side effect you eventually get to understand assembly for the mcu in use.

 

Your time is better served learning to drive the compiler to get it to go in the direction you want using a stock/reliable engine, rather than tinker under the hood of the mcu searching for a few extra horsepower. The driver gets to the destination quicker and more reliably than the tinkerer. In my opinion. I happen to think the better direction is c++ which has some nice advantages with no real downside.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PORTA_toggle_pin_level() is correct. I copied it from Header Files, include, atmel_start_pins.h (generated on start.atmel.com).

 

Maybe I will use code parts generated by start.atmel.com and with modification.

 

I found a nice article with sample code Working with the AVR Assembly language (pdf page 8 at the bottom). I don't know how to modify it and compile in MPLAB X IDE XC8 for ATtiny202.

 

#include "avr/io.h"

.global Serial_Setup
Serial_Setup:

; Configure the parameters of serial interface 0
clr r0
sts UCSR0A, r0
ldi r24, 1<<RXEN0 | 1 <<TXEN0   ; enable Rx & Tx
sts UCSR0B, r24
ldi r24, 1 <<UCSZ00 | 1 <<UCSZ01    ; asynchronous, no parity, 1 stop, 8 bits
sts UBRR0H, r0
ldi r24, 103
sts UBRR0L, r24
ret

.global Print_Hello
Print_Hello:
; load the starting address of the string in the Z pointer
ldi ZL, lo8(the_message)    ; r30
ldi ZH, hi8(the_message)    ; r31
lpm r18, Z+     ; Load the first character of the string in r18

Loop:
lds r17, UCSR0A
sbrs r17, UDRE0 ; test the data buffer if data can be transmitted
rjmp Loop
sts UDR0, r18   ; send data contained in r18
lpm r18, Z+     ; load the next character
tst r18         ; check if 0 – the string ends
brne Loop
ret

the_message:    ; the message itself, followed by LF and CR, and 0
.ascii "Assembly is fun"
.byte 10, 13, 0