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;
	}
}
예제 #2
0
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;
}
usb_request_status_t usb_vendor_request_erase_spiflash(
		usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
{
	if (stage == USB_TRANSFER_STAGE_SETUP) {
		spi_bus_start(spi_flash.bus, &ssp_config_w25q80bv);
		w25q80bv_setup(&spi_flash);
		/* only chip erase is implemented */
		w25q80bv_chip_erase(&spi_flash);
		usb_transfer_schedule_ack(endpoint->in);
	}
	return USB_REQUEST_STATUS_OK;
}
예제 #4
0
isp_iap_ret_code_t iap_cmd_call(iap_cmd_res_t* iap_cmd_res) 
{
  uint32_t* p_u32_data;
  
  if( iap_is_implemented() )
  {
    pROM_API->IAP( (uint32_t*)&iap_cmd_res->cmd_param, (uint32_t*)&iap_cmd_res->status_res);
  }else
  {
    /* 
      Alternative way to retrieve Part Id on MCU with no IAP 
      Read Serial No => Read Unique ID in SPIFI (only compatible with W25Q80BV)
    */
    w25q80bv_setup();

    switch(iap_cmd_res->cmd_param.command_code)
    {
      case IAP_CMD_READ_PART_ID_NO:
        p_u32_data = (uint32_t*)CHIP_PART_ID;
        iap_cmd_res->status_res.iap_result[0] = p_u32_data[0];
        p_u32_data = (uint32_t*)ROM_OTP_PART_ID_ADDR;
        iap_cmd_res->status_res.iap_result[1] = p_u32_data[0];
        iap_cmd_res->status_res.status_ret = CMD_SUCCESS;
      break;
      
      case IAP_CMD_READ_SERIAL_NO:
        /* Only 64bits used */
        iap_cmd_res->status_res.iap_result[0] = 0;
        iap_cmd_res->status_res.iap_result[1] = 0;
        w25q80bv_get_unique_id( (w25q80bv_unique_id_t*)&iap_cmd_res->status_res.iap_result[2] );
        iap_cmd_res->status_res.status_ret = CMD_SUCCESS;
      break;
      
      default:
        iap_cmd_res->status_res.status_ret = ERROR_IAP_NOT_IMPLEMENTED;
      break;
    }
  }
  return iap_cmd_res->status_res.status_ret;
}