in meta-facebook/yv35-bb/src/sensor/dev/altera.c [107:171]
int cpld_altera_fw_update(uint32_t offset, uint16_t msg_len, uint8_t *msg)
{
uint32_t buffer_offset = 0;
int addr = 0, byte = 0, data = 0;
int ret = 0;
int receive_buffer[4]; // for received data
int retry = MAX_RETRY;
uint8_t status = 0;
bool is_done = false;
buffer_offset = 0;
for (addr = (CFM_START_ADDR + offset); addr < (CFM_START_ADDR + offset + msg_len);
addr += 4) {
// Get 4 bytes
receive_buffer[0] = msg[buffer_offset + 0];
receive_buffer[1] = msg[buffer_offset + 1];
receive_buffer[2] = msg[buffer_offset + 2];
receive_buffer[3] = msg[buffer_offset + 3];
// Swap LSB with MSB before write into CFM
for (byte = 0; byte < 4; byte++) {
receive_buffer[byte] = (((receive_buffer[byte] & 0xaa) >> 1) |
((receive_buffer[byte] & 0x55) << 1));
receive_buffer[byte] = (((receive_buffer[byte] & 0xcc) >> 2) |
((receive_buffer[byte] & 0x33) << 2));
receive_buffer[byte] = (((receive_buffer[byte] & 0xf0) >> 4) |
((receive_buffer[byte] & 0x0f) << 4));
}
// Combine 4 bytes to 1 word before write operation
data = (receive_buffer[3] << 24) | (receive_buffer[2] << 16) |
(receive_buffer[1] << 8) | (receive_buffer[0]);
ret = max10_write_flash_data(addr, data);
if (ret != 0) {
printf("[CPLD] write flash data failed\n");
return fwupdate_update_fail;
}
// Check write successful
is_done = false;
retry = MAX_RETRY;
do {
status = max10_status_read();
status &= STATUS_BIT_MASK;
if ((status & WRITE_SUCCESS) == WRITE_SUCCESS) {
is_done = true;
} else {
printf("status: %x retry...\n", status);
k_usleep(100);
retry--;
}
} while ((is_done == false) && (retry > 0));
if (retry == 0) {
return fwupdate_update_fail;
}
buffer_offset += 4;
}
return fwupdate_success;
}