mirror of https://github.com/arendst/Tasmota.git
Fix C2 programmer, incorrect initialization could brick EFM8 MCUs
This commit is contained in:
parent
f7ae554394
commit
1418af3f31
|
@ -204,13 +204,33 @@ uint8_t c2_reset() {
|
|||
return C2_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t c2_programming_init() {
|
||||
uint8_t c2_programming_init(uint8_t devid) {
|
||||
c2_reset();
|
||||
c2_address_write(C2FPCTL);
|
||||
C2_DATA_WRITE_AND_CHECK(C2FPCTL_ENABLE0, 1);
|
||||
C2_DATA_WRITE_AND_CHECK(C2FPCTL_CORE_HALT, 1);
|
||||
C2_DATA_WRITE_AND_CHECK(C2FPCTL_ENABLE1, 1)
|
||||
C2_DELAY_MS(21);
|
||||
|
||||
// device specific initialization, see https://www.silabs.com/documents/public/application-notes/AN127.pdf
|
||||
switch (devid) {
|
||||
case C2_DEVID_UNKNOWN:
|
||||
break;
|
||||
case C2_DEVID_EFM8BB1:
|
||||
case C2_DEVID_EFM8BB2:
|
||||
case C2_DEVID_EFM8BB3: // C2_DEVID_EFM8LB1 is the same
|
||||
c2_address_write(0xFF);
|
||||
C2_DATA_WRITE_AND_CHECK(0x80, 1);
|
||||
C2_DELAY_US(5);
|
||||
c2_address_write(0xEF);
|
||||
C2_DATA_WRITE_AND_CHECK(0x02, 1);
|
||||
c2_address_write(0xA9);
|
||||
C2_DATA_WRITE_AND_CHECK(0x00, 1);
|
||||
break;
|
||||
default:
|
||||
return C2_BROKEN_LINK;
|
||||
}
|
||||
|
||||
return C2_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,13 @@ inline void C2D_enable(bool oe) {
|
|||
#define C2_INBUSY 0x02
|
||||
#define C2_OUTREADY 0x01
|
||||
|
||||
// Device families (https://www.silabs.com/documents/public/application-notes/AN127.pdf)
|
||||
#define C2_DEVID_UNKNOWN 0x00
|
||||
#define C2_DEVID_EFM8BB1 0x30
|
||||
#define C2_DEVID_EFM8BB2 0x32
|
||||
#define C2_DEVID_EFM8BB3 0x34
|
||||
#define C2_DEVID_EFM8LB1 0x34
|
||||
|
||||
// Layer 1: C2 Programmig Interface (PI) Register access
|
||||
void c2_address_write(uint8_t address);
|
||||
uint8_t c2_address_read();
|
||||
|
@ -125,7 +132,7 @@ inline uint8_t c2_data_read(uint8_t &d, uint8_t bytes=1) {
|
|||
|
||||
// Layer 2: Operations
|
||||
uint8_t c2_reset();
|
||||
uint8_t c2_programming_init();
|
||||
uint8_t c2_programming_init(uint8_t devid);
|
||||
uint8_t c2_block_write(uint32_t address, uint8_t *data, uint8_t len);
|
||||
uint8_t c2_block_read(uint32_t address, uint8_t *data, uint8_t len);
|
||||
uint8_t c2_eeprom_read(uint32_t address, uint8_t *data, uint8_t len);
|
||||
|
|
|
@ -127,7 +127,7 @@ ssize_t rf_decode_and_write(uint8_t *record, size_t size)
|
|||
uint16_t address = h->address_high * 0x100 + h->address_low;
|
||||
|
||||
do {
|
||||
err = c2_programming_init();
|
||||
err = c2_programming_init(C2_DEVID_EFM8BB1);
|
||||
err = c2_block_write(address, h->data, h->len);
|
||||
} while (err != C2_SUCCESS && retries--);
|
||||
} else if (h->record_type == IHX_RT_END_OF_FILE) {
|
||||
|
@ -179,7 +179,7 @@ uint8_t rf_erase_flash(void)
|
|||
uint8_t err;
|
||||
|
||||
for (uint32_t i = 0; i < 4; i++) { // HACK: Try multiple times as the command sometimes fails (unclear why)
|
||||
err = c2_programming_init();
|
||||
err = c2_programming_init(C2_DEVID_EFM8BB1);
|
||||
if (err != C2_SUCCESS) {
|
||||
return 10; // Failed to init RF chip
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue