Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: Teensy programs Teensy

  1. #1
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,651

    Teensy programs Teensy

    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...l=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.

    Click image for larger version. 

Name:	cables.jpg 
Views:	192 
Size:	93.1 KB 
ID:	12027 Click image for larger version. 

Name:	output.PNG 
Views:	197 
Size:	40.0 KB 
ID:	12028


    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 ). 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.

    Click image for larger version. 

Name:	case.PNG 
Views:	158 
Size:	167.5 KB 
ID:	12029 Click image for larger version. 

Name:	setup.PNG 
Views:	129 
Size:	77.3 KB 
ID:	12030 Click image for larger version. 

Name:	dimensions.PNG 
Views:	145 
Size:	8.8 KB 
ID:	12032

    In case anybody is interested I can post the progress here.
    Attached Files Attached Files
    Last edited by luni; 12-14-2017 at 08:08 PM.

  2. #2
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,435

  3. #3
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,651
    Hm, should have found that before I started programming, anyway was quite instructive... :-)

  4. #4
    Senior Member
    Join Date
    Jun 2013
    Posts
    415
    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 by yeahtuna; 11-29-2020 at 01:32 PM.

  5. #5
    Senior Member
    Join Date
    Jun 2013
    Posts
    415
    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;
    };

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •