Teensy programs Teensy

luni

Well-known member
I just successfully programmed a T3.2 using the USB host from a T3.6. with a hex file loaded from the SD card.
To do this I wrote the following two USB drivers (attached, but still quite sketchy! Maybe somebody has an answer to my question in this thread: https://forum.pjrc.com/threads/47550-USB-Host-Status-of-control-transfers?p=158821&viewfull=1#post158821 )

  • The "TeensyRebootDriver" is used to start the bootloader without pressing the button. (This should work with any board compiled in USB_Serial mode or one in the various HID modes)
  • The TeensyHalfKayDriver connects to boards with an already running bootloader and is used to program the firmware.

Here a picture of the "setup" and a screenshot of the debug output.

cables.jpg output.PNG


I'm considering making a small programmer with integrated display and LiPo out of this. Such a thing might come in handy if you need to program a teensy mounted in in some difficult to reach place. It might also be useful in a production environment (no time consuming loading of the windows drivers :p ). And it gives me a reason to finally do something with this display lying around for some time now :)

Here a few sketches how such a thing could look like. 2.4" Nextion touch display, USB A connector for programming at the front and the T3.6 -USB micro for uploading hex files to the SD card and charging the 1300mAh LiPo.

case.PNG setup.PNG dimensions.PNG

In case anybody is interested I can post the progress here.
 

Attachments

  • drivers.zip
    5.9 KB · Views: 225
Last edited:
Hm, should have found that before I started programming, anyway was quite instructive... :)
 
Hi. I'm trying to do something similar, except my firmware file is not located on the host device.

I already have an application for updating my teensy based devices by sending a hex file from a PC or Mac (very similar to how the teensy loader works), and now I'd like support updating the firmware of a device connected to the USB Host port of another teensy 3.6 based device.

I've made a copy of the rawhid driver from the USB host library and set it up to claim halfKay interfaces. It's working and I can see that when I press the program button, the device indeed gets claimed.

And after it's claimed, I get my firmware updater application to send the firmware. Of course I won't be sending directly to the device to be programmed, instead I'm sending it to the host device and the idea is to redirect it to the device that is connected to the host port (which is now in halfKay mode ready to be programmed). And this is where I'm not sure how to proceed.

I've tried to redirect the data by doing the following, but it doesn't seem to work.

Code:
if (RawHID.recv(buffer, 0)) halfKay.sendPacket(buffer);

Any suggestions as to how I might proceed?
 
Last edited:
I managed to get this working. Basically you need to send the data to the HOST device (in my case a T3.6) and then do something similar to what Luni did to program the device plugged into the host port.

I send the data as 64 byte packets using rawhid_send, and then dynamically reconstructed the blocks on the T3.6. After I have a buffer of 2 blocks, I start programming the device plugged into the host port so I can free up memory as the device is programmed, that way I don't need to consume huge chunks of data on the T3.6.

Rob

Here's some code I use. It's not everything you need, but it gives you the idea...
Code:
#define MAX_BLOCK_SIZE 1024+128

enum FirmwarePacketType {
	kNewBlock, kContinueBlock, kAllDone
};


struct FirmwareBlockPacket {
	uint8_t app;
	uint8_t id;

	uint8_t type;
	uint8_t len;

	uint8_t data[60];
};


struct FirmwareBlock {
	uint16_t writeIndex = 0;
	uint8_t data[MAX_BLOCK_SIZE];
	FirmwareBlock* next = 0;
};

class AF_Firmware_Streamer {
public:
	AF_Firmware_Streamer() {
	
	}

	void processPacket(FirmwareBlockPacket p) {

		if (p.type == kAllDone) {
			doneSending = true;
			lastWrittenBlock = 0;
			return;
		}

		doneSending = false;

		if (p.type == kNewBlock) {

			
			FirmwareBlock* newBlock = new FirmwareBlock;

			// IF THIS IS THE FIRST BLOCK
			if (!lastWrittenBlock) {
				lastWrittenBlock = newBlock;
				blockToRead = newBlock;
			}

			else {
				lastWrittenBlock->next = newBlock;
				lastWrittenBlock = newBlock;
			}

			numBlocks++;
		}

		memcpy(&(lastWrittenBlock->data[lastWrittenBlock->writeIndex]), p.data, p.len);
		lastWrittenBlock->writeIndex += p.len;
		
	}

	FirmwareBlock getBlock() {
		return *blockToRead;
	}

	void queueNext() {

		if (!blockToRead) return;

		FirmwareBlock* old = blockToRead;
		blockToRead = blockToRead->next;
		delete old;

		numBlocks --;
	}

	int getNumAvailable() { return numBlocks; }

	bool available() {
		return (blockToRead && (numBlocks > 1 || doneSending));
	}

	void init(int size) {
		blockSize = size;
		doneSending = false;
	}

	void setDone(bool state) {
		doneSending = state;
	}

	bool getDone() { return doneSending; }

	FirmwareBlock* getRead() { return blockToRead; }
	FirmwareBlock* getWrite() { return lastWrittenBlock; }


protected:
	int blockSize = 0;

	bool doneSending = false;
	int numBlocks = 0;
	FirmwareBlock* blockToRead = 0;
	FirmwareBlock* lastWrittenBlock = 0;
};
 
Thanks for sharing. Very cool. I would require to either to ship my devices with two Teensy's, one to program another, or send a handheld programmer for field updates. I wonder if there are fresh news on this topic for Teensy 4.1.
 
I'm potentially interested in making one T4.1 program another. Is there any documentation of the Halfkay protocol? From what I see, my pc is just dumping data to teensy using update HID reports. It'll be nice to know the protocol.
 
I just successfully programmed a T3.2 using the USB host from a T3.6. with a hex file loaded from the SD card.
To do this I wrote the following two USB drivers (attached, but still quite sketchy! Maybe somebody has an answer to my question in this thread: https://forum.pjrc.com/threads/47550-USB-Host-Status-of-control-transfers?p=158821&viewfull=1#post158821 )

  • The "TeensyRebootDriver" is used to start the bootloader without pressing the button. (This should work with any board compiled in USB_Serial mode or one in the various HID modes)
  • The TeensyHalfKayDriver connects to boards with an already running bootloader and is used to program the firmware.

Sorry for bringing up an old thread, but I've been using a variation of this for years. Now I'm moving to T4.1 based devices and I'm experiencing issues. Did you have any troubles modifying this code to work for T4.1 based devices?
 
I never ported this code for a T4, but for my PC(c#) based uploading library I needed to siginificantly increase timeouts to be able to program a T4. I assume that deleting the large flash at the beginning of the programming cycle simply takes much longer than for the T3x boards. Might be the same issue here.
 
I can program a T3.x and T4.1 froma T3.6. I did indeed need to increase the wait time for erasing the T4.1 chip.

The problem I'm seeing is programming T3.x from a T4.1 device. It looks like it works--all the blocks are rent, but the T3.2 device never reboots. Can't figure out what the issue is. I thought maybe you would have more insight.
 
Back
Top