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) */
|
/* I2C scratch buffers in xdata (24 bytes: fits 20-byte EEPROM blocks) */
|
||||||
static __xdata BYTE i2c_buf[24];
|
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 */
|
/* TUNE_MONITOR result buffer: filled by OUT phase, returned by IN phase */
|
||||||
static __xdata BYTE tm_result[10];
|
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) {
|
static BOOL bcm_write_init_block(const __code BYTE *data, BYTE len) {
|
||||||
BYTE i;
|
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 */
|
/* Page select = 0 */
|
||||||
if (!bcm_direct_write(BCM_REG_PAGE, 0x00))
|
if (!bcm_direct_write(BCM_REG_PAGE, 0x00))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -871,7 +877,34 @@ static BOOL bcm_write_init_block(const __code BYTE *data, BYTE len) {
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Wait for BCM4500 to process the write */
|
/* 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