-#include <types.h>
+#include <inttypes.h>
#include <cpu_def.h>
#include <system_def.h>
#include <string.h>
#include <stdio.h>
+#include <stdint.h>
#include <endian.h>
#include <usb/lpc.h>
#include <usb/usb.h>
#include <hal_machperiph.h>
#endif /*CONFIG_KEYVAL*/
+#ifdef CONFIG_OC_MTD_DRV_SYSLESS
+#include <mtd_spi_drv.h>
+#endif
+
#include <endian.h>
#if __BYTE_ORDER == __BIG_ENDIAN
#include <byteswap.h>
#define SWAP(x) (x)
#endif
-#define USB_CMD_FPGA_CONFIGURE 0xF000
+#define USB_VENDOR_TARGET_TUMBL 0x03
+#define USB_VENDOR_TARGET_32BIT 0x04
+#define USB_VENDOR_TARGET_SPI_FLASH 0x05
+
+#define USB_CMD_FPGA_CONFIGURE 0xF000
+#define USB_CMD_FPGA_MEASURE_READ 0xF001
+#define USB_CMD_FPGA_MEASURE_WRITE 0xF002
+
+#define USB_CMD_FPGA_IRC_GET_RESET 0xF010
+#define USB_CMD_FPGA_IRC_SET_RESET 0xF011
+#define USB_CMD_FPGA_IRC_DUMP 0xF012
+
+#define USB_CMD_FPGA_LXMASTER_GET_RESET 0xF020
+#define USB_CMD_FPGA_LXMASTER_SET_RESET 0xF021
+#define USB_CMD_FPGA_LXMASTER_TRANSMITTER_GET_REG 0xF022
+#define USB_CMD_FPGA_LXMASTER_TRANSMITTER_SET_REG 0xF023
+#define USB_CMD_FPGA_LXMASTER_TRANSMITTER_WRITE 0xF024
+#define USB_CMD_FPGA_LXMASTER_TRANSMITTER_DUMP 0xF025
+
+#define USB_CMD_FPGA_TUMBL_SET_RESET 0xF100
+#define USB_CMD_FPGA_TUMBL_SET_HALT 0xF101
+#define USB_CMD_FPGA_TUMBL_SET_TRACE 0xF102
+#define USB_CMD_FPGA_TUMBL_KICK_TRACE 0xF103
+#define USB_CMD_FPGA_TUMBL_GET_PC 0xF104
+
+#define USB_CMD_FPGA_TUMBL_DUMP_IMEM 0xF200
+#define USB_CMD_FPGA_TUMBL_DUMP_DMEM 0xF201
+
+#define USB_CMD_FPGA_RESET 0xFFFF
usb_device_t usb_device;
usb_ep_t eps[NUM_ENDPOINTS];
-#define MASK_EP1RX 0x01
-#define MASK_EP1TX 0x02
+#define CDC0_EPIDX_NOTIFY 0
+#define CDC0_EPIDX_RXD 1
+#define CDC0_EPIDX_TXD 2
+#define CDC0_MASK_EP_NOTIFY (1<<CDC0_EPIDX_NOTIFY)
+#define CDC0_MASK_EP_RXD (1<<CDC0_EPIDX_RXD)
+#define CDC0_MASK_EP_TXD (1<<CDC0_EPIDX_TXD)
+
+unsigned char cdc0_ep_tx_buff[CDC0_MAX_PACKET] __attribute__ ((aligned (8)));
+unsigned char cdc0_ep_rx_buff[CDC0_MAX_PACKET] __attribute__ ((aligned (8)));
+unsigned char ep0_buffer[USB_MAX_PACKET0] __attribute__ ((aligned (8)));
+int cdc0_tx_index = 0, cdc0_tx_ready = 1;
+int cdc0_tx_flush_required;
+int cdc0_rx_index = 0, cdc0_rx_chars = 0;
+
+uint16_t cdc0_serial_state = 0; /* USBCDC_SERIAL_STATE_xxx */
+acm_desc_t usbcdc_acm_description;
-unsigned char ep1_rx_buff[USB_MAX_PACKET];
-unsigned char ep1_tx_buff[USB_MAX_PACKET];
-unsigned char ep0_buffer[USB_MAX_PACKET0];
int usb_active = 0;
-int ep1_rx_index = 0, ep1_rx_ready = 1;
-int ep1_tx_index = 0, ep1_tx_chars = 0;
#ifdef CONFIG_OC_CMDPROC
return USB_COMPLETE_OK;
}
+static int usb_tumbl_pkt_wr(struct usb_ep_t *ep, int len, int code)
+{
+ unsigned char *ptr = ep->ptr - len;
+
+ fpga_tumbl_write(ep->user_data, ptr, len);
+
+ ep->user_data += len;
+ ep->ptr = ep0_buffer;
+ return USB_COMPLETE_OK;
+}
+
+static int usb_32bit_pkt_wr(struct usb_ep_t *ep, int len, int code)
+{
+ uint32_t *srcptr = (uint32_t *)(ep->ptr - len);
+ volatile uint32_t *dstptr = (uint32_t *)ep->user_data;
+ int pos;
+
+ for (pos = 0; len - pos >= 4; pos += 4, dstptr++, srcptr++)
+ *dstptr = *srcptr;
+
+ ep->user_data += len;
+ ep->ptr = ep0_buffer;
+ return USB_COMPLETE_OK;
+}
+
+int usb_32bit_pkt_rd(struct usb_ep_t *ep, int len, int code)
+{
+ volatile uint32_t *srcptr;
+ uint32_t *dstptr;
+ int pos;
+
+ ep->ptr = ep0_buffer;
+ dstptr = (uint32_t *)ep->ptr;
+ srcptr = (uint32_t *)ep->user_data;
+
+ for (pos = 0; len - pos >= 4; pos += 4, dstptr++, srcptr++)
+ *dstptr = *srcptr;
+
+ ep->user_data += len;
+ return USB_COMPLETE_OK;
+}
+
static int usb_flash_erase(unsigned addr, unsigned len)
{
#ifdef CONFIG_KEYVAL
return 0;
}
+static int usb_spi_flash_pkt_wr(struct usb_ep_t *ep, int len, int code)
+{
+ unsigned char *ptr = ep->ptr - len;
+
+#ifdef CONFIG_OC_MTD_DRV_SYSLESS
+ mtd_spi_write(&mtd_spi_state, ptr, len, ep->user_data, 0);
+#endif /*CONFIG_KEYVAL*/
+
+ ep->user_data += len;
+ ep->ptr = ep0_buffer;
+ return USB_COMPLETE_OK;
+}
+
+int usb_spi_flash_pkt_rd(struct usb_ep_t *ep, int len, int code)
+{
+ ep->ptr = ep0_buffer;
+#ifdef CONFIG_OC_MTD_DRV_SYSLESS
+ mtd_spi_read(&mtd_spi_state, ep->ptr, len, ep->user_data, 0);
+#endif /*CONFIG_KEYVAL*/
+
+ ep->user_data += len;
+ return USB_COMPLETE_OK;
+}
+
+int usb_spi_flash_mass_erase(int mode)
+{
+#ifdef CONFIG_OC_MTD_DRV_SYSLESS
+ mtd_spi_set_protect_mode(&mtd_spi_state, 0, 0);
+ mtd_spi_chip_erase(&mtd_spi_state, mode, 0);
+#endif /*CONFIG_KEYVAL*/
+ return 0;
+}
+
static void usb_goto(unsigned address)
{
#ifdef CONFIG_KEYVAL
uint16_t appl_usb_vendor_call(uint16_t command, uint16_t argument)
{
- if (command == USB_CMD_FPGA_CONFIGURE)
- return appl_fpga_configure();
+ int i, j;
+
+ switch (command)
+ {
+ case USB_CMD_FPGA_CONFIGURE:
+ return fpga_configure();
+
+ case USB_CMD_FPGA_MEASURE_READ:
+ return fpga_measure_bus_read();
+
+ case USB_CMD_FPGA_MEASURE_WRITE:
+ return fpga_measure_bus_write();
+
+ case USB_CMD_FPGA_IRC_GET_RESET:
+ printf("IRC RESET: 0x%02x\n", *fpga_irc_reset);
+ return 0;
+
+ case USB_CMD_FPGA_IRC_SET_RESET:
+ /* When starting, zero out counters */
+ *fpga_irc_reset = argument & 0x0001;
+ return 0;
+
+ case USB_CMD_FPGA_IRC_DUMP:
+ for (i = 0; i < 8; i++)
+ printf("IRC%d: count = %d, count index = %d, mark = %d, ab_error = %d, index_event = %d, index = %d\n", i+1,
+ (unsigned int) fpga_irc[i]->count, (unsigned int) fpga_irc[i]->count_index, ((*(fpga_irc_state[i])) & 0x01) != 0,
+ ((*(fpga_irc_state[i])) & 0x02) != 0, ((*(fpga_irc_state[i])) & 0x04) != 0, ((*(fpga_irc_state[i])) & 0x08) != 0);
+ return 0;
+
+ case USB_CMD_FPGA_LXMASTER_GET_RESET:
+ printf("LXMASTER RESET: 0x%02"PRIx32"\n", *fpga_lx_master_reset);
+ return 0;
+
+ case USB_CMD_FPGA_LXMASTER_SET_RESET:
+ /* When starting, zero out counters */
+ *fpga_lx_master_reset = argument & 0x0001;
+ return 0;
+
+ case USB_CMD_FPGA_LXMASTER_TRANSMITTER_GET_REG:
+ printf("LXMASTER TRANSMITTER REG: 0x%02"PRIx32"\n", *fpga_lx_master_transmitter_reg);
+ return 0;
+
+ case USB_CMD_FPGA_LXMASTER_TRANSMITTER_SET_REG:
+ /* When starting, zero out counters */
+ *fpga_lx_master_transmitter_reg = argument & 0x0001;
+ return 0;
+
+ case USB_CMD_FPGA_LXMASTER_TRANSMITTER_WRITE:
+ for (i = 0; i < (argument / 4); i++)
+ fpga_lx_master_transmitter_base[i] = fpga_lx_master_conf[i];
+ return 0;
+
+ case USB_CMD_FPGA_LXMASTER_TRANSMITTER_DUMP:
+ printf("LX MASTER TRANSMITTER MEM:\n");
+ for (i = 0; i < 16; i++)
+ {
+ for (j = 0; j < 16; j++)
+ printf("%04X ", (unsigned int) (fpga_lx_master_transmitter_base[i*16 + j] & 0xFFFF));
+
+ printf("\n");
+ }
+ return 0;
+
+ case USB_CMD_FPGA_TUMBL_SET_RESET:
+ return fpga_tumbl_set_reset(argument);
+
+ case USB_CMD_FPGA_TUMBL_SET_HALT:
+ return fpga_tumbl_set_halt(argument);
+
+ case USB_CMD_FPGA_TUMBL_SET_TRACE:
+ return fpga_tumbl_set_trace(argument);
+
+ case USB_CMD_FPGA_TUMBL_KICK_TRACE:
+ return fpga_tumbl_kick_trace();
+
+ case USB_CMD_FPGA_TUMBL_GET_PC:
+ printf("Tubml PC: 0x%08X\n", (unsigned int) *fpga_tumbl_pc);
+ return 0;
+
+ case USB_CMD_FPGA_TUMBL_DUMP_IMEM:
+ printf("TUMBL IMEM:\n");
+ for (i = 0; i < 64; i++)
+ {
+ for (j = 0; j < 8; j++)
+ printf("%08X ", (unsigned int) fpga_tumbl_imem[i*8 + j]);
+
+ printf("\n");
+ }
+ return 0;
+
+ case USB_CMD_FPGA_TUMBL_DUMP_DMEM:
+ printf("TUMBL DMEM:\n");
+ for (i = 0; i < 128; i++)
+ {
+ for (j = 0; j < 8; j++)
+ printf("%08X ", (unsigned int) fpga_tumbl_dmem[i*8 + j]);
+
+ printf("\n");
+ }
+ return 0;
+
+ case USB_CMD_FPGA_RESET:
+ hal_gpio_direction_output(XC_INIT_PIN, 0);
+
+ for (i = 0; i < 128; i++)
+ {}
+
+ hal_gpio_direction_output(XC_INIT_PIN, 1);
+ return 0;
+ }
return 0xFFFF;
}
usb_flash_erase((uint32_t)dreq->wValue << 10, dreq->wIndex << 10);
return 1;
+ case USB_VENDOR_MASS_ERASE:
+ usb_send_control_data(udev, NULL, 0);
+ if (dreq->wIndex == 5)
+ usb_spi_flash_mass_erase(dreq->wValue);
+ return 1;
+
case USB_VENDOR_CALL:
vendor_call_ret = SWAP(appl_usb_vendor_call(dreq->wIndex, dreq->wValue));
usb_send_control_data(udev, (unsigned char *) &vendor_call_ret, sizeof(uint16_t));
udev->ep0.ptr = ep0_buffer;
break;
+ case USB_VENDOR_TARGET_TUMBL:
+ udev->ep0.next_pkt_fnc = usb_tumbl_pkt_wr;
+ udev->ep0.user_data = addr;
+ udev->ep0.ptr = ep0_buffer;
+ break;
+
+ case USB_VENDOR_TARGET_32BIT:
+ udev->ep0.next_pkt_fnc = usb_32bit_pkt_wr;
+ udev->ep0.user_data = addr;
+ udev->ep0.ptr = ep0_buffer;
+ break;
+
+ case USB_VENDOR_TARGET_SPI_FLASH:
+ udev->ep0.next_pkt_fnc = usb_spi_flash_pkt_wr;
+ udev->ep0.user_data = addr;
+ udev->ep0.ptr = ep0_buffer;
+ break;
+
default:
return -1;
}
usb_send_control_data(udev, (void *)addr, len);
break;
+ case USB_VENDOR_TARGET_32BIT:
+ udev->ep0.next_pkt_fnc = usb_32bit_pkt_rd;
+ udev->ep0.user_data=addr;
+ usb_send_control_data( udev, ep0_buffer, len);
+ break;
+
+ case USB_VENDOR_TARGET_SPI_FLASH:
+ udev->ep0.next_pkt_fnc = usb_spi_flash_pkt_rd;
+ udev->ep0.user_data=addr;
+ usb_send_control_data( udev, ep0_buffer, len);
+ break;
+
default:
return -1;
}
return 0;
}
+static inline
+int usb_app_epnum2event_mask(int epnum)
+{
+ int evmask;
+ int evbit;
+ /* LPC17xx EP1RX 0x04, EP1TX 0x08, EP2RX 0x10, EP2TX 0x20 */
+
+ evbit = (epnum & ~USB_ENDPOINT_DIRECTION_MASK) * 2;
+ if (epnum & USB_ENDPOINT_DIRECTION_MASK)
+ evbit++;
+
+ evmask = 1 << evbit;
+
+ return evmask;
+}
+
int usb_app_init(void)
{
memset(&usb_device, 0, sizeof(usb_device));
- eps[0].max_packet_size = USB_MAX_PACKET;
- eps[1].max_packet_size = USB_MAX_PACKET;
- eps[0].epnum = 0x81;
- eps[1].epnum = 0x01;
- eps[0].event_mask = 0x08;
- eps[1].event_mask = 0x04;
- eps[0].udev = &usb_device;
- eps[1].udev = &usb_device;
+ eps[CDC0_EPIDX_NOTIFY].max_packet_size = USB_MAX_PACKET;
+ eps[CDC0_EPIDX_RXD].max_packet_size = CDC0_MAX_PACKET;
+ eps[CDC0_EPIDX_TXD].max_packet_size = CDC0_MAX_PACKET;
+ eps[CDC0_EPIDX_NOTIFY].epnum = CDC0_EP_NOTIFY;
+ eps[CDC0_EPIDX_RXD].epnum = CDC0_EP_RXD;
+ eps[CDC0_EPIDX_TXD].epnum = CDC0_EP_TXD;
+ eps[CDC0_EPIDX_NOTIFY].event_mask = usb_app_epnum2event_mask(CDC0_EP_NOTIFY); /* 0x08; */
+ eps[CDC0_EPIDX_RXD].event_mask = usb_app_epnum2event_mask(CDC0_EP_RXD); /* 0x10; */
+ eps[CDC0_EPIDX_TXD].event_mask = usb_app_epnum2event_mask(CDC0_EP_TXD); /* 0x20; */
+ eps[CDC0_EPIDX_NOTIFY].udev = &usb_device;
+ eps[CDC0_EPIDX_RXD].udev = &usb_device;
+ eps[CDC0_EPIDX_TXD].udev = &usb_device;
usb_device.id = 1;
usb_device.devdes_table = &usb_devdes_table;
usb_device.cntep = NUM_ENDPOINTS;
usb_device.ep = eps;
usb_device.vendor_fnc = appl_usb_vendor;
+ usb_device.class_fnc = usbcdc_acm_class_response;
usb_init(&usb_device);
usb_connect(&usb_device);
return 0;
}
-int usb_check_ep1()
+int cdc0_txd_check_ep(void)
{
- if (usb_device.ep_events & MASK_EP1RX)
+ if (usb_device.ep_events & CDC0_MASK_EP_TXD)
{
- usb_device.ep_events &= ~MASK_EP1RX;
+ usb_device.ep_events &= ~CDC0_MASK_EP_TXD;
//TODO: Use some field in the structure, probably flags
- ep1_rx_ready = 1;
+ cdc0_tx_ready = 1;
}
/* Respond if there is something to send and RX is ready */
- if (ep1_rx_ready && ep1_rx_index != 0)
+ if (cdc0_tx_ready && ((cdc0_tx_index != 0) || cdc0_tx_flush_required))
{
- usb_udev_write_endpoint(&eps[0], ep1_rx_buff, ep1_rx_index);
- ep1_rx_index = 0;
- ep1_rx_ready = 0;
+ usb_udev_write_endpoint(&eps[CDC0_EPIDX_TXD], cdc0_ep_tx_buff, cdc0_tx_index);
+ cdc0_tx_flush_required = (cdc0_tx_index == CDC0_MAX_PACKET);
+ cdc0_tx_index = 0;
+ cdc0_tx_ready = 0;
hal_gpio_set_value(LED2_PIN, 0);
return 1;
}
usb_check_events(&usb_device);
usb_control_response(&usb_device);
- /* Check TX endpoint */
- if (usb_device.ep_events & MASK_EP1TX)
+ /* Check RXD/OUT endpoint */
+ if (usb_device.ep_events & CDC0_MASK_EP_NOTIFY)
+ {
+ usb_udev_read_endpoint(&eps[CDC0_EPIDX_NOTIFY], &cdc0_serial_state, 2);
+ usb_device.ep_events &= ~CDC0_MASK_EP_NOTIFY;
+ usb_active = 1;
+ }
+
+ /* Check RXD/OUT endpoint */
+ if (usb_device.ep_events & CDC0_MASK_EP_RXD)
{
- ep1_tx_chars = usb_udev_read_endpoint(&eps[1], ep1_tx_buff, USB_MAX_PACKET);
- ep1_tx_index = 0;
- usb_device.ep_events &= ~MASK_EP1TX;
+ cdc0_rx_chars = usb_udev_read_endpoint(&eps[CDC0_EPIDX_RXD], cdc0_ep_rx_buff, CDC0_MAX_PACKET);
+ cdc0_rx_index = 0;
+ usb_device.ep_events &= ~CDC0_MASK_EP_RXD;
hal_gpio_set_value(LED2_PIN, 0);
usb_active = 1;
}
/* Check RX endpoint */
- usb_active |= usb_check_ep1();
+ usb_active |= cdc0_txd_check_ep();
return active;
}
int cmd_io_getc_usbcon(struct cmd_io *cmd_io)
{
- if (ep1_tx_index >= ep1_tx_chars)
+ if (cdc0_rx_index >= cdc0_rx_chars)
return -1;
- return ep1_tx_buff[ep1_tx_index++];
+ return cdc0_ep_rx_buff[cdc0_rx_index++];
}
int cmd_io_putc_usbcon(struct cmd_io *cmd_io, int ch)
{
- if (ep1_rx_index >= USB_MAX_PACKET)
+ if (cdc0_tx_index >= CDC0_MAX_PACKET)
{
/* Check EP1 status and return -1 if unavailable */
usb_check_events(&usb_device);
- usb_check_ep1();
+ cdc0_txd_check_ep();
/* Check again if it wasn't emptied */
- if (ep1_rx_index >= USB_MAX_PACKET)
+ if (cdc0_tx_index >= CDC0_MAX_PACKET)
return -1;
}
- ep1_rx_buff[ep1_rx_index++] = (unsigned char)ch;
+ cdc0_ep_tx_buff[cdc0_tx_index++] = (unsigned char)ch;
return ch;
}