Provide urclock programmer
This commit is contained in:
parent
4c92030e3a
commit
e6c26d8db4
|
@ -225,6 +225,9 @@ add_library(libavrdude
|
|||
updi_readwrite.h
|
||||
updi_state.c
|
||||
updi_state.h
|
||||
urclock.c
|
||||
urclock.h
|
||||
urclock_private.h
|
||||
usbasp.c
|
||||
usbasp.h
|
||||
usbdevs.h
|
||||
|
|
|
@ -180,6 +180,9 @@ libavrdude_a_SOURCES = \
|
|||
updi_readwrite.h \
|
||||
updi_nvm.c \
|
||||
updi_nvm.h \
|
||||
urclock.c \
|
||||
urclock.h \
|
||||
urclock_private.h \
|
||||
usbdevs.h \
|
||||
usb_hidapi.c \
|
||||
usb_libusb.c \
|
||||
|
|
|
@ -756,6 +756,19 @@ programmer
|
|||
connection_type = serial;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# urclock
|
||||
#------------------------------------------------------------
|
||||
|
||||
# See https://github.com/stefanrueger/urboot
|
||||
programmer
|
||||
id = "urclock";
|
||||
desc = "Urclock programmer for urboot bootloaders (arduino compatible)";
|
||||
type = "urclock";
|
||||
prog_modes = PM_SPM;
|
||||
connection_type = serial;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# xbee
|
||||
#------------------------------------------------------------
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
* Atmel AVR8L, AVR8, XMEGA and AVR8X family description of interrupts and more
|
||||
*
|
||||
* published under GNU General Public License, version 3 (GPL-3.0)
|
||||
* meta-author: Stefan Rueger <stefan.rueger@urclocks.com>
|
||||
* meta-author Stefan Rueger <stefan.rueger@urclocks.com>
|
||||
*
|
||||
* v 1.1
|
||||
* 30.08.2022
|
||||
* 04.11.2022
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* meta-author Stefan Rueger <stefan.rueger@urclocks.com>
|
||||
*
|
||||
* v 1.1
|
||||
* 30.08.2022
|
||||
* 04.11.2022
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -770,7 +770,7 @@ typedef struct { // Value of -1 typically means unknown
|
|||
#define vts_avr128da64 64
|
||||
#define vts_avr128db64 65
|
||||
|
||||
// Suggested vector bootloader interrupt number (first unused vector or, failing that, slot just above vector table)
|
||||
// Suggested vector bootloader interrupt: first unused vector or slot just above vector table
|
||||
#define vbu_attiny4 10
|
||||
#define vbu_attiny5 11
|
||||
#define vbu_attiny9 10
|
||||
|
|
|
@ -580,6 +580,7 @@ const char * pinmask_to_str(const pinmask_t * const pinmask);
|
|||
The target file will be selected at configure time. */
|
||||
|
||||
extern long serial_recv_timeout; /* ms */
|
||||
extern long serial_drain_timeout; /* ms */
|
||||
|
||||
union filedescriptor
|
||||
{
|
||||
|
@ -798,6 +799,7 @@ typedef struct programmer_t {
|
|||
int (*parseextparams) (const struct programmer_t *pgm, const LISTID xparams);
|
||||
void (*setup) (struct programmer_t *pgm);
|
||||
void (*teardown) (struct programmer_t *pgm);
|
||||
int (*flash_readhook) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *flm, const char *fname, int size);
|
||||
// Cached r/w API for terminal reads/writes
|
||||
int (*write_byte_cached)(const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
|
||||
unsigned long addr, unsigned char value);
|
||||
|
|
|
@ -119,12 +119,12 @@ PROGRAMMER *pgm_new(void) {
|
|||
pgm->err_led = pgm_default_led;
|
||||
pgm->pgm_led = pgm_default_led;
|
||||
pgm->vfy_led = pgm_default_led;
|
||||
pgm->read_byte_cached = avr_read_byte_cached;
|
||||
pgm->read_byte_cached = avr_read_byte_cached;
|
||||
pgm->write_byte_cached = avr_write_byte_cached;
|
||||
pgm->chip_erase_cached = avr_chip_erase_cached;
|
||||
pgm->page_erase_cached = avr_page_erase_cached;
|
||||
pgm->flush_cache = avr_flush_cache;
|
||||
pgm->reset_cache = avr_reset_cache;
|
||||
pgm->reset_cache = avr_reset_cache;
|
||||
|
||||
/*
|
||||
* optional functions - these are checked to make sure they are
|
||||
|
@ -154,6 +154,7 @@ PROGRAMMER *pgm_new(void) {
|
|||
pgm->parseextparams = NULL;
|
||||
pgm->setup = NULL;
|
||||
pgm->teardown = NULL;
|
||||
pgm->flash_readhook = NULL;
|
||||
|
||||
// For allocating "global" memory by the programmer
|
||||
pgm->cookie = NULL;
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "stk500generic.h"
|
||||
#include "stk500v2.h"
|
||||
#include "teensy.h"
|
||||
#include "urclock.h"
|
||||
#include "usbasp.h"
|
||||
#include "usbtiny.h"
|
||||
#include "wiring.h"
|
||||
|
@ -102,6 +103,7 @@ const PROGRAMMER_TYPE programmers_types[] = { // Name(s) the programmers call th
|
|||
{"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc}, // "STK600HVSP"
|
||||
{"stk600pp", stk600pp_initpgm, stk600pp_desc}, // "STK600PP"
|
||||
{"teensy", teensy_initpgm, teensy_desc}, // "teensy"
|
||||
{"urclock", urclock_initpgm, urclock_desc}, // "Urclock"
|
||||
{"usbasp", usbasp_initpgm, usbasp_desc}, // "usbasp"
|
||||
{"usbtiny", usbtiny_initpgm, usbtiny_desc}, // "USBtiny" or "usbtiny"
|
||||
{"wiring", wiring_initpgm, wiring_desc}, // "Wiring"
|
||||
|
@ -171,5 +173,3 @@ void walk_programmer_types(walk_programmer_types_cb cb, void *cookie)
|
|||
cb(p->id, p->desc, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "libavrdude.h"
|
||||
|
||||
long serial_recv_timeout = 5000; /* ms */
|
||||
long serial_drain_timeout = 250; /* ms */
|
||||
|
||||
struct baud_mapping {
|
||||
long baud;
|
||||
|
@ -549,7 +550,7 @@ static int ser_drain(const union filedescriptor *fd, int display) {
|
|||
unsigned char buf;
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 250000;
|
||||
timeout.tv_usec = serial_drain_timeout*1000L;
|
||||
|
||||
if (display) {
|
||||
msg_info("drain>");
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "libavrdude.h"
|
||||
|
||||
long serial_recv_timeout = 5000; /* ms */
|
||||
long serial_drain_timeout = 250; /* ms */
|
||||
|
||||
#define W32SERBUFSIZE 1024
|
||||
|
||||
|
@ -635,7 +636,7 @@ static int net_drain(const union filedescriptor *fd, int display) {
|
|||
}
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 250000;
|
||||
timeout.tv_usec = serial_drain_timeout*1000L;
|
||||
|
||||
while (1) {
|
||||
FD_ZERO(&rfds);
|
||||
|
@ -712,7 +713,7 @@ static int ser_drain(const union filedescriptor *fd, int display) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
serial_w32SetTimeOut(hComPort,250);
|
||||
serial_w32SetTimeOut(hComPort, serial_drain_timeout);
|
||||
|
||||
if (display) {
|
||||
msg_info("drain>");
|
||||
|
|
11
src/update.c
11
src/update.c
|
@ -485,6 +485,17 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, UPDATE *upd, enum updateflags
|
|||
pmsg_error("read from file %s failed\n", update_inname(upd->filename));
|
||||
return LIBAVRDUDE_GENERAL_FAILURE;
|
||||
}
|
||||
// Patch input if for flash, eg, for vector bootloaders?
|
||||
if(pgm->flash_readhook) {
|
||||
AVRMEM *mem = avr_locate_mem(p, upd->memtype);
|
||||
if(mem && !strcmp(mem->desc, "flash")) {
|
||||
rc = pgm->flash_readhook(pgm, p, mem, upd->filename, rc);
|
||||
if (rc < 0) {
|
||||
pmsg_notice("readhook for file %s failed\n", update_inname(upd->filename));
|
||||
return LIBAVRDUDE_GENERAL_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size = rc;
|
||||
pmsg_info("reading input file %s for %s%s\n",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2022, Stefan Rueger <stefan.rueger@urclocks.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef urclock_h__
|
||||
#define urclock_h__
|
||||
|
||||
extern const char urclock_desc[];
|
||||
void urclock_initpgm (PROGRAMMER *pgm);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2022, Stefan Rueger <stefan.rueger@urclocks.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef urclock_private_h__
|
||||
#define urclock_private_h__
|
||||
|
||||
#include "avrintel.h"
|
||||
|
||||
// EEPROM or flash cache for bytewise access
|
||||
typedef struct {
|
||||
int base, size;
|
||||
char *page, *copy;
|
||||
} Cache;
|
||||
|
||||
// STK500v1 protocol constants
|
||||
|
||||
#define Resp_STK_OK 0x10
|
||||
#define Resp_STK_INSYNC 0x14
|
||||
|
||||
#define Sync_CRC_EOP 0x20
|
||||
|
||||
#define Cmnd_STK_GET_SYNC 0x30
|
||||
#define Cmnd_STK_ENTER_PROGMODE 0x50
|
||||
#define Cmnd_STK_LEAVE_PROGMODE 0x51
|
||||
#define Cmnd_STK_CHIP_ERASE 0x52
|
||||
#define Cmnd_STK_LOAD_ADDRESS 0x55
|
||||
#define Cmnd_STK_UNIVERSAL 0x56
|
||||
|
||||
#define Cmnd_STK_PROG_PAGE 0x64
|
||||
#define Cmnd_STK_READ_PAGE 0x74
|
||||
#define Cmnd_STK_READ_SIGN 0x75
|
||||
|
||||
#define Cmnd_UR_PROG_PAGE_EE 0x00
|
||||
#define Cmnd_UR_READ_PAGE_EE 0x01
|
||||
|
||||
#define Cmnd_UR_PROG_PAGE_FL 0x02
|
||||
#define Cmnd_UR_READ_PAGE_FL 0x03
|
||||
|
||||
|
||||
// STK_UNIVERSAL commands for backward compatibility
|
||||
#define Subc_STK_UNIVERSAL_LEXT 0x4d000000u // Load extended address
|
||||
#define Subc_STK_UNIVERSAL_CE 0xac800000u // Chip erase
|
||||
|
||||
|
||||
// Urboot protocol side channel info about MCU id and 5 binary bootloader features
|
||||
|
||||
// Number of differnt MCU ids
|
||||
#define UB_N_MCU 2040 // MCU id 0..2039
|
||||
|
||||
// 5 bootloader features
|
||||
#define UB_RESERVED_1 1
|
||||
#define UB_RESERVED_2 2
|
||||
#define UB_READ_FLASH 4 // Bootloader can read flash
|
||||
#define UB_FLASH_LL_NOR 8 // Bootloader flash programming looks like a NOR memory
|
||||
#define UB_CHIP_ERASE 16 // Bootloader has a flash-only chip erase that protects itself
|
||||
|
||||
#define UB_INFO(ub_features, ub_mcuid) (ub_features*UB_N_MCU + ub_mcuid)
|
||||
#define UB_FEATURES(ub_info) ((uint16_t)(ub_info)/UB_N_MCU)
|
||||
#define UB_MCUID(ub_info) ((uint16_t)(ub_info)%UB_N_MCU)
|
||||
|
||||
|
||||
/*
|
||||
* Urboot layout of top six bytes
|
||||
*
|
||||
* FLASHEND-5: numblpags, only from v7.5: 1 byte number 1..127 of bootloader flash pages
|
||||
* FLASHEND-4: vblvecnum, only from v7.5: 1 byte vector number 1..127 for vector bootloader
|
||||
* FLASHEND-3: 2 byte rjmp opcode to bootloader pgm_write_page(sram, flash) or ret opcode
|
||||
* FLASHEND-1: capability byte of bootloader
|
||||
* FLASHEND-0: version number of bootloader: 5 msb = major version, 3 lsb = minor version
|
||||
*/
|
||||
|
||||
// Capability byte of bootloader from version 7.2 onwards
|
||||
#define UR_PGMWRITEPAGE 128 // pgm_write_page() can be called from application at FLASHEND+1-4
|
||||
#define UR_EEPROM 64 // EEPROM read/write support
|
||||
#define UR_URPROTOCOL 32 // Bootloader uses urprotocol that requires avrdude -c urclock
|
||||
#define UR_DUAL 16 // Dual boot
|
||||
#define UR_VBLMASK 12 // Vector bootloader bits
|
||||
#define UR_VBLPATCHVERIFY 12 // Patch reset/interrupt vectors and show original ones on verify
|
||||
#define UR_VBLPATCH 8 // Patch reset/interrupt vectors only (expect an error on verify)
|
||||
#define UR_VBL 4 // Merely start application via interrupt vector instead of reset
|
||||
#define UR_NO_VBL 0 // Not a vector bootloader, must set fuses to HW bootloader support
|
||||
#define UR_PROTECTME 2 // Bootloader safeguards against overwriting itself
|
||||
#define UR_RESETFLAGS 1 // Load reset flags into register R2 before starting application
|
||||
|
||||
#define verbyte_cv(capver) ((uint8_t) ((uint16_t) (capver) >> 8))
|
||||
#define hascapbyte_cv(capver) ({ uint8_t _vh = verbyte_cv(capver); _vh >= 072 && _vh != 0xff; })
|
||||
#define hasextendedv_cv(capver) ({ uint8_t _vh = verbyte_cv(capver); _vh >= 075 && _vh != 0xff; })
|
||||
#define capabilities_cv(capver) ({ uint16_t _vc = capver; \
|
||||
(uint8_t) (hascapbyte_cv(_vc)? _vc&0xff: 0); })
|
||||
#define vblvecnum_cv(capver) ({ uint16_t _vc = capver; \
|
||||
(uint8_t) (hasextendedv_cv(_vc)? pgm_read_b1(FLASHEND-4): 0); })
|
||||
#define numblpages_cv(capver) ({ uint16_t _vc = capver; \
|
||||
(uint8_t) (hasextendedv_cv(_vc)? pgm_read_b1(FLASHEND-5): 0); })
|
||||
#define blurversion_cv(capver) ({ uint8_t _vh = verbyte_cv(capver); \
|
||||
(uint8_t) (_vh >= 072 && _vh != 0xff? _vh: 0); })
|
||||
|
||||
#define vercapis(capver, mask) ({ uint16_t _vi = capver; !!(capabilities_cv(_vi) & (mask)); })
|
||||
#define ispgmwritepage_cv(capver) vercapis(capver, UR_PGMWRITEPAGE)
|
||||
#define iseeprom_cv(capver) vercapis(capver, UR_EEPROM)
|
||||
#define isurprotocol_cv(capver) vercapis(capver, UR_URPROTOCOL)
|
||||
#define isdual_cv(capver) vercapis(capver, UR_DUAL)
|
||||
#define isvectorbl_cv(capver) vercapis(capver, UR_VBLMASK)
|
||||
#define isprotectme_cv(capver) vercapis(capver, UR_PROTECTME)
|
||||
#define isresetflags_cv(capver) vercapis(capver, UR_RESETFLAGS)
|
||||
|
||||
// Capability bits incl position
|
||||
#define pgmwritepage_bit_cap(cap) ((cap) & UR_PGMWRITEPAGE)
|
||||
#define eeprom_bit_cap(cap) ((cap) & UR_EEPROM)
|
||||
#define dual_bit_cap(cap) ((cap) & UR_DUAL)
|
||||
#define vector_bits_cap(cap) ((cap) & UR_VBLMASK))
|
||||
#define protectme_bit_cap(cap) ((cap) & UR_PROTECTME)
|
||||
#define urprotocol_bit_cap(cap) ((cap) & UR_URPROTOCOL)
|
||||
#define resetflags_bit_cap(cap) ((cap) & UR_RESETFLAGS)
|
||||
|
||||
// Boolean capabilities
|
||||
#define ispgmwritepage_cap(cap) (!!((cap) & UR_PGMWRITEPAGE))
|
||||
#define iseeprom_cap(cap) (!!((cap) & UR_EEPROM))
|
||||
#define isdual_cap(cap) (!!((cap) & UR_DUAL))
|
||||
#define isvectorbl_cap(cap) (!!((cap) & UR_VBLMASK)))
|
||||
#define isprotectme_cap(cap) (!!((cap) & UR_PROTECTME))
|
||||
#define isurprotocol_cap(cap) (!!((cap) & UR_URPROTOCOL))
|
||||
#define isresetflags_cap(cap) (!!((cap) & UR_RESETFLAGS))
|
||||
|
||||
// Capability levels 0, 1, 2 or 3
|
||||
#define vectorbl_level_cap(cap) (((cap) & UR_VBLMASK)/UR_VBL)
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue