PMD-85 colorAce 2024



I started work or play with new Microchip AVR devices: ATMega4809-PF in DIL40 package and AVR128DB28.

ATMega4809-PF is product of post-2016 merge of Atmel with Microchip company.

The ATMega4809-PF is a new (and the only new) single-chip AVR microprocessor in a DIL40 package. Other new processors are SMT versions, e.g., TQFP.
A quick look at the datasheets, which have added a few hundred pages, gives a glimpse of the new product from the megaAVR 0 series family. Among the main novelties, I consider 48 KB flash and 6 KB RAM, while the flash content is mirrored in the address space of 64 KB RAM due to better addressing, not only through LPM instructions. Hence, the exotic 48KB and not 64KB. The RAM size is not a power of two, for example, 8KB.
* I consider the integration of the internal 16/20MHz oscillator a big plus, meaning no external piezo crystal or capacitors are needed. We save outlets and the price of the board.
* Another big plus is doubling the speed of CBI and SBI—setting and resetting the bit of a specific port. This was an early fix for some internal AVR architecture bug; after all, changing one bit in an 8-bit register can't take as long as multiplying 8-bit numbers.
* acceleration of PUSH and ST instructions (writing to stack and writing to RAM)

* Among the main disadvantages, I consider only 33 GPIO ports, of which only 2 are 8-bit PORTA and PORTD. PORTE is 4-bit, PORTC is 6-bit, PORTF is 7-bit, and the Atmega8515 still had up to 4 8-bit ports + 3-bit PORTE. GND has taken its toll, and VDD is on several pins around EMC, AVDD, and a separate UPDI pin. With the addition of the UPDI programming interface, you need to purchase another programmer or make a jtag2updi from an Atmega328 arduino like I did. The only positive is that you connect UPDI via 3 pins; SPI ISP was up to 6 pins. So usable digital GPIOs are 8+8+6+4+7=33 bits. Two pins are the power supply. The 40-35=5 pins of the DIL package cannot be used.
How can we increase, e.g., PORTC to 8-bit? I think it can be done by mapping PC6 and PC7 bits that actually exist via CCL (custom configurable logic) to other ports/pins, for example, PF0=PC6 and PF1=PC7. So we get a full-fledged 8-bit port C. When we have 3 8-bit ports, that's good for us because even the 8080 processor had a 16-bit address and an 8-bit data bus. We'll be fine...
* The advantage of Microchip's new approach is creating a CPU line with scaled FLASH 8,16,32, 48 KB, and 28,32,40,48 pin cases. Even this already gives 16 options + different cases for SMT TQFP, MFR, QFN, and SSOP. This provides realistic dozens of combinations * If you choose an unsuitable CPU, expect 52 weeks of storage. I decided for the ATmega4809-PF, the only one in the DIL40 case. Inside is the same chip as for the TQFP 48 case; only 8 pins are not connected. It's pretty logical and beautiful. Attention—the TQFP 48 case is cheaper than the DIL40. Here, I hesitated whether to go classic (few expensive pins) or SMT (future). * The increased complexity of the ATMega4809 microcomputer is confusing. Golden ATmega. There are so many IO registers, and most of them are memory mapped - MMIO. But there is an effort to clean up. For example, when there are 6 USARTs, each is the same. They differ only in the base address. Each one then has its own 16 registers. * Assembly language programming is no longer for the masses; it's not in the manual, but we'll try.

I created an LED blinker (LED blink or flasher) as a first project to test the new mega4809 processor. Of course, it is connected to PORTE0 through a resistor. I couldn't find a sample program in the assembler anywhere for such a simple thing, so I created it.


ATmega4809 blink LED, UPDI programmer in action


AVRA   Ver. 1.4.2 pmd.asm Fri Apr 12 09:55:28 2024


         
         	; mega4809 test
         	; BLINK LED DIODE connected to PORTE0 (pin 19 on DIL40 ATMEGA4809-PF)	
         	; pure assembly language
         	; (c) wurmi 2024
                  	
         	; for program device use command: avrdude -c jtag2updi -p m4809 -P /dev/ttyUSB0 -U flash:w:pmd.hex
         	
          		.device		ATmega4809
         		
          		.def	_zero		=	r10	
                .def	_255		=	r22
         	
          		.equ	xDDRE		=	0x0480+0
          		.equ	xPORTE		=	0x0480+0x04
         		
          		.equ	DDRE		=	0x10+0
          		.equ	PORTE		=	0x10+1
          		.equ	PINE		=	0x10+2
         		
         		
         		; CPU is base 0x0030
          		.equ	CPU 	=	0x0030
          		.equ	SPL		=	CPU+0x0D
          		.equ	SPH		=	CPU+0x0D+1
         		
          		.equ	CPU_CCP =	CPU+4
         				
          		.equ	RAMEND	=	0x3FFF
         		  
          		.def	XH	= r27
                  .def	XL	= r26
                  .def	YH	= r29
                  .def	YL	= r28
                  .def	ZH	= r31
                  .def	ZL	= r30
                   
                 ; base of CLKCTRL is 0x0060
                  .equ	CLKCTRL= 0x60
                 
                  .equ 	MCLKCTRLB	=	CLKCTRL + 0x01 
         		
         		; PORTE0 is LED diode
         	
          		.cseg
C:000000 24aa      		clr		_zero
C:000001 ef6f      		ldi		_255,0xff
         		
C:000002 ef0f      		ldi		r16, low(RAMEND)               	
C:000003 e31f      		ldi		r17, high(RAMEND)               	
C:000004 bf0d      		out	   	SPL,r16
C:000005 bf1e      		out		SPH,r17				; set STACK POINTER 
         		
C:000006 ed08      		ldi		r16,0xD8			; magic unlock
C:000007 bf04      		out		CPU_CCP, r16
C:000008 92a0 0061 		sts		MCLKCTRLB, _zero	; disable prescaller /6 -> run at full 16/20 MHZ
         		
C:00000a bb60      		out		DDRE, _255			; whole PORTE to output
         
          main:		
         		
C:00000b d004      		rcall	delay	
C:00000c 9888      		cbi		PORTE,0			; output 0 to PORTE0; or set whole PORTE to zeroes: out		PORTE, _zero
         		
         		
C:00000d d002      		rcall	delay
C:00000e 9a88      		sbi		PORTE,0			; output 1 to PORTE0;  or set whole PORTE to ones: out		PORTE, _255
         		
C:00000f cffb      		rjmp	main			; forever blinking
         		
          delay:	
C:000010 e4e2      		ldi		ZL,66
          de1:
C:000011 d003      		rcall	delay_ffff			; subroutine call
C:000012 95ea      		dec		ZL
C:000013 f7e9      		brne	de1
C:000014 9508      		ret
         		
          delay_ffff:
C:000015 efaf      		ldi		XL,255
          de3:		
C:000016 efbf      		ldi		XH,255
          de2:
C:000017 95ba      		dec		XH
C:000018 f7f1      		brne	de2
C:000019 95aa      		dec		XL
C:00001a f7d9      		brne	de3
         		
C:00001b 9508      		ret
         		
         			
         		
         		
Used memory blocks:
   code      :  Start = 0x0000, End = 0x001B, Length = 0x001C (28 words), Overlap=N


Segment usage:
   Code      :        28 words (56 bytes)
   Data      :         0 bytes
   EEPROM    :         0 bytes

Assembly completed with no errors.