usb_request_status_t usb_vendor_request_write_spiflash( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { uint32_t addr = 0; uint16_t len = 0; if (stage == USB_TRANSFER_STAGE_SETUP) { addr = (endpoint->setup.value << 16) | endpoint->setup.index; len = endpoint->setup.length; if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes) || ((addr + len) > spi_flash.num_bytes)) { return USB_REQUEST_STATUS_STALL; } else { usb_transfer_schedule_block(endpoint->out, &spiflash_buffer[0], len, NULL, NULL); spi_bus_start(spi_flash.bus, &ssp_config_w25q80bv); w25q80bv_setup(&spi_flash); return USB_REQUEST_STATUS_OK; } } else if (stage == USB_TRANSFER_STAGE_DATA) { addr = (endpoint->setup.value << 16) | endpoint->setup.index; len = endpoint->setup.length; /* This check is redundant but makes me feel better. */ if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes) || ((addr + len) > spi_flash.num_bytes)) { return USB_REQUEST_STATUS_STALL; } else { w25q80bv_program(&spi_flash, addr, len, &spiflash_buffer[0]); usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } } else { return USB_REQUEST_STATUS_OK; } }
int main(void) { int i; uint8_t buf[515]; pin_setup(); enable_1v8_power(); cpu_clock_init(); /* program test data to SPI flash */ for (i = 0; i < 515; i++) buf[i] = (i * 3) & 0xFF; w25q80bv_setup(); w25q80bv_chip_erase(); w25q80bv_program(790, 515, &buf[0]); /* blink LED1 and LED3 */ while (1) { gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED3)); /* LEDs on */ for (i = 0; i < 8000000; i++) /* Wait a bit. */ __asm__("nop"); gpio_clear(PORT_LED1_3, (PIN_LED1|PIN_LED3)); /* LED off */ for (i = 0; i < 8000000; i++) /* Wait a bit. */ __asm__("nop"); } return 0; }