Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Teensy 4.0 #47

blackketter opened this issue Aug 12, 2019 · 5 comments


Copy link

commented Aug 12, 2019

Not sure what's needed, but I'm happy to pitch in and help.


This comment has been minimized.

Copy link

commented Aug 19, 2019

I was just looking in to this today. Assuming that the protocol hasn't changed, the changes are pretty minimal:

I think the only open question for this is what the block size is for the flash. seems to indicate it's 64KiB, but I'm unsure if the bootloader expects 64K blobs or if it takes them in smaller chunks over the USB.

It would probably take someone an hour or two to trial-and-error whether the protocol is the same and what the necessary block size is.


This comment has been minimized.

Copy link

commented Aug 23, 2019

I was able to get it working with Teensy 4.0 after a rather big headache.

I changed the MAX_MEMORY_SIZE definition to 0x200000 as well as edited this line of code to look like the following:

static const struct {
	const char *name;
	int code_size;
	int block_size;
} MCUs[] = {
	{"at90usb162",   15872,   128},
	{"atmega32u4",   32256,   128},
	{"at90usb646",   64512,   256},
	{"at90usb1286", 130048,   256},
#if defined(USE_LIBUSB) || defined(USE_APPLE_IOKIT) || defined(USE_WIN32)
	{"mkl26z64",     63488,   512},
	{"mk20dx128",   131072,  1024},
	{"mk20dx256",   262144,  1024},
	{"mk66fx1m0",  1048576,  1024},
	{"mk64fx512",   524288,  1024},
    {"imxrt1062",  2097152,  1024},

	// Add duplicates that match friendly Teensy Names
	// Match board names in boards.txt
	{"TEENSY2",   32256,   128},
	{"TEENSY2PP", 130048,   256},
	{"TEENSYLC",     63488,   512},
	{"TEENSY30",   131072,  1024},
	{"TEENSY31",   262144,  1024},
	{"TEENSY35",   524288,  1024},
	{"TEENSY36",  1048576,  1024},
    {"TEENSY40",  2097152,  1024},
	{NULL, 0, 0},

It looks like the Teensy 4.0 hex files have this fun little line added to the beginning:


According to the Intel Hex Format, this sets the upper 16 bits of the 32-bit memory address. It uses the value 0x6000 to set this value. This then sets the extended_addr to 0x60000000, which suggests there is almost 1.5GB of memory available on the Teensy 4.0!

In order to get around this problem, I also changed this line of code to ignore any commands to use an extended address above the MAX_MEMORY_SIZE.

if (code == 4 && len == 2) {
	if (!sscanf(ptr, "%04x", &i)) return 1;
	ptr += 4;
	sum += ((i >> 8) & 255) + (i & 255);
		if (!sscanf(ptr, "%02x", &cksum)) return 1;
	if (((sum & 255) + (cksum & 255)) & 255) return 1;
        if ((i << 16) > MAX_MEMORY_SIZE) return 1;
	extended_addr = i << 16;
	printf("ext addr = %08X\n", extended_addr);

This solution is admittedly hacky, but it has worked with several different hex files I have. It ends up ignoring any line in the hex file that tries to set the upper 16-bits to a location over 2MB. I'm not sure what will happen with this solution with hex files that approach the upper size limit of the teensy 4.0, but it should work with most firmwares.


This comment has been minimized.

Copy link

commented Sep 3, 2019

It looks like the Teensy 4.0 hex files have this fun little line added to the beginning:

Makes sense if you look at the linker skript:

Looks like this is some virtual address the flash is mapped to. Just wondering if ignoring this adress is the right way to do it but if it works...

Maybe Paul can shed some light into that?


This comment has been minimized.

Copy link

commented Sep 9, 2019

If somebody feels like experimenting, I just published a first version of loader CLI reimplementation in Rust that should work with 4.0 (but haven't tested it with a 4.0 yet – I still need to get some binary working; tested with an LC, though, and tested booting from HalfKay into user mode with 3.6 and 4.0):

Caveats: libusb only (Linux/FreeBSD), accepts ELF file as an input (because I was tired of having to convert to ihex); patches for supporting other platforms / input formats are welcome, though.


This comment has been minimized.

Copy link

commented Oct 8, 2019

Done 900a2bf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
6 participants
You can’t perform that action at this time.