int cpld_altera_fw_update()

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;
}