keyboardio / attiny_i2c_bootloader Goto Github PK
View Code? Open in Web Editor NEWAn I2C bootloader for ATTiny devices based on AVR112.
An I2C bootloader for ATTiny devices based on AVR112.
When I compile my firmware (fork of avr keyscanner: https://github.com/Dygmalab/avr-keyscanner/tree/arm-flasher) the interrupt table is longer:
00000156 <__ctors_end>:
so the rjmp hardcoded here
attiny_i2c_bootloader/TWI_Slave/twi_slave.c
Line 201 in 5b14e6e
Doesn't work.
I had a couple questions regarding possible use of this on my project.
1: Is there any reason this would not work with an ATTINY85 running on an 8 mhz internal clock, since it's the same family?
2: I don't suppose it would work on a 328P...
3: The "Master" program that uploads the firmware confuses me. How would I get my firmware into a byte array like was shown in order to upload it? Normally it's a hex file.
Specifically, I am using an ESP8266 as the host device, where I would ideally upload the hex file to the internal filesystem (which I can do already). Can you elaborate on what algorithm (pseudocode or C++) would convert a hex file (or whatever compiled output you used) into a byte array as you demonstrated? I'm also not sure how it's safe to move it around address-wise without corrupting the program (unless it uses relative addressing by default, or it's somehow compiled that way).
I was looking at the LED clearing code, and it looks like it won't work properly once the application interrupt vectors have overwritten the ones initially programmed with the bootloader. Right now when powering on my Model 01, random LEDs light up until the greeting mode turns on (the breathing "LED" key). Maybe the LED clearing in the bootloader should happen synchronously.
Right now, once the application code is flashed, the SPI interrupt goes to the application code, even while the bootloader is running. The buffers won't be initialized, and maybe worse things will happen if stuff gets rearranged in the application code. These seem like good reasons to leave the SPI interrupt off in the bootloader.
Also, it probably should be modeled after the code in the keyscanner, because it looks like the APA102 protocol requires the 1-bits in order for an LED to recognize that it's being addressed, so writing only zeroes won't accomplish turning them off.
The Model 100 keyscanner could likely enter a WDT reset loop if the watchdog timer issues a reset. This probably won't happen under normal usage, though. It's most likely if the bootloader enters command mode and then leaves via a watchdog reset. (For example, running the bootloader flashing sketch for the ATtinys, or pressing the bootloader trigger keys during reset, then timing out.)
This is a somewhat non-obvious consequence of facts documented in the datasheet, but never explicitly stated. If a watchdog reset occurs, all I/O registers are reset to their default values, forcing the watchdog timer to its smallest interval (approx. 15ms). Additionally, watchdog configuration updates will fail while WDRF
is set, because the hardware won't clear WDE
unless WDRF
is cleared first.
The result is that when starting the application after a watchdog reset, the watchdog timer remains enabled at 15ms, causing endless resets in application code every 15ms. The wdt_enable(WDTO_8S)
is ineffective, because the Model 100 configuration doesn't touch MCUSR
. On the Model 01, with my in-progress unified bootloader trigger code, this causes LED flickering and spurious key reports (probably due to resets in the middle of application code writing a key report to the ATmega). My unified bootloader trigger patch will fix this.
As an additional precaution, the keyscanner initialization code could probably also explicitly clear MCUSR
and disable the watchdog timer.
Hi , I am trying to modify this project to adapt ATmega support.
I am having some problem with the code that I cant figure it out.
uint8_t process_read_frame() { // check disabled for space reasons // Check the SPM is ready, abort if not. if ((SPMCSR & _BV(SELFPROGEN)) != 0) { abort_twi(); return 0; }
if this function has no argument then why
case TWI_CMD_PAGEUPDATE_FRAME: if (!process_read_frame(&pageAddr)) {
Thanks.
Should the bootloader possibly share the key checking code between Model 01 and Model 100? It looks like the hardware might be similar enough.
That would allow an immediate application start on the Model 01, and have the added benefit of avoiding repeated firmware flashing if the flasher sketch is accidentally restarted.
Maybe the code size was originally too tight to both do that and the Model 01-specific initialization?
For the "update frame" command, this bootloader sort of inherits a design flaw from its AVR112 predecessor: it assumes that a target receiver should NACK the last byte of a transmission from the controller on success. We should probably fix this for the sake of robustness. I have a design in mind that I will describe later on.
As far as I can tell, the low-level I2C ACK protocol is suitable for flow control only. Additionally, there is no way to distinguish an unresponsive target from one that actively chooses to NACK a transmission. Therefore, the controller shouldn't rely on detecting a NACK on the last byte of a command as an indication of success.
The bootloader calls abort_twi()
on errors, which resets the hardware state machine to "unaddressed target" mode, which will probably release the bus lines until the next START. This is equivalent to issuing a NACK for every byte for the rest of the transaction. The low-level TWI library that we use can't distinguish an early NACK from a NACK at the end of a controller transmission, so even that theoretical distinction is unavailable to us for handshaking. (Note: I haven't extensively tested these scenarios yet, but I have seen bugs that are consistent with this explanation.)
A possible solution is to add a new, differently-numbered command for "update frame" that reverses the sense of ACK vs NACK for success. This should also maybe get a bootloader protocol version bump, though we could also continue implementing the old command while still sharing code. I'm willing to work to implement this.
Another possibility is to also add another new command to query the status of a flash page write.
The I2C specification says that a controller should NACK the last byte when receiving from a target. One explanation (which isn't explicitly stated in the specification) is that it serves an important flow control function: the target needs to know to release the bus and stop transmitting at the falling edge of SCL at the end of the ACK bit period (the one where the controller has NACKed). Otherwise, in a protocol where the controller can read arbitrarily many bytes from the target, the target might continue transmitting, driving the SDA line during the next SCL period. This would interfere with the controller sending a STOP or repeated START condition.
Also, a NACK sent by a controller in receive mode is semantically different from a NACK from a target in receive mode: a target always knows when the controller is present, because the controller is driving clock pulses on the SCL line. The controller has no such assurances about a target NACK, except for maybe when the target happens to be stretching the clock.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.