]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blobdiff - sw/app/rocon/appl_usb.c
RoCoN: compute USB engine event mask by function.
[fpga/lx-cpu1/lx-rocon.git] / sw / app / rocon / appl_usb.c
index 38dcd1389767768264de56523af4d499d4824460..f96b1f0e3cf4a3dd27675f65f09fb27819e809f5 100644 (file)
 usb_device_t usb_device;
 usb_ep_t eps[NUM_ENDPOINTS];
 
-#define MASK_EP1RX 0x01
-#define MASK_EP1TX 0x02
-
-unsigned char ep1_rx_buff[USB_MAX_PACKET] __attribute__ ((aligned (8)));
-unsigned char ep1_tx_buff[USB_MAX_PACKET] __attribute__ ((aligned (8)));
+#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[USB_MAX_PACKET] __attribute__ ((aligned (8)));
+unsigned char cdc0_ep_rx_buff[USB_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;
+
 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
 
@@ -226,6 +235,15 @@ int usb_spi_flash_pkt_rd(struct usb_ep_t *ep, int len, int code)
   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
@@ -408,6 +426,12 @@ int appl_usb_vendor(usb_device_t *udev)
       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));
@@ -514,18 +538,38 @@ int usb_app_fill_serial_number(uint32_t ul_sn)
   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 = USB_MAX_PACKET;
+  eps[CDC0_EPIDX_TXD].max_packet_size = USB_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;
@@ -534,6 +578,7 @@ int usb_app_init(void)
   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);
@@ -541,21 +586,22 @@ int usb_app_init(void)
   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 == USB_MAX_PACKET);
+    cdc0_tx_index = 0;
+    cdc0_tx_ready = 0;
     hal_gpio_set_value(LED2_PIN, 0);
     return 1;
   }
@@ -571,18 +617,26 @@ int usb_app_poll(void)
   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, USB_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;
 }
@@ -597,26 +651,26 @@ int usb_app_stop(void)
 
 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 >= USB_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 >= USB_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;
 }