; File: updi-test-tn1614\main.asm ; Device: ATtiny1614 ; Created: 09.06.2024 21:52:27 ; Version: 2024-06-23 ; Author: Johannes Fechner #define fkHz 20000 .nolist .include .include "macros.asm" .list ; == Hardware definitions == ; === CPU clock frequency === .equ F_CPU = 20_000_000 ; Hz (internal HF oscillator w/o prescaling). ; === Hardware connections === ; USART0.TxD output: .equ TXD_VDIR = VPORTB_DIR .equ TXD_bp = 2 ; Target UPDI (connected via 1kOhm "anxiety" resistor to UPDI of target device): .equ TARGET_UPDI_INTFLAGS = PORTA_INTFLAGS .equ TARGET_UPDI_PINCTRL = PORTA_PIN1CTRL .equ TARGET_UPDI_PORT_VECT = PORTA_PORT_vect .equ TARGET_UPDI_VDIR = VPORTA_DIR .equ TARGET_UPDI_VIN = VPORTA_IN .equ TARGET_UPDI_VOUT = VPORTA_OUT .equ TARGET_UPDI_bp = 1 ; PA1. ; Target UPDI Rx LED: .equ LED_UPDI_RX_VDIR = VPORTA_DIR .equ LED_UPDI_RX_VIN = VPORTA_IN .equ LED_UPDI_RX_VOUT = VPORTA_OUT .equ LED_UPDI_RX_bp = 2 ; PA2. ; Target UPDI Tx LED: .equ LED_UPDI_TX_VDIR = VPORTA_DIR .equ LED_UPDI_TX_VOUT = VPORTA_OUT .equ LED_UPDI_TX_bp = 3 ; PA3. ; == PC UART definitions == .equ UART_BPS = 115_200 ; bits/s ; == UPDI protocol definitions == .equ UPDI_BPS = 50_000 ; UPDI UART baud rate in bits/s. .equ UPDI_UART_BUFLEN = 16 ; UPDI UART tx/rx buffer length in bytes. ; == Register name definitions == .def zero = r2 ; Contains always 0x00. ; === Temporary registers === .def tmp0 = r16 .def tmp1 = r17 .def tmp2 = r18 .def tmp3 = r19 .def tmpL = r24 .def tmpH = r25 ; === Main registers === .def updiFlags = r3 ; UPDI status bits and flags. .equ UPDI_FLAGS_BUSY_bp = 0 ; UPDI transmission or reception in progress. .equ UPDI_FLAGS_TXC_bp = 1 ; UPDI transmission complete. .equ UPDI_FLAGS_RXC_bp = 2 ; UPDI Frame Received flag. .equ UPDI_FLAGS_TIMEOUT_bp = 3 ; Timeout occurred while waiting for reception. .equ UPDI_FLAGS_BUFOVF_bp = 4 ; Buffer overflow while receiving. ; == RAM usage == .dseg .org SRAM_START updiUartBitCntr_ram: .byte 1 ; == 0: during start bit. ; == 1: during data LSb. ; ... ; == 8: during data MSb. ; == 9: during (even) parity bit. ; ==10: during 1st stop bit. ; ==11: during 2nd stop bit. updiUartBitMask_ram: .byte 1 updiUartDataBuf_ram: .byte UPDI_UART_BUFLEN updiUartDataCount_ram: .byte 1 updiUartDataIndex_ram: .byte 1 updiUartParityCntr_ram: .byte 1 updiUartTimeoutCntr_ram: .byte 1 writeFuseAddrL_ram: .byte 1 writeFuseAddrH_ram: .byte 1 writeFuseData_ram: .byte 1 .cseg .org 0 rjmp reset ; == Interrupt vectors == .org TARGET_UPDI_PORT_VECT rjmp updi_fallingEdgeIsr .org TCA0_OVF_vect rjmp updi_timerIsr ; == Zero-terminated strings == .org INT_VECTORS_SIZE szMenu: .db "(1) Read SIB", '\r', '\n',\ "(2) Read UPDI register", '\r', '\n',\ "(3) Read byte from UPDI address space", '\r', '\n',\ "(4) Chip erase", '\r', '\n',\ "(5) Write fuse byte", '\r', '\n', 0, 0 szAddress: .db "Address: ", 0 szData: .db " Data: ", 0 szLdcs: .db "LDCS returned: ", 0 szLds: .db "LDS returned: ", 0, 0 szConfirm: .db " Confirm (y/n): ", 0, 0 szEnteringCEK: .db "Entering Chip Erase key...", '\r', '\n', 0, 0 szEnteringNVMPK: .db "Entering NVM Programming key...", '\r', '\n', 0 szAsiKeyStatus: .db "ASI KEY STATUS: ", 0, 0 szReset: .db "Issuing System Reset...", '\r', '\n', 0 szAsiSysStatus: .db "ASI SYS STATUS: ", 0, 0 szNvmctrlStatus: .db "NVMCTRL_STATUS: ", 0, 0 szNvmVersion: .db "NVM version number: ", 0, 0 szSendingSts0: .db "Sending STS no. 1/4 ... ", 0, 0 szSendingSts1: .db "Sending STS no. 2/4 ... ", 0, 0 szSendingSts2: .db "Sending STS no. 3/4 ... ", 0, 0 szSendingSts3: .db "Sending STS no. 4/4 ... ", 0, 0 szOK: .db "OK", '\r', '\n', 0, 0 szErrInvAnswer: .db "Error: Invalid answer.", '\r', '\n', '\r', '\n', 0, 0 szErrBufOvf: .db "Error: Buffer overflow while receiving.", '\r', '\n', '\r', '\n', 0 szErrTimeout: .db "Error: Timeout while waiting for UPDI answer.", '\r', '\n', '\r', '\n', 0 szErrKey: .db "Error: ASI Key submitting failed.", '\r', '\n', '\r', '\n', 0 szErrErasefail: .db"Error: ERASEFAIL==1 - Chip Erase failed.", '\r', '\n', '\r', '\n', 0, 0 szLineBreak: .db '\r', '\n', 0, 0 ; == External routines == .include "updi.asm" ; == Execution entry point after reset == reset: ; == Set clock == ; Disable clock prescaler: ldi tmp0, CPU_CCP_IOREG_gc xout CPU_CCP, tmp0 ldi tmp0, 0 xout CLKCTRL_MCLKCTRLB, tmp0 ; == Initialize registers == clr zero clr updiFlags ; == Initialize UART == .equ BAUD_REG_VAL = ROUND(4.0*F_CPU/(1.0*UART_BPS)) ldi tmp0, low(BAUD_REG_VAL) xout USART0_BAUDL, tmp0 ldi tmp0, high(BAUD_REG_VAL) xout USART0_BAUDH, tmp0 ; USART0_CTRLC = $03 (reset value): asynchronous, 8N1. ldi tmp0, (1<