fork(3) download
  1. /*
  2. ** v2dap.c
  3. **
  4. ** Copyright ? 2010-2011 Future Technology Devices International Limited
  5. **
  6. ** C Source file for Vinculum II V2DAP Configuration and State Machine
  7. ** Main module
  8. **
  9. ** Author: FTDI
  10. ** Project: Vinculum II
  11. ** Module: Vinculum II Applications
  12. ** Requires: VOS
  13. ** Comments: Refer to VNC1L Firmware User Manual for detailed information on operation
  14. **
  15. ** History:
  16. ** 1 ? Initial version
  17. **
  18. */
  19.  
  20. #include "vos.h"
  21.  
  22. #include "stdlib.h"
  23.  
  24. #include "SPISlave.h"
  25. #include "FIFO.h"
  26. #include "UART.h"
  27. #include "USBHost.h"
  28. #include "USB.h"
  29. #include "msi.h"
  30. #include "BOMS.h"
  31. #include "FAT.h"
  32.  
  33. #include "host.h"
  34. #include "v2dap.h"
  35. #include "monitor.h"
  36. #include "cfgmonitor.h"
  37. #include "disk.h"
  38.  
  39. VOS_HANDLE hMonitor;
  40. VOS_HANDLE hBoms;
  41. VOS_HANDLE hUsb2;
  42.  
  43. unsigned char monInterface; // Interface to the monitor.
  44. #define UART 0
  45.  
  46. // driver context structure
  47. fat_context fatContext;
  48.  
  49. // thread control block for the monitor
  50. vos_tcb_t *tcbMonitor;
  51. vos_tcb_t *tcbMonitor2;
  52.  
  53. // forward declarations
  54. void firmware(void);
  55.  
  56. unsigned char checkDataMode(void);
  57. void ackDataMode(void);
  58. void ackCmdMode(void);
  59. void msgOnline(void);
  60. usbDevList *cdcSetup(void);
  61. unsigned char cdcGetSerialState(VOS_HANDLE hUsbHost, usbhost_ep_handle_ex ep, char *serialState);
  62.  
  63. /*
  64. ** main
  65. **
  66. ** Entry point for application
  67. **
  68. ** Parameters: none
  69. ** Returns: none
  70. ** never returns
  71. ** Requires: VOS kernel
  72. ** Comments: Intialise firmware before calling scheduler
  73. */
  74. void main(void)
  75. {
  76. common_ioctl_cb_t monitor_iocb;
  77. uart_context_t uart_ctx;
  78. usbhost_context_t usb_ctx;
  79. unsigned char dataBuf;
  80. unsigned short numRead;
  81. unsigned char monInt;
  82.  
  83. // coinfigure UART, FIFO and SPISlave context structures
  84. uart_ctx.buffer_size = VOS_BUFFER_SIZE_128_BYTES;
  85.  
  86. // call VOS initialisation routines
  87. vos_init(10, VOS_TICK_INTERVAL, NUMBER_OF_DEVICES);
  88. vos_set_idle_thread_tcb_size(0x100);
  89. vos_set_clock_frequency(VOS_48MHZ_CLOCK_FREQUENCY);
  90.  
  91. // initialise USB Host device driver
  92. usb_ctx.if_count = 16;
  93. usb_ctx.ep_count = 32;
  94. usb_ctx.xfer_count = 2;
  95. usb_ctx.iso_xfer_count = 1;
  96. usbhost_init(VOS_DEV_USB1, VOS_DEV_USB2, &usb_ctx);
  97.  
  98. // initialise BOMS device driver
  99. boms_init(VOS_DEV_BOMS);
  100.  
  101. uart_init(VOS_DEV_MON, &uart_ctx);
  102. monInterface = UART;
  103.  
  104.  
  105. // configure the IOMUX depending on the monitor interface selected
  106.  
  107. /* GPIO Configuration
  108. VNC1L Port VNC2 GPIO Port
  109. AD C
  110. AC D
  111. BD A
  112. BC B
  113. */
  114. if (vos_get_package_type() == VINCULUM_II_48_PIN)
  115. {
  116. // BD0 -> Pin 11
  117. vos_iomux_define_bidi(11, IOMUX_IN_GPIO_PORT_A_0, IOMUX_OUT_GPIO_PORT_A_0);
  118. // BD1 -> Pin 12
  119. vos_iomux_define_bidi(12, IOMUX_IN_GPIO_PORT_A_1, IOMUX_OUT_GPIO_PORT_A_1);
  120. // BD2 -> Pin 13
  121. vos_iomux_define_bidi(13, IOMUX_IN_GPIO_PORT_A_2, IOMUX_OUT_GPIO_PORT_A_2);
  122. // BD3 -> Pin 14
  123. vos_iomux_define_bidi(14, IOMUX_IN_GPIO_PORT_A_3, IOMUX_OUT_GPIO_PORT_A_3);
  124. // BD4 -> Pin 15
  125. vos_iomux_define_bidi(15, IOMUX_IN_GPIO_PORT_A_4, IOMUX_OUT_GPIO_PORT_A_4);
  126. // BD5 -> Pin 16
  127. vos_iomux_define_bidi(16, IOMUX_IN_GPIO_PORT_A_5, IOMUX_OUT_GPIO_PORT_A_5);
  128. // BD6 -> Pin 18
  129. vos_iomux_define_bidi(18, IOMUX_IN_GPIO_PORT_A_6, IOMUX_OUT_GPIO_PORT_A_6);
  130. // BD7 -> Pin 19
  131. vos_iomux_define_bidi(19, IOMUX_IN_GPIO_PORT_A_7, IOMUX_OUT_GPIO_PORT_A_7);
  132.  
  133. // BC0 -> Pin 20
  134. vos_iomux_define_bidi(20, IOMUX_IN_GPIO_PORT_B_0, IOMUX_OUT_GPIO_PORT_B_0);
  135. // BC1 -> Pin 21
  136. vos_iomux_define_bidi(21, IOMUX_IN_GPIO_PORT_B_1, IOMUX_OUT_GPIO_PORT_B_1);
  137. // BC2 -> Pin 22
  138. vos_iomux_define_bidi(22, IOMUX_IN_GPIO_PORT_B_2, IOMUX_OUT_GPIO_PORT_B_2);
  139. // BC3 -> Pin 23
  140. vos_iomux_define_bidi(23, IOMUX_IN_GPIO_PORT_B_3, IOMUX_OUT_GPIO_PORT_B_3);
  141.  
  142. // TXD -> Pin 31
  143. // RXD -> Pin 32
  144. // RTS# -> Pin 33
  145. // CTS# -> Pin 34
  146. // DTR# (DATAACK#) -> Pin 35
  147. // AD4 -> Pin 35
  148. vos_iomux_define_output(35, IOMUX_OUT_GPIO_PORT_C_4);
  149. // DSR# (DATAREQ#) -> Pin 36
  150. // AD5 -> Pin 36
  151. vos_iomux_define_input(36, IOMUX_IN_GPIO_PORT_C_5);
  152. // DCD# -> Pin 37
  153. // RI# -> Pin 38
  154. // TXDEN# -> Pin 41
  155.  
  156. // AC1 -> Pin 42
  157. vos_iomux_define_bidi(42, IOMUX_IN_GPIO_PORT_D_1, IOMUX_OUT_GPIO_PORT_D_1);
  158. // AC2 -> Pin 43
  159. vos_iomux_define_bidi(43, IOMUX_IN_GPIO_PORT_D_2, IOMUX_OUT_GPIO_PORT_D_2);
  160. // AC3 -> Pin 44
  161. vos_iomux_define_bidi(44, IOMUX_IN_GPIO_PORT_D_3, IOMUX_OUT_GPIO_PORT_D_3);
  162. // AC4 -> Pin 45
  163. vos_iomux_define_bidi(45, IOMUX_IN_GPIO_PORT_D_4, IOMUX_OUT_GPIO_PORT_D_4);
  164. // AC5 -> Pin 46
  165. vos_iomux_define_bidi(46, IOMUX_IN_GPIO_PORT_D_5, IOMUX_OUT_GPIO_PORT_D_5);
  166.  
  167. // ACBUS6
  168. vos_iomux_define_bidi(47, IOMUX_IN_GPIO_PORT_D_6, IOMUX_OUT_GPIO_PORT_D_6);
  169. // ACBUS7
  170. vos_iomux_define_bidi(48, IOMUX_IN_GPIO_PORT_D_7, IOMUX_OUT_GPIO_PORT_D_7);
  171. }
  172.  
  173. // setup for 64 pin package is to only allow UART interface
  174. if (vos_get_package_type() == VINCULUM_II_64_PIN)
  175. {
  176. // BD1 -> Pin 12 -> V2EVAL Board LED 3
  177. vos_iomux_define_output(12, IOMUX_OUT_GPIO_PORT_A_1);
  178. // BD2 -> Pin 13 -> V2EVAL Board LED 4
  179. vos_iomux_define_output(13, IOMUX_OUT_GPIO_PORT_A_2);
  180. // BD5 -> Pin 29 -> V2EVAL Board LED 5
  181. vos_iomux_define_output(29, IOMUX_OUT_GPIO_PORT_A_5);
  182. // BD6 -> Pin 31 -> V2EVAL Board LED 6
  183. vos_iomux_define_output(31, IOMUX_OUT_GPIO_PORT_A_6);
  184.  
  185. // UART Defaults
  186. // TXD -> Pin 39
  187. vos_iomux_define_output(39, IOMUX_OUT_UART_TXD);
  188. // RXD -> Pin 40
  189. vos_iomux_define_input(40, IOMUX_IN_UART_RXD);
  190. // RTS# -> Pin 41
  191. vos_iomux_define_output(41, IOMUX_OUT_UART_RTS_N);
  192. // CTS# -> Pin 42
  193. vos_iomux_define_input(42, IOMUX_IN_UART_CTS_N);
  194. // DTR# (DATAACK#) -> Pin 43
  195. vos_iomux_define_output(43, IOMUX_OUT_GPIO_PORT_C_4);
  196. // DSR# (DATAREQ#) -> Pin 44
  197. vos_iomux_define_input(44, IOMUX_IN_GPIO_PORT_C_5);
  198. // DCD# -> Pin 45
  199. // RI# -> Pin 46
  200. // TXDEN# -> Pin 47
  201. }
  202.  
  203. if (vos_get_package_type() == VINCULUM_II_32_PIN)
  204. {
  205. // UART Defaults
  206. // TXD -> Pin 23
  207. vos_iomux_define_output(23, IOMUX_OUT_UART_TXD);
  208. // RXD -> Pin 24
  209. vos_iomux_define_input(24, IOMUX_IN_UART_RXD);
  210. // RTS# -> Pin 25
  211. vos_iomux_define_output(25, IOMUX_OUT_UART_RTS_N);
  212. // CTS# -> Pin 26
  213. vos_iomux_define_input(26, IOMUX_IN_UART_CTS_N);
  214. // BC0 -> Pin 29
  215. vos_iomux_define_output(29, IOMUX_OUT_GPIO_PORT_B_0);
  216. // BC1 -> Pin 30
  217. vos_iomux_define_input(30, IOMUX_IN_GPIO_PORT_B_1);
  218. }
  219.  
  220. // create threads for firmware application
  221. tcbMonitor = vos_create_thread_ex(20, SIZEOF_FIRMWARE_TASK_MEMORY, firmware, "Application", 0);
  222.  
  223. // start VOS scheduler
  224. vos_start_scheduler();
  225.  
  226. main_loop:
  227. goto main_loop;
  228. }
  229.  
  230. /*
  231. ** firmware
  232. **
  233. ** State machine and control for V2DAP application
  234. **
  235. ** Parameters: none
  236. ** Returns: none
  237. ** never returns
  238. ** Requires: VOS kernel
  239. ** Comments: State machine progresses depending on devices connected and
  240. ** removed from USB ports. Command monitor is called whenever the state
  241. ** machine does not change.
  242. */
  243.  
  244. // state machine progression
  245. enum state_e {
  246. STATE_NONE,
  247. STATE_DEVICE,
  248. STATE_DISK,
  249. };
  250.  
  251. volatile enum state_e curState, nextState;
  252.  
  253.  
  254. unsigned long StartTime, CurrentTime, ElapsedTime;
  255. #if 1 // MMA
  256. void MonitorTASK(void) {
  257. while (1) {
  258. /*vos_delay_msecs(2);
  259. Task2Cnt += 1;*/
  260. monCheck(curState == STATE_DISK);
  261. }
  262. }
  263. #endif
  264.  
  265. void firmware(void) {
  266. // UART IOCTL request block
  267. common_ioctl_cb_t monitor_iocb;
  268.  
  269. // general purpose variables
  270. unsigned char status;
  271. unsigned char count;
  272.  
  273. // current device type bitmap for USB ports
  274. unsigned char host1DevType = 0;
  275. unsigned char host2DevType = 0;
  276.  
  277.  
  278.  
  279. curState = STATE_NONE;
  280. nextState = curState;
  281.  
  282. // initialise monitor
  283. monInit(CFGMONITOR_MON_INIT);
  284.  
  285. vos_gpio_set_port_mode(GPIO_PORT_A, 0xff); // set all as output
  286. vos_gpio_set_port_mode(GPIO_PORT_B, 0x00); // set all as input
  287.  
  288. // set DATAACK as output DATAREQ as input
  289. vos_gpio_set_port_mode(GPIO_PORT_C, 0x10);
  290. vos_gpio_set_port_mode(GPIO_PORT_D, 0x00); // set all as input
  291.  
  292. /* start with data mode DATAACK# not asserted */
  293. ackCmdMode();
  294.  
  295. /* set LEDs to all off */
  296. monLedsOff();
  297.  
  298. /* find and open USB drivers */
  299.  
  300. //hUsb1 = vos_dev_open(VOS_DEV_USB1);
  301. hUsb2 = vos_dev_open(VOS_DEV_USB2);
  302.  
  303. hMonitor = vos_dev_open(VOS_DEV_MON);
  304.  
  305. /** FERDINANDO XON AND XOFF CHARACTERS ARE NOT CONFIGURED ******/
  306. #if CFGMONITOR_FLOW_CONTROL == UART_FLOW_XON_XOFF
  307. monitor_iocb.ioctl_code = VOS_IOCTL_UART_SET_XON_CHAR;
  308. monitor_iocb.set.param = CFGMONITOR_XON_CHAR;
  309. vos_dev_ioctl(hMonitor, &monitor_iocb);
  310.  
  311. monitor_iocb.ioctl_code = VOS_IOCTL_UART_SET_XOFF_CHAR;
  312. monitor_iocb.set.param = CFGMONITOR_XOFF_CHAR;
  313. vos_dev_ioctl(hMonitor, &monitor_iocb);
  314. #endif
  315.  
  316. /* UART setup */
  317. /* set baud rate to 9600 baud */
  318. monitor_iocb.ioctl_code = VOS_IOCTL_UART_SET_BAUD_RATE;
  319. monitor_iocb.set.uart_baud_rate = CFGMONITOR_BAUD;
  320. vos_dev_ioctl(hMonitor, &monitor_iocb);
  321. /* set flow control */
  322. monitor_iocb.ioctl_code = VOS_IOCTL_UART_SET_FLOW_CONTROL;
  323. monitor_iocb.set.param = CFGMONITOR_FLOW_CONTROL;
  324. vos_dev_ioctl(hMonitor, &monitor_iocb);
  325. /* set data bits */
  326. monitor_iocb.ioctl_code = VOS_IOCTL_UART_SET_DATA_BITS;
  327. monitor_iocb.set.param = CFGMONITOR_DATA_BITS;
  328. vos_dev_ioctl(hMonitor, &monitor_iocb);
  329. /* set stop bits */
  330. monitor_iocb.ioctl_code = VOS_IOCTL_UART_SET_STOP_BITS;
  331. monitor_iocb.set.param = CFGMONITOR_STOP_BITS;
  332. vos_dev_ioctl(hMonitor, &monitor_iocb);
  333. /* set parity */
  334. monitor_iocb.ioctl_code = VOS_IOCTL_UART_SET_PARITY;
  335. monitor_iocb.set.param = CFGMONITOR_PARITY;
  336. vos_dev_ioctl(hMonitor, &monitor_iocb);
  337.  
  338. // Enable DMA for monitor
  339. monitor_iocb.ioctl_code = VOS_IOCTL_COMMON_ENABLE_DMA;
  340. monitor_iocb.set.param = DMA_ACQUIRE_AS_REQUIRED;
  341. vos_dev_ioctl(hMonitor, &monitor_iocb);
  342.  
  343. do {
  344. // loop on flashing LEDS
  345. #ifdef CFGMONITOR_LEDS_FLASH
  346. monLedsGreen();
  347. vos_delay_msecs(250);
  348. monLedsRed();
  349. vos_delay_msecs(250);
  350. monLedsGreen();
  351. vos_delay_msecs(250);
  352. monLedsRed();
  353. vos_delay_msecs(250);
  354. monLedsGreen();
  355. vos_delay_msecs(250);
  356. monLedsRed();
  357. vos_delay_msecs(250);
  358. monLedsOff();
  359. vos_delay_msecs(250);
  360. #endif // CFGMONITOR_LEDS_FLASH
  361. //vos_delay_msecs(250); MMA
  362.  
  363. // if we are on the UART interface then we will loop until the
  364. // CTS (or DSR) pin goes active (i.e. a terminal application on
  365. // a PC or an application processor is activated)
  366. monitor_iocb.ioctl_code = VOS_IOCTL_UART_GET_MODEM_STATUS;
  367. monitor_iocb.get.param = 0;
  368. vos_dev_ioctl(hMonitor, &monitor_iocb);
  369.  
  370. monitor_iocb.get.param &= (UART_MODEM_STATUS_CTS | UART_MODEM_STATUS_DSR);
  371. }
  372. while (monitor_iocb.get.param == (UART_MODEM_STATUS_CTS | UART_MODEM_STATUS_DSR));
  373.  
  374. // report that the firmware is ready to start
  375. #ifdef CFGMONITOR_SHOW_VERSION
  376. msgOnline();
  377. #endif // CFGMONITOR_SHOW_VERSION
  378.  
  379. // initialise monitor
  380. hostSelectDevice(0);
  381.  
  382. tcbMonitor2 = vos_create_thread_ex(/*10*/29, SIZEOF_MONITOR_TASK_MEMORY, MonitorTASK, "MonitorTask", 0);
  383.  
  384. vos_delay_msecs(500/*0 MMA */);
  385.  
  386. while (1) {
  387. //Task1Cnt += 1; MMA
  388.  
  389. vos_delay_msecs(250); //MMA
  390.  
  391. if (curState == STATE_NONE) {
  392.  
  393. // STATE: USB no device
  394. // NEXT: USB device
  395.  
  396. // check for connect of USB device on port 2
  397. if (hostConnected(hUsb2) == PORT_STATE_ENUMERATED) {
  398. monDeviceDetected(USBHOST_PORT_2);
  399. hostAddToDeviceList(hUsb2);
  400. // if not a disk then go here
  401. nextState = STATE_DEVICE;
  402. }
  403. }
  404. else if (curState == STATE_DEVICE) {
  405.  
  406. // STATE: USB device
  407. // NEXT: USB no device
  408. // USB disk
  409.  
  410. if (hostConnected(hUsb2) == PORT_STATE_DISCONNECTED) {
  411. monDeviceRemoved(USBHOST_PORT_2);
  412. hostRemoveFromDeviceList(hUsb2);
  413.  
  414. monLedsOff();
  415.  
  416. host2DevType = 0;
  417. nextState = STATE_NONE;
  418. }
  419. else if (hostConnected(hUsb2) == PORT_STATE_ENUMERATED) {
  420. // device is detected and enumerated
  421. if (host2DevType == 0) {
  422. host2DevType = hostGetPortDevType(hUsb2);
  423.  
  424. if (host2DevType & hostHasBOMSClass) {
  425. monLedsRed();
  426. hBoms = vos_dev_open(VOS_DEV_BOMS);
  427.  
  428. if (diskCheckDisk(hUsb2) == MON_SUCCESS) {
  429. monLedsGreen();
  430. nextState = STATE_DISK;
  431. monPrompt();
  432. }
  433. else {
  434. monLedsOff();
  435. vos_dev_close(hBoms);
  436. }
  437. }
  438. }
  439. }
  440. }
  441.  
  442. // STATE: USB disk
  443. // NEXT: USB no device
  444. else if (curState == STATE_DISK) {
  445. if (hostConnected(hUsb2) == PORT_STATE_DISCONNECTED) {
  446. diskRemoveDisk();
  447.  
  448. monDeviceRemoved(USBHOST_PORT_2);
  449. hostRemoveFromDeviceList(hUsb2);
  450.  
  451. monLedsOff();
  452.  
  453. host2DevType = 0;
  454. nextState = STATE_NONE;
  455.  
  456. vos_dev_close(hBoms);
  457. }
  458. }
  459.  
  460. #if 0
  461. if (curState == nextState)
  462. {
  463. // check and process commands
  464. monCheck(curState == STATE_DISK);
  465. }
  466. #endif
  467.  
  468. curState = nextState;
  469. }
  470. }
  471.  
  472. /*
  473. ** checkDataMode
  474. **
  475. ** Check if the DATAREQ pin is asserted to enter data mode
  476. **
  477. ** Parameters: none
  478. ** Returns: TRUE if asserted, FALSE if not
  479. ** Comments: Must be available externally to monitor.c
  480. */
  481. unsigned char checkDataMode(void)
  482. {
  483. unsigned char bitVal;
  484. unsigned char status = FALSE;
  485.  
  486. #ifdef CFGMONITOR_DATA_MODE
  487. // do not move to data mode with hub devices
  488. if ((deviceList[curDevice].type & hostHasHub) == 0)
  489. {
  490. if (monInterface == UART)
  491. {
  492. vos_gpio_read_port(GPIO_PORT_C, &bitVal);
  493.  
  494. if ((bitVal & 0x20) == 0)
  495. {
  496. status = TRUE;
  497. }
  498. }
  499. }
  500. #endif // CFGMONITOR_DATA_MODE
  501.  
  502. return status;
  503. }
  504.  
  505. /*
  506. ** ackDataMode
  507. **
  508. ** Acknowledge data mode by asserting the DATAACK pin
  509. **
  510. ** Parameters: none
  511. ** Returns: none
  512. ** Comments: Must be available externally to monitor.c
  513. */
  514. void ackDataMode(void)
  515. {
  516. unsigned char bitVal;
  517.  
  518. if (monInterface == UART)
  519. {
  520. vos_gpio_read_port(GPIO_PORT_C, &bitVal);
  521. bitVal &= 0xef;
  522. vos_gpio_write_port(GPIO_PORT_C, bitVal);
  523. }
  524. }
  525.  
  526. /*
  527. ** ackCmdMode
  528. **
  529. ** Return to command mode and deassert DATAACK pin
  530. **
  531. ** Parameters: none
  532. ** Returns: none
  533. ** Comments: Must be available externally to monitor.c
  534. */
  535. void ackCmdMode(void)
  536. {
  537. unsigned char bitVal;
  538.  
  539. if (monInterface == UART)
  540. {
  541. vos_gpio_read_port(GPIO_PORT_C, &bitVal);
  542. bitVal |= 0x10;
  543. vos_gpio_write_port(GPIO_PORT_C, bitVal);
  544. }
  545. }
  546.  
  547. /*
  548. ** monDataMode
  549. **
  550. ** Perform input/output operations required in data mode.
  551. **
  552. ** Parameters: none
  553. ** Returns: none
  554. ** Comments: Uses current device (SC command).
  555. ** Needs access to checkDataMode() function.
  556. */
  557. void monDataModeIn(usbhost_ep_handle_ex epHandleIn, usbDevList *pUsbDevList,
  558. unsigned char bulkInEp, unsigned short maxSize);
  559.  
  560. void monDataMode()
  561. {
  562. usbhost_xfer_t xfer;
  563. vos_tcb_t *tcbDm = NULL;
  564. char strDm[7] = {'D', 'A', 'T', 'A', 'I', 'N', 0}; // "DATAIN"
  565. vos_semaphore_t semOut;
  566. common_ioctl_cb_t uart_iocb; // UART iocb for getting bytes available.
  567. unsigned short numRead, dataLength;
  568. usbhost_ep_handle_ex epHandleIn, epHandleOut;
  569. usbhost_ioctl_cb_ep_info_t epInfo; // Structure to store our endpoint data.
  570. usbhost_device_handle_ex ifDev;
  571. usbhost_ioctl_cb_t host_ioctl_cb; // IOCTL block for our requests.
  572. // maximum allowed data (arbitary size)
  573. unsigned char buf[64];
  574. unsigned char status;
  575. unsigned char bulkInEp = USBHOST_XFER_FLAG_START_BULK_ENDPOINT_LIST;
  576. unsigned char bulkOutEp = USBHOST_XFER_FLAG_START_BULK_ENDPOINT_LIST;
  577. // Get device which is currently selected with SC command
  578. usbDevList *pUsbDevList = &deviceList[curDevice];
  579.  
  580. // Setup the device as a CDC device
  581. if (pUsbDevList->type == hostHasCDCClass) {
  582. // For CDC devices data mode will poll the Data Communictions Endpoint
  583. // at next slot in the device table
  584. pUsbDevList = cdcSetup();
  585. }
  586.  
  587. // Data mode for Host
  588. ifDev = pUsbDevList->ifDev;
  589. epHandleIn = NULL;
  590. epHandleOut = NULL;
  591.  
  592. // Pipe In Endpoint
  593. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_BULK_IN_ENDPOINT_HANDLE;
  594. host_ioctl_cb.handle.dif = ifDev;
  595. host_ioctl_cb.get = &epHandleIn;
  596. vos_dev_ioctl(pUsbDevList->host, &host_ioctl_cb);
  597.  
  598. if (!epHandleIn) { // We have no handle to a bulk endpoint so try an interrupt
  599. // Acquire Handle to interrupt endpoint
  600. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_INT_IN_ENDPOINT_HANDLE;
  601. vos_dev_ioctl(pUsbDevList->host, &host_ioctl_cb);
  602. bulkInEp = 0;
  603. }
  604.  
  605. if (epHandleIn) {
  606. // get max IN endpoint transfer size
  607. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_ENDPOINT_INFO;
  608. host_ioctl_cb.handle.ep = epHandleIn;
  609. host_ioctl_cb.get = &epInfo;
  610.  
  611. vos_dev_ioctl(pUsbDevList->host, &host_ioctl_cb);
  612. }
  613.  
  614. // Pipe Out Endpoint
  615. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_BULK_OUT_ENDPOINT_HANDLE;
  616. host_ioctl_cb.handle.dif = ifDev;
  617. host_ioctl_cb.get = &epHandleOut;
  618. vos_dev_ioctl(pUsbDevList->host, &host_ioctl_cb);
  619.  
  620. if (!epHandleOut) { // We have no handle to a bulk endpoint so try an interrupt
  621.  
  622. // Acquire Handle to interrupt endpoint
  623. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_INT_OUT_ENDPOINT_HANDLE;
  624. vos_dev_ioctl(pUsbDevList->host, &host_ioctl_cb);
  625. bulkOutEp = 0;
  626. }
  627.  
  628. vos_init_semaphore(&semOut, 0);
  629.  
  630. // only enter data mode if there are in or out endpoints
  631. if (epHandleIn) {
  632. tcbDm = vos_create_thread_ex(/*24*/31, 1200, monDataModeIn, strDm, 9,
  633. //sizeof(usbhost_ep_handle_ex) + sizeof(usbDevList*) +
  634. //sizeof(unsigned char) + sizeof(unsigned short),
  635. epHandleIn, pUsbDevList, bulkInEp, epInfo.max_size);
  636.  
  637. // setup IOCTL for detecting disconnected IN endpoint
  638. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_ENDPOINT_INFO;
  639. host_ioctl_cb.handle.ep = epHandleIn;
  640. host_ioctl_cb.get = &epInfo;
  641. }
  642.  
  643. if ((epHandleIn == NULL) && (epHandleOut == NULL))
  644. {
  645. // no device present
  646. return;
  647. }
  648.  
  649. while(checkDataMode()) {
  650. if (epHandleOut) {
  651. uart_iocb.ioctl_code = VOS_IOCTL_COMMON_GET_RX_QUEUE_STATUS;
  652. vos_dev_ioctl(hMonitor, &uart_iocb);
  653. dataLength = uart_iocb.get.queue_stat;
  654.  
  655. if (dataLength) {
  656. if (dataLength > 64)
  657. dataLength = 64;
  658.  
  659. vos_dev_read(hMonitor, buf, dataLength, &numRead);
  660.  
  661. xfer.buf = buf;
  662. xfer.len = dataLength;
  663. xfer.ep = epHandleOut;
  664. xfer.s = &semOut;
  665. xfer.cond_code = USBHOST_CC_NOTACCESSED;
  666. xfer.flags = bulkOutEp;
  667. status = vos_dev_write(pUsbDevList->host, (unsigned char *) &xfer, sizeof(usbhost_xfer_t), NULL);
  668.  
  669. // catch a disconnected device
  670. if (status == USBHOST_NOT_FOUND)
  671. break;
  672. }
  673. }
  674. if (epHandleIn && tcbDm) {
  675. // detect disconnected IN endpoint (DATAIN thread will have completed)
  676. status = vos_dev_ioctl(pUsbDevList->host, &host_ioctl_cb);
  677. if (status == USBHOST_NOT_FOUND) {
  678. break;
  679. }
  680. }
  681. }
  682.  
  683. if (tcbDm != NULL) {
  684. // remove transfer request (and also complete thread)
  685. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_CLEAR_ENDPOINT_TRANSFER;
  686. host_ioctl_cb.handle.ep = epHandleIn;
  687. status = vos_dev_ioctl(pUsbDevList->host, &host_ioctl_cb);
  688. }
  689. }
  690.  
  691. void monDataModeIn(usbhost_ep_handle_ex epHandleIn, usbDevList *pUsbDevList,
  692. unsigned char bulkInEp, unsigned short maxSize) {
  693. usbhost_xfer_t xfer;
  694. unsigned char status;
  695. unsigned char *buf;
  696. unsigned char *pbuf;
  697. vos_semaphore_t semIn;
  698.  
  699. vos_init_semaphore(&semIn, 0);
  700.  
  701. buf = vos_malloc(maxSize);
  702. pbuf = buf;
  703. if (pUsbDevList->type == hostHasFTDI) {
  704. pbuf = &buf[2];
  705. }
  706.  
  707. while (checkDataMode()) {
  708. xfer.buf = buf;
  709. xfer.len = maxSize;
  710. xfer.ep = epHandleIn;
  711. xfer.s = &semIn;
  712. xfer.cond_code = USBHOST_CC_NOTACCESSED;
  713. xfer.flags = bulkInEp | USBHOST_XFER_FLAG_ROUNDING;
  714. status = vos_dev_read(pUsbDevList->host, (unsigned char *) &xfer, sizeof(usbhost_xfer_t), NULL);
  715.  
  716. if (status == USBHOST_OK) {
  717. // only report data on a complete transfer
  718. if (xfer.cond_code == USBHOST_CC_NOERROR) {
  719. if (xfer.len) {
  720. if (pUsbDevList->type == hostHasFTDI) {
  721. xfer.len -= 2;
  722. }
  723.  
  724. monWrite((char *) pbuf, xfer.len);
  725. }
  726. }
  727. else {
  728. break;
  729. }
  730. }
  731. // detect a disconnected device
  732. else if (status == USBHOST_NOT_FOUND) {
  733. break;
  734. }
  735. }
  736. vos_free(buf);
  737. }
  738.  
  739.  
  740. /*
  741. ** cdcSetup
  742. **
  743. ** Setup CDC device for communications
  744. **
  745. ** Parameters: none
  746. ** Returns: none
  747. ** Comments:
  748. */
  749. usbDevList *cdcSetup(void)
  750. {
  751. usb_deviceRequest_t desc_dev;
  752. usbDevList *pUsbDevData, *pUsbDevCtrl;
  753. usbhost_ep_handle_ex epHandleIn, epHandleCtrl;
  754. usbhost_ioctl_cb_class_t cbClass;
  755. usbhost_ioctl_cb_dev_info_t ifInfo;
  756. usbhost_device_handle_ex ifDevData, ifDevCtrl;
  757. unsigned short intData;
  758. usbhost_ioctl_cb_t host_ioctl_cb; // IOCTL block for our requests.
  759.  
  760. // Pointer to CDC Control Interface
  761. pUsbDevCtrl = &deviceList[curDevice];
  762. // Pointer to CDC Data Interface
  763. pUsbDevData = &deviceList[curDevice + 1];
  764.  
  765. ifDevData = pUsbDevData->ifDev;
  766. ifDevCtrl = pUsbDevCtrl->ifDev;
  767.  
  768. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_CLASS_INFO;
  769. host_ioctl_cb.handle.dif = ifDevData;
  770. host_ioctl_cb.get = &cbClass;
  771. vos_dev_ioctl(pUsbDevData->host, &host_ioctl_cb);
  772.  
  773. // Test for CDC DATA interface
  774. if (cbClass.dev_class == USB_CLASS_CDC_DATA)
  775. {
  776. // Get device info for CDC Data interface
  777. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_DEV_INFO;
  778. host_ioctl_cb.get = &ifInfo;
  779.  
  780. vos_dev_ioctl(pUsbDevData->host, &host_ioctl_cb);
  781.  
  782. // Interface number for CDC DATA interface
  783. intData = ifInfo.interface_number;
  784.  
  785. epHandleIn = 0;
  786. epHandleCtrl = 0;
  787.  
  788. // Get CDC CTRL IN endpoint
  789. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_INT_IN_ENDPOINT_HANDLE;
  790. host_ioctl_cb.handle.dif = ifDevCtrl;
  791. host_ioctl_cb.get = &epHandleIn;
  792. vos_dev_ioctl(pUsbDevCtrl->host, &host_ioctl_cb);
  793.  
  794. // Get CDC DATA control endpoint
  795. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_CONTROL_ENDPOINT_HANDLE;
  796. host_ioctl_cb.handle.dif = ifDevData;
  797. host_ioctl_cb.get = &epHandleCtrl;
  798. vos_dev_ioctl(pUsbDevData->host, &host_ioctl_cb);
  799.  
  800. if (epHandleIn && epHandleCtrl)
  801. {
  802. char lineCoding[7];
  803. char serialState[16];
  804.  
  805. desc_dev.bmRequestType = USB_BMREQUESTTYPE_DEV_TO_HOST |
  806. USB_BMREQUESTTYPE_CLASS |
  807. USB_BMREQUESTTYPE_INTERFACE;
  808. desc_dev.bRequest = 0x21; // Get Line Coding
  809. desc_dev.wValue = 0;
  810. desc_dev.wIndex = intData;
  811. desc_dev.wLength = 7; // Sends back 7 bytes for line coding
  812.  
  813. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_SETUP_TRANSFER;
  814. host_ioctl_cb.handle.ep = epHandleCtrl;
  815. host_ioctl_cb.set = &desc_dev;
  816. host_ioctl_cb.get = lineCoding; // Line coding returned
  817.  
  818. vos_dev_ioctl(pUsbDevData->host, &host_ioctl_cb);
  819.  
  820. desc_dev.bmRequestType = USB_BMREQUESTTYPE_HOST_TO_DEV |
  821. USB_BMREQUESTTYPE_CLASS |
  822. USB_BMREQUESTTYPE_INTERFACE;
  823. desc_dev.bRequest = 0x22; // Set Control Line
  824. //desc_dev.wValue = 0;
  825. //desc_dev.wIndex = wIndex;
  826. desc_dev.wLength = 0;
  827.  
  828. vos_dev_ioctl(pUsbDevData->host, &host_ioctl_cb);
  829.  
  830. cdcGetSerialState(pUsbDevData->host, epHandleCtrl, serialState);
  831.  
  832. //desc_dev.bmRequestType = USB_BMREQUESTTYPE_HOST_TO_DEV |
  833. //USB_BMREQUESTTYPE_CLASS |
  834. //USB_BMREQUESTTYPE_INTERFACE;
  835. desc_dev.bRequest = 0x22; // Set Control Line
  836. desc_dev.wValue = 0x3;
  837. //desc_dev.wIndex = wIndex;
  838. //desc_dev.wLength = 0;
  839.  
  840. vos_dev_ioctl(pUsbDevData->host, &host_ioctl_cb);
  841.  
  842. cdcGetSerialState(pUsbDevData->host, epHandleCtrl, serialState);
  843.  
  844. //desc_dev.bmRequestType = USB_BMREQUESTTYPE_HOST_TO_DEV |
  845. //USB_BMREQUESTTYPE_CLASS |
  846. //USB_BMREQUESTTYPE_INTERFACE;
  847. desc_dev.bRequest = 0x22; // Set Control Line
  848. desc_dev.wValue = 0x3;
  849. //desc_dev.wIndex = wIndex;
  850. desc_dev.wLength = 7;
  851.  
  852. // Resend line coding
  853. host_ioctl_cb.get = lineCoding;
  854.  
  855. vos_dev_ioctl(pUsbDevData->host, &host_ioctl_cb);
  856.  
  857. cdcGetSerialState(pUsbDevData->host, epHandleCtrl, serialState);
  858.  
  859. return pUsbDevData;
  860. }
  861.  
  862. }
  863.  
  864. return pUsbDevCtrl;
  865. }
  866.  
  867. /*
  868. ** cdcGetSerialState
  869. **
  870. ** Poll CDC device for serial state message
  871. **
  872. ** Parameters: USB Host controller handle, CDC control IN endpoint and buffer for data (min 16 bytes)
  873. ** Returns: none
  874. ** Comments:
  875. */
  876. unsigned char cdcGetSerialState(VOS_HANDLE hUsbHost, usbhost_ep_handle_ex ep, char *serialState)
  877. {
  878. usbhost_ioctl_cb_t host_ioctl_cb; // IOCTL block for our requests.
  879. usbhost_xfer_t xfer;
  880. vos_semaphore_t s;
  881.  
  882. vos_init_semaphore(&s, 0);
  883.  
  884. xfer.buf = serialState;
  885. xfer.len = 16;
  886. xfer.ep = ep;
  887. xfer.s = &s;
  888. xfer.cond_code = USBHOST_CC_NOTACCESSED;
  889. // Normally an interrupt endpoint
  890. xfer.flags = USBHOST_XFER_FLAG_ROUNDING | USBHOST_XFER_FLAG_NONBLOCKING;
  891. vos_dev_read(hUsbHost, (unsigned char *) &xfer, sizeof(usbhost_xfer_t), NULL);
  892.  
  893. // Wait 100ms for CDC device to respond
  894. host_ioctl_cb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_CLEAR_ENDPOINT_TRANSFER;
  895. host_ioctl_cb.handle.ep = ep;
  896. vos_delay_msecs(100);
  897. if (xfer.cond_code == USBHOST_CC_NOTACCESSED)
  898. {
  899. vos_dev_ioctl(hUsbHost, &host_ioctl_cb);
  900. xfer.len = 0;
  901. }
  902.  
  903. return xfer.len;
  904. }
  905.  
  906.  
  907. /*
  908. ** msgOnline
  909. **
  910. ** Initialise the monitor.
  911. **
  912. ** Parameters: none
  913. ** Returns: none
  914. ** Comments: monVersion() must be available externally from monitor.c
  915. */
  916. void msgOnline()
  917. {
  918. char *onlineStr1 = "\rVer V2DAP";
  919. char *onlineStr2 = " On-Line:\r";
  920.  
  921. monWriteString(onlineStr1);
  922. monVersion();
  923. monWriteString(onlineStr2);
  924. }
  925.  
  926.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.c:20:17: fatal error: vos.h: No such file or directory
 #include "vos.h"
                 ^
compilation terminated.
stdout
Standard output is empty