I figured I would start with attempting to read some data first, before I go attempting to write things. Following the guide above, I've got it into bootloader mode, and have the following being sent:
Hey Eascen, nice work tackling that one quickly!
though I requested an LEN of 0x01, I'm receiving 18 response bytes.
Indeed, it turns out that in the interest of trimming the bootloader size it was tweaked to only return full rows (8 bytes) of eeprom data, so if you request a length of say 2 bytes, it will respond with the first 2 bytes correctly and then another 6 bytes of potential garbage. If you request say 16 bytes, it will reply with just the last 8 bytes of that request. Effectively there's an 8 byte buffer that the eeprom reads get moved into, and the buffer is always sent in full.
For writing new values to eeprom, the length field is handled properly up to 8 bytes.
Code: Select all
0, 5, 4, 0, 247, 128, 127, 20, 251??, 64, 0, 254, 48, 255, 0, 255, 64, 191, 132 (again, csum?), 0x04.
Mem4: No response
Mem5: No response
And this is where the byte stuffing comes in. In the AppNote, microchip used 0x55 as the start of the packet, and 0x04 as the end of packet (the first 0x55 is the sync bit for auto-baud detection). As a result, if 0x04 or 0x55 are ever in a different part of the packet, either as part of the data, address, or command, then they must be preceded by the Data Link Escape (DLE) character 0x05. Similarly, if 0x05 needs to be sent, it also needs to be preceeded by a 0x05. In calculating the checksum, all instances of the 0x05 as DLE are ignored, whereas instances of 0x05 as data/address/command are counted.
It's a bit unfortunate, but the two commands relevant here, RD_EEDATA and WR_EEDATA, are commands 04 and 05, and so both need to be preceeded by the 0x05 escape character.
If you use the normal bootloader program, it creates a log file "serial_communication_record.txt" which you can open up to see all the back and forth between the computer and CA, and can copy and paste commands from there while sorting out and verifying stuff. Notice the last command:
which causes the CA to exit the bootloader and return to normal operation.
If I'm on the proper track and value 2 (index 1) is actually the value I'm looking for, I'll call it a day and wait for the mapping; though it makes Mem3 look off, If you have a few basic mappings I can use for testing, I can likely get quite a bit further tomorrow
So that took a way longer time to organize and compile, but the full memory table for the B21 code is in the attached spreadsheet. Hopefully it should be pretty clear. You can totally break the code by putting values in here that are outside of the expected bounds. So for instance, programming in a Preset of 5 (outside of the 0,1 or 2 which are allowed) would cause all kinds of crazy behavior. That goes with every setting that is part of finite set, since I'm not doing any bounds checking on eeprom arrays.
You'll notice too that there are a small number of settings which aren't settable via the setup menu. Some of them are dependencies (like the DGainSpan) while others might be useful for people doing more OEM type customizations. For instance, the 13 bytes of InnrSetupMask
lets you control whether individual items show up in the setup menu or not. So if you don't want the speed limit to be changeable, you'd note that the speed limits are the 5th setup menu, and max speed is the first option, so if you set the 5th byte of InnrSetupMask to b'01111111', then it would skip over the MaxSpeed setting and jump right to the next item "Strt Speed". On a similar note, if you want to be able to change your speed limit but only up to a certain maximum, then that hard coded max can be set at address D8 MaxSpeedADR
, and any value that a user puts in via the setup menu will be clamped to this.
Thanks again for supporting this, and I apologize for my lack of low level programming skills, most of my work is done in higher level languages.
I'd say you've done quite well. Let me know if there is anything more I can help with.