Add init block readback verification to match stock firmware
Stock firmware at 0x0DDD reads back each init block from register A7 after writing and verifies the data matches (with bit 7 XOR'd on the block address byte). Without this readback, the BCM4500 may not finalize the write — our init blocks were "silently failing" (I2C succeeds, status reports booted, but SNR reads all zeros). Changes: - bcm_write_init_block: add pre-write bcm_poll_ready(), post-write A7 readback with XOR(0x80) on byte[0] and full data comparison - i2c_rd buffer: expand from 8 to 24 bytes for 16-byte block readback This is the most likely root cause of the BCM4500 "boots but doesn't work" issue (Task #5). Needs hardware test to confirm.
This commit is contained in:
parent
0d6facb321
commit
e9e5ab859a
@ -132,7 +132,7 @@ volatile __bit got_sud;
|
||||
|
||||
/* I2C scratch buffers in xdata (24 bytes: fits 20-byte EEPROM blocks) */
|
||||
static __xdata BYTE i2c_buf[24];
|
||||
static __xdata BYTE i2c_rd[8];
|
||||
static __xdata BYTE i2c_rd[24];
|
||||
|
||||
/* TUNE_MONITOR result buffer: filled by OUT phase, returned by IN phase */
|
||||
static __xdata BYTE tm_result[10];
|
||||
@ -847,6 +847,12 @@ static BOOL bcm_read_signal_block(void) {
|
||||
static BOOL bcm_write_init_block(const __code BYTE *data, BYTE len) {
|
||||
BYTE i;
|
||||
|
||||
/* Pre-write readiness check — stock firmware 0x0DE9 calls wait_for_ready()
|
||||
* (0x2000) before each block. This polls A8 + additional conditions with
|
||||
* up to 10 retries. Our simplified version polls A8 only. */
|
||||
if (!bcm_poll_ready())
|
||||
return FALSE;
|
||||
|
||||
/* Page select = 0 */
|
||||
if (!bcm_direct_write(BCM_REG_PAGE, 0x00))
|
||||
return FALSE;
|
||||
@ -871,7 +877,34 @@ static BOOL bcm_write_init_block(const __code BYTE *data, BYTE len) {
|
||||
return FALSE;
|
||||
|
||||
/* Wait for BCM4500 to process the write */
|
||||
return bcm_poll_ready();
|
||||
if (!bcm_poll_ready())
|
||||
return FALSE;
|
||||
|
||||
/* Readback verification — stock firmware 0x0DDD does this after every
|
||||
* init block write. The BCM4500 may require the readback to finalize
|
||||
* the write (two-phase commit), or this catches silent write failures.
|
||||
*
|
||||
* Protocol (from disassembly at 0x0E61-0x0EE2):
|
||||
* 1. Re-select page 0 (A6 = 0x00)
|
||||
* 2. Read back len bytes from A7 into scratch buffer
|
||||
* 3. First readback byte has bit 7 set by BCM4500 — XOR to clear
|
||||
* 4. Compare all bytes against original data
|
||||
*/
|
||||
if (!bcm_direct_write(BCM_REG_PAGE, 0x00))
|
||||
return FALSE;
|
||||
|
||||
if (!i2c_combined_read(BCM4500_ADDR, BCM_REG_DATA, len, i2c_rd))
|
||||
return FALSE;
|
||||
|
||||
/* BCM4500 sets bit 7 of the block address byte in readback */
|
||||
i2c_rd[0] ^= 0x80;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i2c_rd[i] != data[i])
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user