static void redraw_handler(struct widget *widget, void *data) { struct demoapp *app = data; cairo_t *cr; struct rectangle allocation; uint32_t time; widget_get_allocation(app->widget, &allocation); cr = widget_cairo_create(widget); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_rectangle(cr, allocation.x, allocation.y, allocation.width, allocation.height); cairo_set_source_rgba(cr, 0, 0.8, 0, 0.8); cairo_fill(cr); time = widget_get_last_time(widget); cairo_set_source_rgba(cr, 0.5, 1.0, 0.5, 1.0); draw_spinner(cr, &allocation, time); cairo_destroy(cr); DBG("%dx%d @ %d,%d, last time %u\n", allocation.width, allocation.height, allocation.x, allocation.y, time); }
int command_write_mem(int fd, uint32_t address, uint32_t size, uint8_t *buffer) { int res; uint32_t remaining = size; uint32_t addr_be; uint32_t cnt; uint8_t outbuf[257]; payload_t loads[2] = { {4, (uint8_t *)&addr_be}, {sizeof(outbuf), outbuf} }; while (remaining) { cnt = (remaining > PAGE_SIZE) ? PAGE_SIZE : remaining; addr_be = htonl(address); outbuf[0] = cnt - 1; loads[1].size = cnt + 1; memcpy(outbuf + 1, buffer, cnt); draw_spinner(remaining, size); fflush(stdout); res = send_command(fd, CMD_WRITEMEM, loads, 2, NULL, 0, 1); if (res < 0) return -EIO; buffer += cnt; address += cnt; remaining -= cnt; } return size; }
int command_read_mem(int fd, uint32_t address, uint32_t size, uint8_t *buffer) { int res; uint32_t remaining = size; uint32_t addr_be; uint8_t cnt; payload_t loads[2] = { {4, (uint8_t *)&addr_be}, {1, &cnt} }; while (remaining) { cnt = (remaining > PAGE_SIZE) ? PAGE_SIZE - 1 : remaining - 1; addr_be = htonl(address); draw_spinner(remaining, size); fflush(stdout); res = send_command(fd, CMD_READMEM, loads, 2, buffer, cnt + 1, 0); if (res < 0) return -EIO; buffer += cnt + 1; address += cnt + 1; remaining -= cnt + 1; } return size; }
int command_read_pages(struct ftdi_context *ftdi, uint32_t address, uint32_t size, uint8_t *buffer) { int res = -EIO; uint32_t remaining = size; int cnt; uint16_t page; if (spi_flash_follow_mode(ftdi, "fast read") < 0) goto failed_read; while (remaining) { uint8_t cmd = 0x9; cnt = (remaining > PAGE_SIZE) ? PAGE_SIZE : remaining; page = address / PAGE_SIZE; draw_spinner(remaining, size); /* Fast Read command */ if (spi_flash_command_short(ftdi, SPI_CMD_FAST_READ, "fast read") < 0) goto failed_read; res = i2c_write_byte(ftdi, 0x08, page >> 8); res += i2c_write_byte(ftdi, 0x08, page & 0xff); res += i2c_write_byte(ftdi, 0x08, 0x00); res += i2c_write_byte(ftdi, 0x08, 0x00); if (res < 0) { fprintf(stderr, "page address set failed\n"); goto failed_read; } /* read page data */ res = i2c_byte_transfer(ftdi, I2C_CMD_ADDR, &cmd, 1, 1); res = i2c_byte_transfer(ftdi, I2C_BLOCK_ADDR, buffer, 0, cnt); if (res < 0) { fprintf(stderr, "page data read failed\n"); goto failed_read; } address += cnt; remaining -= cnt; buffer += cnt; } /* No error so far */ res = size; failed_read: if (spi_flash_follow_mode_exit(ftdi, "fast read") < 0) res = -EIO; return res; }
static void sub_redraw_handler(struct widget *widget, void *data) { struct demoapp *app = data; cairo_t *cr; struct rectangle allocation; uint32_t time; widget_get_allocation(app->subsurface, &allocation); cr = widget_cairo_create(widget); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); /* debug: paint whole surface magenta; no magenta should show */ cairo_set_source_rgba(cr, 0.9, 0.0, 0.9, 1.0); cairo_paint(cr); cairo_rectangle(cr, allocation.x, allocation.y, allocation.width, allocation.height); cairo_clip(cr); cairo_set_source_rgba(cr, 0.8, 0, 0, 0.8); cairo_paint(cr); time = widget_get_last_time(widget); cairo_set_source_rgba(cr, 1.0, 0.5, 0.5, 1.0); draw_spinner(cr, &allocation, time); cairo_destroy(cr); if (app->animate) widget_schedule_redraw(app->subsurface); DBG("%dx%d @ %d,%d, last time %u\n", allocation.width, allocation.height, allocation.x, allocation.y, time); }
int command_erase(struct ftdi_context *ftdi, uint32_t len, uint32_t off) { int res = -EIO; int page = 0; uint32_t remaining = len; printf("Erasing chip...\n"); if (off != 0 || len != flash_size) { fprintf(stderr, "Only full chip erase is supported\n"); return -EINVAL; } if (spi_flash_follow_mode(ftdi, "erase") < 0) goto failed_erase; while (remaining) { draw_spinner(remaining, len); if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_ENABLE, "write enable for erase") < 0) goto failed_erase; if (spi_check_write_enable(ftdi, "erase") < 0) goto failed_erase; /* do chip erase */ if (remaining == flash_size) { if (spi_flash_command_short(ftdi, SPI_CMD_CHIP_ERASE, "chip erase") < 0) goto failed_erase; goto wait_busy_cleared; } /* do sector erase */ if (spi_flash_command_short(ftdi, SPI_CMD_SECTOR_ERASE, "sector erase") < 0) goto failed_erase; if (spi_flash_set_erase_page(ftdi, page, "sector erase") < 0) goto failed_erase; wait_busy_cleared: if (spi_poll_busy(ftdi, "erase") < 0) goto failed_erase; if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_DISABLE, "write disable for erase") < 0) goto failed_erase; if (remaining == flash_size) { remaining = 0; draw_spinner(remaining, len); } else { page += SECTOR_ERASE_PAGES; remaining -= SECTOR_ERASE_PAGES * PAGE_SIZE; } } /* No error so far */ res = 0; failed_erase: if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_DISABLE, "write disable exit erase") < 0) res = -EIO; if (spi_flash_follow_mode_exit(ftdi, "erase") < 0) res = -EIO; printf("\n"); return res; }
int command_write_pages(struct ftdi_context *ftdi, uint32_t address, uint32_t size, uint8_t *buffer) { int res = -EIO; uint32_t remaining = size; int cnt; uint8_t page; uint8_t cmd; if (spi_flash_follow_mode(ftdi, "AAI write") < 0) goto failed_write; while (remaining) { cnt = (remaining > BLOCK_WRITE_SIZE) ? BLOCK_WRITE_SIZE : remaining; page = address / BLOCK_WRITE_SIZE; draw_spinner(remaining, size); /* Write enable */ if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_ENABLE, "write enable for AAI write") < 0) goto failed_write; /* Check write enable bit */ if (spi_check_write_enable(ftdi, "AAI write") < 0) goto failed_write; /* Setup write */ if (spi_flash_command_short(ftdi, SPI_CMD_WORD_PROGRAM, "AAI write") < 0) goto failed_write; /* Set page */ cmd = 0; res = i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &page, 1, 1); res |= i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &cmd, 1, 1); res |= i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &cmd, 1, 1); if (res < 0) { fprintf(stderr, "Flash write set page FAILED (%d)\n", res); goto failed_write; } /* Wait until not busy */ if (spi_poll_busy(ftdi, "AAI write") < 0) goto failed_write; /* Write up to BLOCK_WRITE_SIZE data */ res = i2c_write_byte(ftdi, 0x10, 0x20); res = i2c_byte_transfer(ftdi, I2C_BLOCK_ADDR, buffer, 1, cnt); buffer += cnt; if (res < 0) { fprintf(stderr, "Flash data write failed\n"); goto failed_write; } cmd = 0xff; res = i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &cmd, 1, 1); res |= i2c_write_byte(ftdi, 0x10, 0x00); if (res < 0) { fprintf(stderr, "Flash end data write FAILED (%d)\n", res); goto failed_write; } /* Write disable */ if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_DISABLE, "write disable for AAI write") < 0) goto failed_write; /* Wait until available */ if (spi_poll_busy(ftdi, "write disable for AAI write") < 0) goto failed_write; address += cnt; remaining -= cnt; } /* No error so far */ res = size; failed_write: if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_DISABLE, "write disable exit AAI write") < 0) res = -EIO; if (spi_flash_follow_mode_exit(ftdi, "AAI write") < 0) res = -EIO; return res; }