Dual CANbus monitor and instrumentation cluster. Presently tuned for the Nissan Leaf EV.

Dependencies:   SPI_TFTx2_ILI9341 TFT_fonts TOUCH_TFTx2_ILI9341 mbed

Fork of CANary_corrupt by Tick Tock

After adding the LPC1768 platform, import as a program and do not select the "update to latest revision" box

User Guide

Eagle Schematic and Board design

/media/uploads/TickTock/canaryr6.zip

/media/uploads/TickTock/canary_sch.jpg

/media/uploads/TickTock/canaryr6brd.jpg

For LCD Rev 1.01:

/media/uploads/TickTock/lcdsch.jpg

For VCD Rev 2.00:

/media/uploads/TickTock/lcdr2.jpg

Parts List

qtyinstancepart #packagesupplierDescription
1BAT3Vhttp://www.ebay.com/itm/10x-CR2032-SMD-Battery-Holder-for-CR2032-Battery-/180938057979?pt=LH_DefaultDomain_0&hash=item2a20bfa8fbLithium 2032 coin battery holder
4C1-C4ECST1DC106R6032Tantalium capacitor 10uF
3FC1-FC3ZF1-20-01-T-WThttp://www.samtec.com/cable-systems/idc-ffc/ffc/zero-insertion.aspx20 conductor 1mm pitch flex cable connector (optional)
1FJ-20-R-08.00-4http://www.samtec.com/cable-systems/idc-ffc/ffc/zero-insertion.aspx8\" 20 conductor 1mm pitch flex connector, end reversed (optional)
2H1-H4(DON'T populate H1-H4 headers - solder mbed directly)
1H5http://www.ebay.com/itm/221186042943?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l26491x12 .1\" pitch header (optional)
1H62x6 .1\" pitch header (optional)
2IC1,IC2VP230LMDSOP8http://www.ebay.com/itm/130488665247?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649canbus transciever
1IC3LM1117-5VSOT2235V regulator
5JP*2 pin .1\" jumper header
1mbedLPC1768http://www.ebay.com/itm/200830573509?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649mbed uC
2Q1,Q22N2222SOT23General purpose NPN transistor
1R1R393M120639K resistor
1R2R103M120610K resistor
4R4-R6R102M12061K resistor
1R3R500M120650 Ohm resistor
2TR1-TR5ZJYS81R5-2PL51TG01http://www.digikey.com/product-detail/en/ZJYS81R5-2PL51T-G01/445-2223-1-ND/765232CM Choke
1Z11N5340BGC1702-15http://www.ebay.com/itm/150878122425?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l26496V, 5W Zener Diode
1Z1DC-DC conveterhttp://www.ebay.com/itm/251142727849?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l264912V-7V, 3W DC-DC converter
1X1USBhttp://www.ebay.com/itm/New-Vertical-USB-2-0-A-pcb-connector-socket-USB-A-Type-/300553895292?pt=LH_DefaultDomain_0&hash=item45fa687d7cvertical USB connector
2LCD0,LCD1TFThttp://www.mikroe.com/add-on-boards/display/tft-proto/320x240 LCD with touch screen
1E0Enclosurehttp://www.shapeways.com/model/1077799/canary.html?li=user-profile&materialId=63d printed enclosure

Assembly

1) LCD Displays

I found ribbon cable is a nice way to organize the wires to the displays. There are two versions of the display and each must be wired differently. The original project used HW REV. 1.01. For that version, you'll need 12 conductors and I connected them in the following order:

1LED+
2LED-
3RST
4SDI
5WR/SCLK
6CS
7X+
8X-
9Y+
10Y-
11VDD
12GND

If, instead, you have HW REV 2.0, you will need 13 conductors with the following order:

1LED+
2LED-
3RST
4SDI
5RS (SCLK)
6WR (DC)
7CS
8X+
9X-
10Y+
11Y-
12VDD
13GND

First I connected all the GND connections (2 GND & IM0, IM1, IM3 for REV1.01 or 2 GND, RD, & IM0 for REV2.00). Do not connect the bottom GND until you have the ribbon cable connected. After making all the ribbon cable connections (connecting the GND of the ribbon cable to the bottom GND pad), solder the GND bar from the previous step to the back of the bottom GND connection. Finally, make a connection from the back side 3.3V pin to IM2 for REV1.01 or to IM1,IM2,&IM3 for REV2.00. Take a break and repeat for the second display.

Examples of REV1.01 boards:

/media/uploads/TickTock/lcdtop.jpg /media/uploads/TickTock/lcdbot.jpg

Examples of REV2.00:

/media/uploads/TickTock/rev2front.jpg /media/uploads/TickTock/rev2back.jpg

Once the two displays are complete combine all wires except CS0, CS1, X+, X-, Y+, and Y-. Connect X- of the left display to X+ of the right. Similarly connect Y- of the left display to Y+ of the right. Insulate any exposed wires.

2) PCB

Refer to the schematics to place all the components on the board. If you plan to install into the CANary 3D enclosure, DO NOT install the battery holder or the socket for the mbed and, instead, connect two wires to the VB and GND pads nearby. You will have to install the battery holder against the back wall to avoid interfering with the right-hand display and the mbed will have to be directly soldered. I have not found a socket with a low enough profile to fit in the space provided (depth of enclosure is limited by the space behind the center console). Also, I recommend keeping as much lead as possible on the Zener diode (bending it as shown to clear the back wall). Although it is operating well within parameters, the Zener gets quite hot during extended operation and the leads help dissipate the heat and keep it away from the PCB and other components.Update: Several Zeners have failed resulting in damage to some users boards so I recommend using a DC-DC converter instead to bring the 12V down to 7V.

/media/uploads/TickTock/pcbtop.jpg /media/uploads/TickTock/pcbbot.jpg

Once the PCB is populated, solder the LCDs to the PCB. CS0 connects to the right display and CS1 connects to the left. /media/uploads/TickTock/brddis.jpg

Update: The Zener diodes tended to fail after a few months so I am recommending removing them and replacing with a DC-DC converter. This will run cooler and waste less energy, too. To install, remove the left display panel to gain access to the Zener. From there, the Zener can be removed and it's pads used to connect to the DC-DC converter. I recommend setting the output voltage on the bench before installing since the trim pot is tricky to reach once installed. Set it to 7V. The input can be connected to the left pad previously occupied by the zener and the output can connect to the right. GND(-) can be connected to the bottom right pad on the 2x6 header below the flex cable connector. Make sure the GND wire lies flat so it doesn't interfere with the connection of the flex cable. /media/uploads/TickTock/dcdcinst2.jpg

Once soldered in place, the DC-DC converter can easily be mounted to the back wall with double sided tape above the battery holder. /media/uploads/TickTock/dcdcinst3.jpg

3) Testing

1)First step is to buzz out all connections from the LCDs to the pins in the main board
2)Next check the touch screen connections. On the main board, place an Ohm meter across X+ and X-. You should read 700 Ohms. Repeat for Y+ and Y-. Then test the resistance from X+ to Y+. With nothing touching the screens, it should read >100K Ohms and <1K when touching either screen.
3)When all connections are checked, solder in the mbed. Download and install the touch2 program http://mbed.org/users/TickTock/code/touch2/ to test the basic operation of the mbed and touch screens.
tips:
Touch screen is sensitive - excess flux on X+,X-,Y+,Y- connection on mbed can result in flakey operation
If touch is not working, double-check the LCD0_CS and LCD1_CS are not swapped. LCD0_CS must connect to the CS of the LCD that has X- & Y- connected to the mbed. LCD1_CS must connect to the CS of the LCD that has X+ & Y+ connected to the mbed.
4)Once touch2 works, it is time to connect to the OBD connector. I highly recommend double checking all connections from the OBD to the PCB with the cable in place before connecting to the Leaf. Buzz out all the pins in the OBS to make sure none are shorting to each other, Check that the 12V goes to the Zener (and nothing else) and the switched 12V to the resistor divider (and nothing else). Test the ground connection properly connects to ground and nothing else.
5)Once you are confident there are no shorts or wrong connections from the OBD connector, take a deep breath and plug it into your leaf. Touch2 program should come up and function. Unplug and install the latest CANary firmware. If you have the REV2.00 LCD boards, you will need to edit the precompile.h file in the TOUCH_TFTx2_w9341 library and set USE_ILI9341 to 1. Test all features before installing into the enclosure (gids, cellpair, menu system, logging) since installing and removing from the enclosure is a PITA.

/media/uploads/TickTock/pcbdone.jpg /media/uploads/TickTock/functioning.jpg

4) Enclosure

The 3D printer leaves a lot of powder behind - I used a strong spray of water to get it out of all the cracks. The enclosure comes with a rather rough finish. I recommend convincing yourself you like it, then simply lightly sand then paint before assembly. Sanding is very difficult - the nylon is very nicely fused and doesn't want to sand. I tried sandblasting and that didn't work either. I had some limited success with filler and then sanding, but only on the outside - it is too difficult to sand the face. /media/uploads/TickTock/enclosure.jpg

5) Final Assembly

Make sure you are well rested with lots of patience before attempting assembly. It is a puzzle figuring out how to get both displays and the PCB in place. Enclosure was too expensive for me to keep iterating to optimize for assembly. I ended up snipping the thin display posts shorter and using various tools to push the displays into place. Also, some USB connectors are taller than others. If you have one of the taller ones, you will have to deflect the back wall a bit while inserting the PCB (being careful not to bend the housing) to get it to it's opening in the back wall. Do use a screw in the provided post to secure the PCB as USB insertion will otherwise dislodge it.

I added an additional safety line which wraps around the center post to prevent the enclosure from becoming a projectile in the event of an accident. /media/uploads/TickTock/safety.jpg Installed: /media/uploads/TickTock/installed.jpg

Committer:
TickTock
Date:
Wed Jul 01 22:21:52 2015 +0000
Revision:
208:bfb6b68d1677
Parent:
146:88f7bda79d8e
Added option to auto delete logs older that a configurable number of days.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TickTock 146:88f7bda79d8e 1 /*
TickTock 146:88f7bda79d8e 2 **************************************************************************************************************
TickTock 146:88f7bda79d8e 3 * NXP USB Host Stack
TickTock 146:88f7bda79d8e 4 *
TickTock 146:88f7bda79d8e 5 * (c) Copyright 2008, NXP SemiConductors
TickTock 146:88f7bda79d8e 6 * (c) Copyright 2008, OnChip Technologies LLC
TickTock 146:88f7bda79d8e 7 * All Rights Reserved
TickTock 146:88f7bda79d8e 8 *
TickTock 146:88f7bda79d8e 9 * www.nxp.com
TickTock 146:88f7bda79d8e 10 * www.onchiptech.com
TickTock 146:88f7bda79d8e 11 *
TickTock 146:88f7bda79d8e 12 * File : usbhost_lpc17xx.c
TickTock 146:88f7bda79d8e 13 * Programmer(s) : Ravikanth.P
TickTock 146:88f7bda79d8e 14 * Version :
TickTock 146:88f7bda79d8e 15 *
TickTock 146:88f7bda79d8e 16 **************************************************************************************************************
TickTock 146:88f7bda79d8e 17 */
TickTock 146:88f7bda79d8e 18
TickTock 146:88f7bda79d8e 19 /*
TickTock 146:88f7bda79d8e 20 **************************************************************************************************************
TickTock 146:88f7bda79d8e 21 * INCLUDE HEADER FILES
TickTock 146:88f7bda79d8e 22 **************************************************************************************************************
TickTock 146:88f7bda79d8e 23 */
TickTock 146:88f7bda79d8e 24
TickTock 146:88f7bda79d8e 25 #include "usbhost_lpc17xx.h"
TickTock 146:88f7bda79d8e 26
TickTock 146:88f7bda79d8e 27 /*
TickTock 146:88f7bda79d8e 28 **************************************************************************************************************
TickTock 146:88f7bda79d8e 29 * GLOBAL VARIABLES
TickTock 146:88f7bda79d8e 30 **************************************************************************************************************
TickTock 146:88f7bda79d8e 31 */
TickTock 146:88f7bda79d8e 32 int gUSBConnected;
TickTock 146:88f7bda79d8e 33
TickTock 146:88f7bda79d8e 34 volatile USB_INT32U HOST_RhscIntr = 0; /* Root Hub Status Change interrupt */
TickTock 146:88f7bda79d8e 35 volatile USB_INT32U HOST_WdhIntr = 0; /* Semaphore to wait until the TD is submitted */
TickTock 146:88f7bda79d8e 36 volatile USB_INT08U HOST_TDControlStatus = 0;
TickTock 146:88f7bda79d8e 37 volatile HCED *EDCtrl; /* Control endpoint descriptor structure */
TickTock 146:88f7bda79d8e 38 volatile HCED *EDBulkIn; /* BulkIn endpoint descriptor structure */
TickTock 146:88f7bda79d8e 39 volatile HCED *EDBulkOut; /* BulkOut endpoint descriptor structure */
TickTock 146:88f7bda79d8e 40 volatile HCTD *TDHead; /* Head transfer descriptor structure */
TickTock 146:88f7bda79d8e 41 volatile HCTD *TDTail; /* Tail transfer descriptor structure */
TickTock 146:88f7bda79d8e 42 volatile HCCA *Hcca; /* Host Controller Communications Area structure */
TickTock 146:88f7bda79d8e 43 USB_INT16U *TDBufNonVol; /* Identical to TDBuffer just to reduce compiler warnings */
TickTock 146:88f7bda79d8e 44 volatile USB_INT08U *TDBuffer; /* Current Buffer Pointer of transfer descriptor */
TickTock 146:88f7bda79d8e 45
TickTock 146:88f7bda79d8e 46 // USB host structures
TickTock 146:88f7bda79d8e 47 // AHB SRAM block 1
TickTock 146:88f7bda79d8e 48 #define HOSTBASEADDR 0x2007C000
TickTock 146:88f7bda79d8e 49 // reserve memory for the linker
TickTock 146:88f7bda79d8e 50 static USB_INT08U HostBuf[0x200] __attribute__((at(HOSTBASEADDR)));
TickTock 146:88f7bda79d8e 51 /*
TickTock 146:88f7bda79d8e 52 **************************************************************************************************************
TickTock 146:88f7bda79d8e 53 * DELAY IN MILLI SECONDS
TickTock 146:88f7bda79d8e 54 *
TickTock 146:88f7bda79d8e 55 * Description: This function provides a delay in milli seconds
TickTock 146:88f7bda79d8e 56 *
TickTock 146:88f7bda79d8e 57 * Arguments : delay The delay required
TickTock 146:88f7bda79d8e 58 *
TickTock 146:88f7bda79d8e 59 * Returns : None
TickTock 146:88f7bda79d8e 60 *
TickTock 146:88f7bda79d8e 61 **************************************************************************************************************
TickTock 146:88f7bda79d8e 62 */
TickTock 146:88f7bda79d8e 63
TickTock 146:88f7bda79d8e 64 void Host_DelayMS (USB_INT32U delay)
TickTock 146:88f7bda79d8e 65 {
TickTock 146:88f7bda79d8e 66 volatile USB_INT32U i;
TickTock 146:88f7bda79d8e 67
TickTock 146:88f7bda79d8e 68
TickTock 146:88f7bda79d8e 69 for (i = 0; i < delay; i++) {
TickTock 146:88f7bda79d8e 70 Host_DelayUS(1000);
TickTock 146:88f7bda79d8e 71 }
TickTock 146:88f7bda79d8e 72 }
TickTock 146:88f7bda79d8e 73
TickTock 146:88f7bda79d8e 74 /*
TickTock 146:88f7bda79d8e 75 **************************************************************************************************************
TickTock 146:88f7bda79d8e 76 * DELAY IN MICRO SECONDS
TickTock 146:88f7bda79d8e 77 *
TickTock 146:88f7bda79d8e 78 * Description: This function provides a delay in micro seconds
TickTock 146:88f7bda79d8e 79 *
TickTock 146:88f7bda79d8e 80 * Arguments : delay The delay required
TickTock 146:88f7bda79d8e 81 *
TickTock 146:88f7bda79d8e 82 * Returns : None
TickTock 146:88f7bda79d8e 83 *
TickTock 146:88f7bda79d8e 84 **************************************************************************************************************
TickTock 146:88f7bda79d8e 85 */
TickTock 146:88f7bda79d8e 86
TickTock 146:88f7bda79d8e 87 void Host_DelayUS (USB_INT32U delay)
TickTock 146:88f7bda79d8e 88 {
TickTock 146:88f7bda79d8e 89 volatile USB_INT32U i;
TickTock 146:88f7bda79d8e 90
TickTock 146:88f7bda79d8e 91
TickTock 146:88f7bda79d8e 92 for (i = 0; i < (4 * delay); i++) { /* This logic was tested. It gives app. 1 micro sec delay */
TickTock 146:88f7bda79d8e 93 ;
TickTock 146:88f7bda79d8e 94 }
TickTock 146:88f7bda79d8e 95 }
TickTock 146:88f7bda79d8e 96
TickTock 146:88f7bda79d8e 97 // bits of the USB/OTG clock control register
TickTock 146:88f7bda79d8e 98 #define HOST_CLK_EN (1<<0)
TickTock 146:88f7bda79d8e 99 #define DEV_CLK_EN (1<<1)
TickTock 146:88f7bda79d8e 100 #define PORTSEL_CLK_EN (1<<3)
TickTock 146:88f7bda79d8e 101 #define AHB_CLK_EN (1<<4)
TickTock 146:88f7bda79d8e 102
TickTock 146:88f7bda79d8e 103 // bits of the USB/OTG clock status register
TickTock 146:88f7bda79d8e 104 #define HOST_CLK_ON (1<<0)
TickTock 146:88f7bda79d8e 105 #define DEV_CLK_ON (1<<1)
TickTock 146:88f7bda79d8e 106 #define PORTSEL_CLK_ON (1<<3)
TickTock 146:88f7bda79d8e 107 #define AHB_CLK_ON (1<<4)
TickTock 146:88f7bda79d8e 108
TickTock 146:88f7bda79d8e 109 // we need host clock, OTG/portsel clock and AHB clock
TickTock 146:88f7bda79d8e 110 #define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN)
TickTock 146:88f7bda79d8e 111
TickTock 146:88f7bda79d8e 112 /*
TickTock 146:88f7bda79d8e 113 **************************************************************************************************************
TickTock 146:88f7bda79d8e 114 * INITIALIZE THE HOST CONTROLLER
TickTock 146:88f7bda79d8e 115 *
TickTock 146:88f7bda79d8e 116 * Description: This function initializes lpc17xx host controller
TickTock 146:88f7bda79d8e 117 *
TickTock 146:88f7bda79d8e 118 * Arguments : None
TickTock 146:88f7bda79d8e 119 *
TickTock 146:88f7bda79d8e 120 * Returns :
TickTock 146:88f7bda79d8e 121 *
TickTock 146:88f7bda79d8e 122 **************************************************************************************************************
TickTock 146:88f7bda79d8e 123 */
TickTock 146:88f7bda79d8e 124 void Host_Init (void)
TickTock 146:88f7bda79d8e 125 {
TickTock 146:88f7bda79d8e 126 PRINT_Log("In Host_Init\n");
TickTock 146:88f7bda79d8e 127 NVIC_DisableIRQ(USB_IRQn); /* Disable the USB interrupt source */
TickTock 146:88f7bda79d8e 128
TickTock 146:88f7bda79d8e 129 // turn on power for USB
TickTock 146:88f7bda79d8e 130 LPC_SC->PCONP |= (1UL<<31);
TickTock 146:88f7bda79d8e 131 // Enable USB host clock, port selection and AHB clock
TickTock 146:88f7bda79d8e 132 LPC_USB->USBClkCtrl |= CLOCK_MASK;
TickTock 146:88f7bda79d8e 133 // Wait for clocks to become available
TickTock 146:88f7bda79d8e 134 while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK)
TickTock 146:88f7bda79d8e 135 ;
TickTock 146:88f7bda79d8e 136
TickTock 146:88f7bda79d8e 137 // it seems the bits[0:1] mean the following
TickTock 146:88f7bda79d8e 138 // 0: U1=device, U2=host
TickTock 146:88f7bda79d8e 139 // 1: U1=host, U2=host
TickTock 146:88f7bda79d8e 140 // 2: reserved
TickTock 146:88f7bda79d8e 141 // 3: U1=host, U2=device
TickTock 146:88f7bda79d8e 142 // NB: this register is only available if OTG clock (aka "port select") is enabled!!
TickTock 146:88f7bda79d8e 143 // since we don't care about port 2, set just bit 0 to 1 (U1=host)
TickTock 146:88f7bda79d8e 144 LPC_USB->OTGStCtrl |= 1;
TickTock 146:88f7bda79d8e 145
TickTock 146:88f7bda79d8e 146 // now that we've configured the ports, we can turn off the portsel clock
TickTock 146:88f7bda79d8e 147 LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;
TickTock 146:88f7bda79d8e 148
TickTock 146:88f7bda79d8e 149 // power pins are not connected on mbed, so we can skip them
TickTock 146:88f7bda79d8e 150 /* P1[18] = USB_UP_LED, 01 */
TickTock 146:88f7bda79d8e 151 /* P1[19] = /USB_PPWR, 10 */
TickTock 146:88f7bda79d8e 152 /* P1[22] = USB_PWRD, 10 */
TickTock 146:88f7bda79d8e 153 /* P1[27] = /USB_OVRCR, 10 */
TickTock 146:88f7bda79d8e 154 /*LPC_PINCON->PINSEL3 &= ~((3<<4) | (3<<6) | (3<<12) | (3<<22));
TickTock 146:88f7bda79d8e 155 LPC_PINCON->PINSEL3 |= ((1<<4)|(2<<6) | (2<<12) | (2<<22)); // 0x00802080
TickTock 146:88f7bda79d8e 156 */
TickTock 146:88f7bda79d8e 157
TickTock 146:88f7bda79d8e 158 // configure USB D+/D- pins
TickTock 146:88f7bda79d8e 159 /* P0[29] = USB_D+, 01 */
TickTock 146:88f7bda79d8e 160 /* P0[30] = USB_D-, 01 */
TickTock 146:88f7bda79d8e 161 LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28));
TickTock 146:88f7bda79d8e 162 LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); // 0x14000000
TickTock 146:88f7bda79d8e 163
TickTock 146:88f7bda79d8e 164 PRINT_Log("Initializing Host Stack\n");
TickTock 146:88f7bda79d8e 165
TickTock 146:88f7bda79d8e 166 Hcca = (volatile HCCA *)(HostBuf+0x000);
TickTock 146:88f7bda79d8e 167 TDHead = (volatile HCTD *)(HostBuf+0x100);
TickTock 146:88f7bda79d8e 168 TDTail = (volatile HCTD *)(HostBuf+0x110);
TickTock 146:88f7bda79d8e 169 EDCtrl = (volatile HCED *)(HostBuf+0x120);
TickTock 146:88f7bda79d8e 170 EDBulkIn = (volatile HCED *)(HostBuf+0x130);
TickTock 146:88f7bda79d8e 171 EDBulkOut = (volatile HCED *)(HostBuf+0x140);
TickTock 146:88f7bda79d8e 172 TDBuffer = (volatile USB_INT08U *)(HostBuf+0x150);
TickTock 146:88f7bda79d8e 173
TickTock 146:88f7bda79d8e 174 /* Initialize all the TDs, EDs and HCCA to 0 */
TickTock 146:88f7bda79d8e 175 Host_EDInit(EDCtrl);
TickTock 146:88f7bda79d8e 176 Host_EDInit(EDBulkIn);
TickTock 146:88f7bda79d8e 177 Host_EDInit(EDBulkOut);
TickTock 146:88f7bda79d8e 178 Host_TDInit(TDHead);
TickTock 146:88f7bda79d8e 179 Host_TDInit(TDTail);
TickTock 146:88f7bda79d8e 180 Host_HCCAInit(Hcca);
TickTock 146:88f7bda79d8e 181
TickTock 146:88f7bda79d8e 182 Host_DelayMS(50); /* Wait 50 ms before apply reset */
TickTock 146:88f7bda79d8e 183 LPC_USB->HcControl = 0; /* HARDWARE RESET */
TickTock 146:88f7bda79d8e 184 LPC_USB->HcControlHeadED = 0; /* Initialize Control list head to Zero */
TickTock 146:88f7bda79d8e 185 LPC_USB->HcBulkHeadED = 0; /* Initialize Bulk list head to Zero */
TickTock 146:88f7bda79d8e 186
TickTock 146:88f7bda79d8e 187 /* SOFTWARE RESET */
TickTock 146:88f7bda79d8e 188 LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
TickTock 146:88f7bda79d8e 189 LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; /* Write Fm Interval and Largest Data Packet Counter */
TickTock 146:88f7bda79d8e 190
TickTock 146:88f7bda79d8e 191 /* Put HC in operational state */
TickTock 146:88f7bda79d8e 192 LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
TickTock 146:88f7bda79d8e 193 LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; /* Set Global Power */
TickTock 146:88f7bda79d8e 194
TickTock 146:88f7bda79d8e 195 LPC_USB->HcHCCA = (USB_INT32U)Hcca;
TickTock 146:88f7bda79d8e 196 LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; /* Clear Interrrupt Status */
TickTock 146:88f7bda79d8e 197
TickTock 146:88f7bda79d8e 198
TickTock 146:88f7bda79d8e 199 LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE |
TickTock 146:88f7bda79d8e 200 OR_INTR_ENABLE_WDH |
TickTock 146:88f7bda79d8e 201 OR_INTR_ENABLE_RHSC;
TickTock 146:88f7bda79d8e 202
TickTock 146:88f7bda79d8e 203 NVIC_SetPriority(USB_IRQn, 0); /* highest priority */
TickTock 146:88f7bda79d8e 204 /* Enable the USB Interrupt */
TickTock 146:88f7bda79d8e 205 NVIC_EnableIRQ(USB_IRQn);
TickTock 146:88f7bda79d8e 206 PRINT_Log("Host Initialized\n");
TickTock 146:88f7bda79d8e 207 }
TickTock 146:88f7bda79d8e 208
TickTock 146:88f7bda79d8e 209 /*
TickTock 146:88f7bda79d8e 210 **************************************************************************************************************
TickTock 146:88f7bda79d8e 211 * INTERRUPT SERVICE ROUTINE
TickTock 146:88f7bda79d8e 212 *
TickTock 146:88f7bda79d8e 213 * Description: This function services the interrupt caused by host controller
TickTock 146:88f7bda79d8e 214 *
TickTock 146:88f7bda79d8e 215 * Arguments : None
TickTock 146:88f7bda79d8e 216 *
TickTock 146:88f7bda79d8e 217 * Returns : None
TickTock 146:88f7bda79d8e 218 *
TickTock 146:88f7bda79d8e 219 **************************************************************************************************************
TickTock 146:88f7bda79d8e 220 */
TickTock 146:88f7bda79d8e 221
TickTock 146:88f7bda79d8e 222 void USB_IRQHandler (void) __irq
TickTock 146:88f7bda79d8e 223 {
TickTock 146:88f7bda79d8e 224 USB_INT32U int_status;
TickTock 146:88f7bda79d8e 225 USB_INT32U ie_status;
TickTock 146:88f7bda79d8e 226
TickTock 146:88f7bda79d8e 227 int_status = LPC_USB->HcInterruptStatus; /* Read Interrupt Status */
TickTock 146:88f7bda79d8e 228 ie_status = LPC_USB->HcInterruptEnable; /* Read Interrupt enable status */
TickTock 146:88f7bda79d8e 229
TickTock 146:88f7bda79d8e 230 if (!(int_status & ie_status)) {
TickTock 146:88f7bda79d8e 231 return;
TickTock 146:88f7bda79d8e 232 } else {
TickTock 146:88f7bda79d8e 233
TickTock 146:88f7bda79d8e 234 int_status = int_status & ie_status;
TickTock 146:88f7bda79d8e 235 if (int_status & OR_INTR_STATUS_RHSC) { /* Root hub status change interrupt */
TickTock 146:88f7bda79d8e 236 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) {
TickTock 146:88f7bda79d8e 237 if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) {
TickTock 146:88f7bda79d8e 238 /*
TickTock 146:88f7bda79d8e 239 * When DRWE is on, Connect Status Change
TickTock 146:88f7bda79d8e 240 * means a remote wakeup event.
TickTock 146:88f7bda79d8e 241 */
TickTock 146:88f7bda79d8e 242 HOST_RhscIntr = 1;// JUST SOMETHING FOR A BREAKPOINT
TickTock 146:88f7bda79d8e 243 }
TickTock 146:88f7bda79d8e 244 else {
TickTock 146:88f7bda79d8e 245 /*
TickTock 146:88f7bda79d8e 246 * When DRWE is off, Connect Status Change
TickTock 146:88f7bda79d8e 247 * is NOT a remote wakeup event
TickTock 146:88f7bda79d8e 248 */
TickTock 146:88f7bda79d8e 249 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
TickTock 146:88f7bda79d8e 250 if (!gUSBConnected) {
TickTock 146:88f7bda79d8e 251 HOST_TDControlStatus = 0;
TickTock 146:88f7bda79d8e 252 HOST_WdhIntr = 0;
TickTock 146:88f7bda79d8e 253 HOST_RhscIntr = 1;
TickTock 146:88f7bda79d8e 254 gUSBConnected = 1;
TickTock 146:88f7bda79d8e 255 }
TickTock 146:88f7bda79d8e 256 else
TickTock 146:88f7bda79d8e 257 PRINT_Log("Spurious status change (connected)?\n");
TickTock 146:88f7bda79d8e 258 } else {
TickTock 146:88f7bda79d8e 259 if (gUSBConnected) {
TickTock 146:88f7bda79d8e 260 LPC_USB->HcInterruptEnable = 0; // why do we get multiple disc. rupts???
TickTock 146:88f7bda79d8e 261 HOST_RhscIntr = 0;
TickTock 146:88f7bda79d8e 262 gUSBConnected = 0;
TickTock 146:88f7bda79d8e 263 }
TickTock 146:88f7bda79d8e 264 else
TickTock 146:88f7bda79d8e 265 PRINT_Log("Spurious status change (disconnected)?\n");
TickTock 146:88f7bda79d8e 266 }
TickTock 146:88f7bda79d8e 267 }
TickTock 146:88f7bda79d8e 268 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
TickTock 146:88f7bda79d8e 269 }
TickTock 146:88f7bda79d8e 270 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC) {
TickTock 146:88f7bda79d8e 271 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
TickTock 146:88f7bda79d8e 272 }
TickTock 146:88f7bda79d8e 273 }
TickTock 146:88f7bda79d8e 274 if (int_status & OR_INTR_STATUS_WDH) { /* Writeback Done Head interrupt */
TickTock 146:88f7bda79d8e 275 HOST_WdhIntr = 1;
TickTock 146:88f7bda79d8e 276 HOST_TDControlStatus = (TDHead->Control >> 28) & 0xf;
TickTock 146:88f7bda79d8e 277 }
TickTock 146:88f7bda79d8e 278 LPC_USB->HcInterruptStatus = int_status; /* Clear interrupt status register */
TickTock 146:88f7bda79d8e 279 }
TickTock 146:88f7bda79d8e 280 return;
TickTock 146:88f7bda79d8e 281 }
TickTock 146:88f7bda79d8e 282
TickTock 146:88f7bda79d8e 283 /*
TickTock 146:88f7bda79d8e 284 **************************************************************************************************************
TickTock 146:88f7bda79d8e 285 * PROCESS TRANSFER DESCRIPTOR
TickTock 146:88f7bda79d8e 286 *
TickTock 146:88f7bda79d8e 287 * Description: This function processes the transfer descriptor
TickTock 146:88f7bda79d8e 288 *
TickTock 146:88f7bda79d8e 289 * Arguments : ed Endpoint descriptor that contains this transfer descriptor
TickTock 146:88f7bda79d8e 290 * token SETUP, IN, OUT
TickTock 146:88f7bda79d8e 291 * buffer Current Buffer Pointer of the transfer descriptor
TickTock 146:88f7bda79d8e 292 * buffer_len Length of the buffer
TickTock 146:88f7bda79d8e 293 *
TickTock 146:88f7bda79d8e 294 * Returns : OK if TD submission is successful
TickTock 146:88f7bda79d8e 295 * ERROR if TD submission fails
TickTock 146:88f7bda79d8e 296 *
TickTock 146:88f7bda79d8e 297 **************************************************************************************************************
TickTock 146:88f7bda79d8e 298 */
TickTock 146:88f7bda79d8e 299
TickTock 146:88f7bda79d8e 300 USB_INT32S Host_ProcessTD (volatile HCED *ed,
TickTock 146:88f7bda79d8e 301 volatile USB_INT32U token,
TickTock 146:88f7bda79d8e 302 volatile USB_INT08U *buffer,
TickTock 146:88f7bda79d8e 303 USB_INT32U buffer_len)
TickTock 146:88f7bda79d8e 304 {
TickTock 146:88f7bda79d8e 305 volatile USB_INT32U td_toggle;
TickTock 146:88f7bda79d8e 306
TickTock 146:88f7bda79d8e 307
TickTock 146:88f7bda79d8e 308 if (ed == EDCtrl) {
TickTock 146:88f7bda79d8e 309 if (token == TD_SETUP) {
TickTock 146:88f7bda79d8e 310 td_toggle = TD_TOGGLE_0;
TickTock 146:88f7bda79d8e 311 } else {
TickTock 146:88f7bda79d8e 312 td_toggle = TD_TOGGLE_1;
TickTock 146:88f7bda79d8e 313 }
TickTock 146:88f7bda79d8e 314 } else {
TickTock 146:88f7bda79d8e 315 td_toggle = 0;
TickTock 146:88f7bda79d8e 316 }
TickTock 146:88f7bda79d8e 317 TDHead->Control = (TD_ROUNDING |
TickTock 146:88f7bda79d8e 318 token |
TickTock 146:88f7bda79d8e 319 TD_DELAY_INT(0) |
TickTock 146:88f7bda79d8e 320 td_toggle |
TickTock 146:88f7bda79d8e 321 TD_CC);
TickTock 146:88f7bda79d8e 322 TDTail->Control = 0;
TickTock 146:88f7bda79d8e 323 TDHead->CurrBufPtr = (USB_INT32U) buffer;
TickTock 146:88f7bda79d8e 324 TDTail->CurrBufPtr = 0;
TickTock 146:88f7bda79d8e 325 TDHead->Next = (USB_INT32U) TDTail;
TickTock 146:88f7bda79d8e 326 TDTail->Next = 0;
TickTock 146:88f7bda79d8e 327 TDHead->BufEnd = (USB_INT32U)(buffer + (buffer_len - 1));
TickTock 146:88f7bda79d8e 328 TDTail->BufEnd = 0;
TickTock 146:88f7bda79d8e 329
TickTock 146:88f7bda79d8e 330 ed->HeadTd = (USB_INT32U)TDHead | ((ed->HeadTd) & 0x00000002);
TickTock 146:88f7bda79d8e 331 ed->TailTd = (USB_INT32U)TDTail;
TickTock 146:88f7bda79d8e 332 ed->Next = 0;
TickTock 146:88f7bda79d8e 333
TickTock 146:88f7bda79d8e 334 if (ed == EDCtrl) {
TickTock 146:88f7bda79d8e 335 LPC_USB->HcControlHeadED = (USB_INT32U)ed;
TickTock 146:88f7bda79d8e 336 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_CLF;
TickTock 146:88f7bda79d8e 337 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_CLE;
TickTock 146:88f7bda79d8e 338 } else {
TickTock 146:88f7bda79d8e 339 LPC_USB->HcBulkHeadED = (USB_INT32U)ed;
TickTock 146:88f7bda79d8e 340 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
TickTock 146:88f7bda79d8e 341 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE;
TickTock 146:88f7bda79d8e 342 }
TickTock 146:88f7bda79d8e 343
TickTock 146:88f7bda79d8e 344 Host_WDHWait();
TickTock 146:88f7bda79d8e 345
TickTock 146:88f7bda79d8e 346 // if (!(TDHead->Control & 0xF0000000)) {
TickTock 146:88f7bda79d8e 347 if (!HOST_TDControlStatus) {
TickTock 146:88f7bda79d8e 348 return (OK);
TickTock 146:88f7bda79d8e 349 } else {
TickTock 146:88f7bda79d8e 350 return (ERR_TD_FAIL);
TickTock 146:88f7bda79d8e 351 }
TickTock 146:88f7bda79d8e 352 }
TickTock 146:88f7bda79d8e 353
TickTock 146:88f7bda79d8e 354 /*
TickTock 146:88f7bda79d8e 355 **************************************************************************************************************
TickTock 146:88f7bda79d8e 356 * ENUMERATE THE DEVICE
TickTock 146:88f7bda79d8e 357 *
TickTock 146:88f7bda79d8e 358 * Description: This function is used to enumerate the device connected
TickTock 146:88f7bda79d8e 359 *
TickTock 146:88f7bda79d8e 360 * Arguments : None
TickTock 146:88f7bda79d8e 361 *
TickTock 146:88f7bda79d8e 362 * Returns : None
TickTock 146:88f7bda79d8e 363 *
TickTock 146:88f7bda79d8e 364 **************************************************************************************************************
TickTock 146:88f7bda79d8e 365 */
TickTock 146:88f7bda79d8e 366
TickTock 146:88f7bda79d8e 367 USB_INT32S Host_EnumDev (void)
TickTock 146:88f7bda79d8e 368 {
TickTock 146:88f7bda79d8e 369 USB_INT32S rc;
TickTock 146:88f7bda79d8e 370
TickTock 146:88f7bda79d8e 371 PRINT_Log("Connect a Mass Storage device\n");
TickTock 146:88f7bda79d8e 372 while (!HOST_RhscIntr)
TickTock 146:88f7bda79d8e 373 __WFI();
TickTock 146:88f7bda79d8e 374 Host_DelayMS(100); /* USB 2.0 spec says atleast 50ms delay beore port reset */
TickTock 146:88f7bda79d8e 375 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset
TickTock 146:88f7bda79d8e 376 while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS)
TickTock 146:88f7bda79d8e 377 __WFI(); // Wait for port reset to complete...
TickTock 146:88f7bda79d8e 378 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal
TickTock 146:88f7bda79d8e 379 Host_DelayMS(200); /* Wait for 100 MS after port reset */
TickTock 146:88f7bda79d8e 380
TickTock 146:88f7bda79d8e 381 EDCtrl->Control = 8 << 16; /* Put max pkt size = 8 */
TickTock 146:88f7bda79d8e 382 /* Read first 8 bytes of device desc */
TickTock 146:88f7bda79d8e 383 rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 8);
TickTock 146:88f7bda79d8e 384 if (rc != OK) {
TickTock 146:88f7bda79d8e 385 PRINT_Err(rc);
TickTock 146:88f7bda79d8e 386 return (rc);
TickTock 146:88f7bda79d8e 387 }
TickTock 146:88f7bda79d8e 388 EDCtrl->Control = TDBuffer[7] << 16; /* Get max pkt size of endpoint 0 */
TickTock 146:88f7bda79d8e 389 rc = HOST_SET_ADDRESS(1); /* Set the device address to 1 */
TickTock 146:88f7bda79d8e 390 if (rc != OK) {
TickTock 146:88f7bda79d8e 391 PRINT_Err(rc);
TickTock 146:88f7bda79d8e 392 return (rc);
TickTock 146:88f7bda79d8e 393 }
TickTock 146:88f7bda79d8e 394 Host_DelayMS(2);
TickTock 146:88f7bda79d8e 395 EDCtrl->Control = (EDCtrl->Control) | 1; /* Modify control pipe with address 1 */
TickTock 146:88f7bda79d8e 396 /* Get the configuration descriptor */
TickTock 146:88f7bda79d8e 397 rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, 9);
TickTock 146:88f7bda79d8e 398 if (rc != OK) {
TickTock 146:88f7bda79d8e 399 PRINT_Err(rc);
TickTock 146:88f7bda79d8e 400 return (rc);
TickTock 146:88f7bda79d8e 401 }
TickTock 146:88f7bda79d8e 402 /* Get the first configuration data */
TickTock 146:88f7bda79d8e 403 rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, ReadLE16U(&TDBuffer[2]));
TickTock 146:88f7bda79d8e 404 if (rc != OK) {
TickTock 146:88f7bda79d8e 405 PRINT_Err(rc);
TickTock 146:88f7bda79d8e 406 return (rc);
TickTock 146:88f7bda79d8e 407 }
TickTock 146:88f7bda79d8e 408 rc = MS_ParseConfiguration(); /* Parse the configuration */
TickTock 146:88f7bda79d8e 409 if (rc != OK) {
TickTock 146:88f7bda79d8e 410 PRINT_Err(rc);
TickTock 146:88f7bda79d8e 411 return (rc);
TickTock 146:88f7bda79d8e 412 }
TickTock 146:88f7bda79d8e 413 rc = USBH_SET_CONFIGURATION(1); /* Select device configuration 1 */
TickTock 146:88f7bda79d8e 414 if (rc != OK) {
TickTock 146:88f7bda79d8e 415 PRINT_Err(rc);
TickTock 146:88f7bda79d8e 416 }
TickTock 146:88f7bda79d8e 417 Host_DelayMS(100); /* Some devices may require this delay */
TickTock 146:88f7bda79d8e 418 return (rc);
TickTock 146:88f7bda79d8e 419 }
TickTock 146:88f7bda79d8e 420
TickTock 146:88f7bda79d8e 421 /*
TickTock 146:88f7bda79d8e 422 **************************************************************************************************************
TickTock 146:88f7bda79d8e 423 * RECEIVE THE CONTROL INFORMATION
TickTock 146:88f7bda79d8e 424 *
TickTock 146:88f7bda79d8e 425 * Description: This function is used to receive the control information
TickTock 146:88f7bda79d8e 426 *
TickTock 146:88f7bda79d8e 427 * Arguments : bm_request_type
TickTock 146:88f7bda79d8e 428 * b_request
TickTock 146:88f7bda79d8e 429 * w_value
TickTock 146:88f7bda79d8e 430 * w_index
TickTock 146:88f7bda79d8e 431 * w_length
TickTock 146:88f7bda79d8e 432 * buffer
TickTock 146:88f7bda79d8e 433 *
TickTock 146:88f7bda79d8e 434 * Returns : OK if Success
TickTock 146:88f7bda79d8e 435 * ERROR if Failed
TickTock 146:88f7bda79d8e 436 *
TickTock 146:88f7bda79d8e 437 **************************************************************************************************************
TickTock 146:88f7bda79d8e 438 */
TickTock 146:88f7bda79d8e 439
TickTock 146:88f7bda79d8e 440 USB_INT32S Host_CtrlRecv ( USB_INT08U bm_request_type,
TickTock 146:88f7bda79d8e 441 USB_INT08U b_request,
TickTock 146:88f7bda79d8e 442 USB_INT16U w_value,
TickTock 146:88f7bda79d8e 443 USB_INT16U w_index,
TickTock 146:88f7bda79d8e 444 USB_INT16U w_length,
TickTock 146:88f7bda79d8e 445 volatile USB_INT08U *buffer)
TickTock 146:88f7bda79d8e 446 {
TickTock 146:88f7bda79d8e 447 USB_INT32S rc;
TickTock 146:88f7bda79d8e 448
TickTock 146:88f7bda79d8e 449
TickTock 146:88f7bda79d8e 450 Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length);
TickTock 146:88f7bda79d8e 451 rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8);
TickTock 146:88f7bda79d8e 452 if (rc == OK) {
TickTock 146:88f7bda79d8e 453 if (w_length) {
TickTock 146:88f7bda79d8e 454 rc = Host_ProcessTD(EDCtrl, TD_IN, TDBuffer, w_length);
TickTock 146:88f7bda79d8e 455 }
TickTock 146:88f7bda79d8e 456 if (rc == OK) {
TickTock 146:88f7bda79d8e 457 rc = Host_ProcessTD(EDCtrl, TD_OUT, NULL, 0);
TickTock 146:88f7bda79d8e 458 }
TickTock 146:88f7bda79d8e 459 }
TickTock 146:88f7bda79d8e 460 return (rc);
TickTock 146:88f7bda79d8e 461 }
TickTock 146:88f7bda79d8e 462
TickTock 146:88f7bda79d8e 463 /*
TickTock 146:88f7bda79d8e 464 **************************************************************************************************************
TickTock 146:88f7bda79d8e 465 * SEND THE CONTROL INFORMATION
TickTock 146:88f7bda79d8e 466 *
TickTock 146:88f7bda79d8e 467 * Description: This function is used to send the control information
TickTock 146:88f7bda79d8e 468 *
TickTock 146:88f7bda79d8e 469 * Arguments : None
TickTock 146:88f7bda79d8e 470 *
TickTock 146:88f7bda79d8e 471 * Returns : OK if Success
TickTock 146:88f7bda79d8e 472 * ERR_INVALID_BOOTSIG if Failed
TickTock 146:88f7bda79d8e 473 *
TickTock 146:88f7bda79d8e 474 **************************************************************************************************************
TickTock 146:88f7bda79d8e 475 */
TickTock 146:88f7bda79d8e 476
TickTock 146:88f7bda79d8e 477 USB_INT32S Host_CtrlSend ( USB_INT08U bm_request_type,
TickTock 146:88f7bda79d8e 478 USB_INT08U b_request,
TickTock 146:88f7bda79d8e 479 USB_INT16U w_value,
TickTock 146:88f7bda79d8e 480 USB_INT16U w_index,
TickTock 146:88f7bda79d8e 481 USB_INT16U w_length,
TickTock 146:88f7bda79d8e 482 volatile USB_INT08U *buffer)
TickTock 146:88f7bda79d8e 483 {
TickTock 146:88f7bda79d8e 484 USB_INT32S rc;
TickTock 146:88f7bda79d8e 485
TickTock 146:88f7bda79d8e 486
TickTock 146:88f7bda79d8e 487 Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length);
TickTock 146:88f7bda79d8e 488
TickTock 146:88f7bda79d8e 489 rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8);
TickTock 146:88f7bda79d8e 490 if (rc == OK) {
TickTock 146:88f7bda79d8e 491 if (w_length) {
TickTock 146:88f7bda79d8e 492 rc = Host_ProcessTD(EDCtrl, TD_OUT, TDBuffer, w_length);
TickTock 146:88f7bda79d8e 493 }
TickTock 146:88f7bda79d8e 494 if (rc == OK) {
TickTock 146:88f7bda79d8e 495 rc = Host_ProcessTD(EDCtrl, TD_IN, NULL, 0);
TickTock 146:88f7bda79d8e 496 }
TickTock 146:88f7bda79d8e 497 }
TickTock 146:88f7bda79d8e 498 return (rc);
TickTock 146:88f7bda79d8e 499 }
TickTock 146:88f7bda79d8e 500
TickTock 146:88f7bda79d8e 501 /*
TickTock 146:88f7bda79d8e 502 **************************************************************************************************************
TickTock 146:88f7bda79d8e 503 * FILL SETUP PACKET
TickTock 146:88f7bda79d8e 504 *
TickTock 146:88f7bda79d8e 505 * Description: This function is used to fill the setup packet
TickTock 146:88f7bda79d8e 506 *
TickTock 146:88f7bda79d8e 507 * Arguments : None
TickTock 146:88f7bda79d8e 508 *
TickTock 146:88f7bda79d8e 509 * Returns : OK if Success
TickTock 146:88f7bda79d8e 510 * ERR_INVALID_BOOTSIG if Failed
TickTock 146:88f7bda79d8e 511 *
TickTock 146:88f7bda79d8e 512 **************************************************************************************************************
TickTock 146:88f7bda79d8e 513 */
TickTock 146:88f7bda79d8e 514
TickTock 146:88f7bda79d8e 515 void Host_FillSetup (USB_INT08U bm_request_type,
TickTock 146:88f7bda79d8e 516 USB_INT08U b_request,
TickTock 146:88f7bda79d8e 517 USB_INT16U w_value,
TickTock 146:88f7bda79d8e 518 USB_INT16U w_index,
TickTock 146:88f7bda79d8e 519 USB_INT16U w_length)
TickTock 146:88f7bda79d8e 520 {
TickTock 146:88f7bda79d8e 521 int i;
TickTock 146:88f7bda79d8e 522 for (i=0;i<w_length;i++)
TickTock 146:88f7bda79d8e 523 TDBuffer[i] = 0;
TickTock 146:88f7bda79d8e 524
TickTock 146:88f7bda79d8e 525 TDBuffer[0] = bm_request_type;
TickTock 146:88f7bda79d8e 526 TDBuffer[1] = b_request;
TickTock 146:88f7bda79d8e 527 WriteLE16U(&TDBuffer[2], w_value);
TickTock 146:88f7bda79d8e 528 WriteLE16U(&TDBuffer[4], w_index);
TickTock 146:88f7bda79d8e 529 WriteLE16U(&TDBuffer[6], w_length);
TickTock 146:88f7bda79d8e 530 }
TickTock 146:88f7bda79d8e 531
TickTock 146:88f7bda79d8e 532
TickTock 146:88f7bda79d8e 533
TickTock 146:88f7bda79d8e 534 /*
TickTock 146:88f7bda79d8e 535 **************************************************************************************************************
TickTock 146:88f7bda79d8e 536 * INITIALIZE THE TRANSFER DESCRIPTOR
TickTock 146:88f7bda79d8e 537 *
TickTock 146:88f7bda79d8e 538 * Description: This function initializes transfer descriptor
TickTock 146:88f7bda79d8e 539 *
TickTock 146:88f7bda79d8e 540 * Arguments : Pointer to TD structure
TickTock 146:88f7bda79d8e 541 *
TickTock 146:88f7bda79d8e 542 * Returns : None
TickTock 146:88f7bda79d8e 543 *
TickTock 146:88f7bda79d8e 544 **************************************************************************************************************
TickTock 146:88f7bda79d8e 545 */
TickTock 146:88f7bda79d8e 546
TickTock 146:88f7bda79d8e 547 void Host_TDInit (volatile HCTD *td)
TickTock 146:88f7bda79d8e 548 {
TickTock 146:88f7bda79d8e 549
TickTock 146:88f7bda79d8e 550 td->Control = 0;
TickTock 146:88f7bda79d8e 551 td->CurrBufPtr = 0;
TickTock 146:88f7bda79d8e 552 td->Next = 0;
TickTock 146:88f7bda79d8e 553 td->BufEnd = 0;
TickTock 146:88f7bda79d8e 554 }
TickTock 146:88f7bda79d8e 555
TickTock 146:88f7bda79d8e 556 /*
TickTock 146:88f7bda79d8e 557 **************************************************************************************************************
TickTock 146:88f7bda79d8e 558 * INITIALIZE THE ENDPOINT DESCRIPTOR
TickTock 146:88f7bda79d8e 559 *
TickTock 146:88f7bda79d8e 560 * Description: This function initializes endpoint descriptor
TickTock 146:88f7bda79d8e 561 *
TickTock 146:88f7bda79d8e 562 * Arguments : Pointer to ED strcuture
TickTock 146:88f7bda79d8e 563 *
TickTock 146:88f7bda79d8e 564 * Returns : None
TickTock 146:88f7bda79d8e 565 *
TickTock 146:88f7bda79d8e 566 **************************************************************************************************************
TickTock 146:88f7bda79d8e 567 */
TickTock 146:88f7bda79d8e 568
TickTock 146:88f7bda79d8e 569 void Host_EDInit (volatile HCED *ed)
TickTock 146:88f7bda79d8e 570 {
TickTock 146:88f7bda79d8e 571
TickTock 146:88f7bda79d8e 572 ed->Control = 0;
TickTock 146:88f7bda79d8e 573 ed->TailTd = 0;
TickTock 146:88f7bda79d8e 574 ed->HeadTd = 0;
TickTock 146:88f7bda79d8e 575 ed->Next = 0;
TickTock 146:88f7bda79d8e 576 }
TickTock 146:88f7bda79d8e 577
TickTock 146:88f7bda79d8e 578 /*
TickTock 146:88f7bda79d8e 579 **************************************************************************************************************
TickTock 146:88f7bda79d8e 580 * INITIALIZE HOST CONTROLLER COMMUNICATIONS AREA
TickTock 146:88f7bda79d8e 581 *
TickTock 146:88f7bda79d8e 582 * Description: This function initializes host controller communications area
TickTock 146:88f7bda79d8e 583 *
TickTock 146:88f7bda79d8e 584 * Arguments : Pointer to HCCA
TickTock 146:88f7bda79d8e 585 *
TickTock 146:88f7bda79d8e 586 * Returns :
TickTock 146:88f7bda79d8e 587 *
TickTock 146:88f7bda79d8e 588 **************************************************************************************************************
TickTock 146:88f7bda79d8e 589 */
TickTock 146:88f7bda79d8e 590
TickTock 146:88f7bda79d8e 591 void Host_HCCAInit (volatile HCCA *hcca)
TickTock 146:88f7bda79d8e 592 {
TickTock 146:88f7bda79d8e 593 USB_INT32U i;
TickTock 146:88f7bda79d8e 594
TickTock 146:88f7bda79d8e 595
TickTock 146:88f7bda79d8e 596 for (i = 0; i < 32; i++) {
TickTock 146:88f7bda79d8e 597
TickTock 146:88f7bda79d8e 598 hcca->IntTable[i] = 0;
TickTock 146:88f7bda79d8e 599 hcca->FrameNumber = 0;
TickTock 146:88f7bda79d8e 600 hcca->DoneHead = 0;
TickTock 146:88f7bda79d8e 601 }
TickTock 146:88f7bda79d8e 602
TickTock 146:88f7bda79d8e 603 }
TickTock 146:88f7bda79d8e 604
TickTock 146:88f7bda79d8e 605 /*
TickTock 146:88f7bda79d8e 606 **************************************************************************************************************
TickTock 146:88f7bda79d8e 607 * WAIT FOR WDH INTERRUPT
TickTock 146:88f7bda79d8e 608 *
TickTock 146:88f7bda79d8e 609 * Description: This function is infinite loop which breaks when ever a WDH interrupt rises
TickTock 146:88f7bda79d8e 610 *
TickTock 146:88f7bda79d8e 611 * Arguments : None
TickTock 146:88f7bda79d8e 612 *
TickTock 146:88f7bda79d8e 613 * Returns : None
TickTock 146:88f7bda79d8e 614 *
TickTock 146:88f7bda79d8e 615 **************************************************************************************************************
TickTock 146:88f7bda79d8e 616 */
TickTock 146:88f7bda79d8e 617
TickTock 146:88f7bda79d8e 618 void Host_WDHWait (void)
TickTock 146:88f7bda79d8e 619 {
TickTock 146:88f7bda79d8e 620 while (!HOST_WdhIntr)
TickTock 146:88f7bda79d8e 621 __WFI();
TickTock 146:88f7bda79d8e 622
TickTock 146:88f7bda79d8e 623 HOST_WdhIntr = 0;
TickTock 146:88f7bda79d8e 624 }
TickTock 146:88f7bda79d8e 625
TickTock 146:88f7bda79d8e 626 /*
TickTock 146:88f7bda79d8e 627 **************************************************************************************************************
TickTock 146:88f7bda79d8e 628 * READ LE 32U
TickTock 146:88f7bda79d8e 629 *
TickTock 146:88f7bda79d8e 630 * Description: This function is used to read an unsigned integer from a character buffer in the platform
TickTock 146:88f7bda79d8e 631 * containing little endian processor
TickTock 146:88f7bda79d8e 632 *
TickTock 146:88f7bda79d8e 633 * Arguments : pmem Pointer to the character buffer
TickTock 146:88f7bda79d8e 634 *
TickTock 146:88f7bda79d8e 635 * Returns : val Unsigned integer
TickTock 146:88f7bda79d8e 636 *
TickTock 146:88f7bda79d8e 637 **************************************************************************************************************
TickTock 146:88f7bda79d8e 638 */
TickTock 146:88f7bda79d8e 639
TickTock 146:88f7bda79d8e 640 USB_INT32U ReadLE32U (volatile USB_INT08U *pmem)
TickTock 146:88f7bda79d8e 641 {
TickTock 146:88f7bda79d8e 642 USB_INT32U val = *(USB_INT32U*)pmem;
TickTock 146:88f7bda79d8e 643 #ifdef __BIG_ENDIAN
TickTock 146:88f7bda79d8e 644 return __REV(val);
TickTock 146:88f7bda79d8e 645 #else
TickTock 146:88f7bda79d8e 646 return val;
TickTock 146:88f7bda79d8e 647 #endif
TickTock 146:88f7bda79d8e 648 }
TickTock 146:88f7bda79d8e 649
TickTock 146:88f7bda79d8e 650 /*
TickTock 146:88f7bda79d8e 651 **************************************************************************************************************
TickTock 146:88f7bda79d8e 652 * WRITE LE 32U
TickTock 146:88f7bda79d8e 653 *
TickTock 146:88f7bda79d8e 654 * Description: This function is used to write an unsigned integer into a charecter buffer in the platform
TickTock 146:88f7bda79d8e 655 * containing little endian processor.
TickTock 146:88f7bda79d8e 656 *
TickTock 146:88f7bda79d8e 657 * Arguments : pmem Pointer to the charecter buffer
TickTock 146:88f7bda79d8e 658 * val Integer value to be placed in the charecter buffer
TickTock 146:88f7bda79d8e 659 *
TickTock 146:88f7bda79d8e 660 * Returns : None
TickTock 146:88f7bda79d8e 661 *
TickTock 146:88f7bda79d8e 662 **************************************************************************************************************
TickTock 146:88f7bda79d8e 663 */
TickTock 146:88f7bda79d8e 664
TickTock 146:88f7bda79d8e 665 void WriteLE32U (volatile USB_INT08U *pmem,
TickTock 146:88f7bda79d8e 666 USB_INT32U val)
TickTock 146:88f7bda79d8e 667 {
TickTock 146:88f7bda79d8e 668 #ifdef __BIG_ENDIAN
TickTock 146:88f7bda79d8e 669 *(USB_INT32U*)pmem = __REV(val);
TickTock 146:88f7bda79d8e 670 #else
TickTock 146:88f7bda79d8e 671 *(USB_INT32U*)pmem = val;
TickTock 146:88f7bda79d8e 672 #endif
TickTock 146:88f7bda79d8e 673 }
TickTock 146:88f7bda79d8e 674
TickTock 146:88f7bda79d8e 675 /*
TickTock 146:88f7bda79d8e 676 **************************************************************************************************************
TickTock 146:88f7bda79d8e 677 * READ LE 16U
TickTock 146:88f7bda79d8e 678 *
TickTock 146:88f7bda79d8e 679 * Description: This function is used to read an unsigned short integer from a charecter buffer in the platform
TickTock 146:88f7bda79d8e 680 * containing little endian processor
TickTock 146:88f7bda79d8e 681 *
TickTock 146:88f7bda79d8e 682 * Arguments : pmem Pointer to the charecter buffer
TickTock 146:88f7bda79d8e 683 *
TickTock 146:88f7bda79d8e 684 * Returns : val Unsigned short integer
TickTock 146:88f7bda79d8e 685 *
TickTock 146:88f7bda79d8e 686 **************************************************************************************************************
TickTock 146:88f7bda79d8e 687 */
TickTock 146:88f7bda79d8e 688
TickTock 146:88f7bda79d8e 689 USB_INT16U ReadLE16U (volatile USB_INT08U *pmem)
TickTock 146:88f7bda79d8e 690 {
TickTock 146:88f7bda79d8e 691 USB_INT16U val = *(USB_INT16U*)pmem;
TickTock 146:88f7bda79d8e 692 #ifdef __BIG_ENDIAN
TickTock 146:88f7bda79d8e 693 return __REV16(val);
TickTock 146:88f7bda79d8e 694 #else
TickTock 146:88f7bda79d8e 695 return val;
TickTock 146:88f7bda79d8e 696 #endif
TickTock 146:88f7bda79d8e 697 }
TickTock 146:88f7bda79d8e 698
TickTock 146:88f7bda79d8e 699 /*
TickTock 146:88f7bda79d8e 700 **************************************************************************************************************
TickTock 146:88f7bda79d8e 701 * WRITE LE 16U
TickTock 146:88f7bda79d8e 702 *
TickTock 146:88f7bda79d8e 703 * Description: This function is used to write an unsigned short integer into a charecter buffer in the
TickTock 146:88f7bda79d8e 704 * platform containing little endian processor
TickTock 146:88f7bda79d8e 705 *
TickTock 146:88f7bda79d8e 706 * Arguments : pmem Pointer to the charecter buffer
TickTock 146:88f7bda79d8e 707 * val Value to be placed in the charecter buffer
TickTock 146:88f7bda79d8e 708 *
TickTock 146:88f7bda79d8e 709 * Returns : None
TickTock 146:88f7bda79d8e 710 *
TickTock 146:88f7bda79d8e 711 **************************************************************************************************************
TickTock 146:88f7bda79d8e 712 */
TickTock 146:88f7bda79d8e 713
TickTock 146:88f7bda79d8e 714 void WriteLE16U (volatile USB_INT08U *pmem,
TickTock 146:88f7bda79d8e 715 USB_INT16U val)
TickTock 146:88f7bda79d8e 716 {
TickTock 146:88f7bda79d8e 717 #ifdef __BIG_ENDIAN
TickTock 146:88f7bda79d8e 718 *(USB_INT16U*)pmem = (__REV16(val) & 0xFFFF);
TickTock 146:88f7bda79d8e 719 #else
TickTock 146:88f7bda79d8e 720 *(USB_INT16U*)pmem = val;
TickTock 146:88f7bda79d8e 721 #endif
TickTock 146:88f7bda79d8e 722 }
TickTock 146:88f7bda79d8e 723
TickTock 146:88f7bda79d8e 724 /*
TickTock 146:88f7bda79d8e 725 **************************************************************************************************************
TickTock 146:88f7bda79d8e 726 * READ BE 32U
TickTock 146:88f7bda79d8e 727 *
TickTock 146:88f7bda79d8e 728 * Description: This function is used to read an unsigned integer from a charecter buffer in the platform
TickTock 146:88f7bda79d8e 729 * containing big endian processor
TickTock 146:88f7bda79d8e 730 *
TickTock 146:88f7bda79d8e 731 * Arguments : pmem Pointer to the charecter buffer
TickTock 146:88f7bda79d8e 732 *
TickTock 146:88f7bda79d8e 733 * Returns : val Unsigned integer
TickTock 146:88f7bda79d8e 734 *
TickTock 146:88f7bda79d8e 735 **************************************************************************************************************
TickTock 146:88f7bda79d8e 736 */
TickTock 146:88f7bda79d8e 737
TickTock 146:88f7bda79d8e 738 USB_INT32U ReadBE32U (volatile USB_INT08U *pmem)
TickTock 146:88f7bda79d8e 739 {
TickTock 146:88f7bda79d8e 740 USB_INT32U val = *(USB_INT32U*)pmem;
TickTock 146:88f7bda79d8e 741 #ifdef __BIG_ENDIAN
TickTock 146:88f7bda79d8e 742 return val;
TickTock 146:88f7bda79d8e 743 #else
TickTock 146:88f7bda79d8e 744 return __REV(val);
TickTock 146:88f7bda79d8e 745 #endif
TickTock 146:88f7bda79d8e 746 }
TickTock 146:88f7bda79d8e 747
TickTock 146:88f7bda79d8e 748 /*
TickTock 146:88f7bda79d8e 749 **************************************************************************************************************
TickTock 146:88f7bda79d8e 750 * WRITE BE 32U
TickTock 146:88f7bda79d8e 751 *
TickTock 146:88f7bda79d8e 752 * Description: This function is used to write an unsigned integer into a charecter buffer in the platform
TickTock 146:88f7bda79d8e 753 * containing big endian processor
TickTock 146:88f7bda79d8e 754 *
TickTock 146:88f7bda79d8e 755 * Arguments : pmem Pointer to the charecter buffer
TickTock 146:88f7bda79d8e 756 * val Value to be placed in the charecter buffer
TickTock 146:88f7bda79d8e 757 *
TickTock 146:88f7bda79d8e 758 * Returns : None
TickTock 146:88f7bda79d8e 759 *
TickTock 146:88f7bda79d8e 760 **************************************************************************************************************
TickTock 146:88f7bda79d8e 761 */
TickTock 146:88f7bda79d8e 762
TickTock 146:88f7bda79d8e 763 void WriteBE32U (volatile USB_INT08U *pmem,
TickTock 146:88f7bda79d8e 764 USB_INT32U val)
TickTock 146:88f7bda79d8e 765 {
TickTock 146:88f7bda79d8e 766 #ifdef __BIG_ENDIAN
TickTock 146:88f7bda79d8e 767 *(USB_INT32U*)pmem = val;
TickTock 146:88f7bda79d8e 768 #else
TickTock 146:88f7bda79d8e 769 *(USB_INT32U*)pmem = __REV(val);
TickTock 146:88f7bda79d8e 770 #endif
TickTock 146:88f7bda79d8e 771 }
TickTock 146:88f7bda79d8e 772
TickTock 146:88f7bda79d8e 773 /*
TickTock 146:88f7bda79d8e 774 **************************************************************************************************************
TickTock 146:88f7bda79d8e 775 * READ BE 16U
TickTock 146:88f7bda79d8e 776 *
TickTock 146:88f7bda79d8e 777 * Description: This function is used to read an unsigned short integer from a charecter buffer in the platform
TickTock 146:88f7bda79d8e 778 * containing big endian processor
TickTock 146:88f7bda79d8e 779 *
TickTock 146:88f7bda79d8e 780 * Arguments : pmem Pointer to the charecter buffer
TickTock 146:88f7bda79d8e 781 *
TickTock 146:88f7bda79d8e 782 * Returns : val Unsigned short integer
TickTock 146:88f7bda79d8e 783 *
TickTock 146:88f7bda79d8e 784 **************************************************************************************************************
TickTock 146:88f7bda79d8e 785 */
TickTock 146:88f7bda79d8e 786
TickTock 146:88f7bda79d8e 787 USB_INT16U ReadBE16U (volatile USB_INT08U *pmem)
TickTock 146:88f7bda79d8e 788 {
TickTock 146:88f7bda79d8e 789 USB_INT16U val = *(USB_INT16U*)pmem;
TickTock 146:88f7bda79d8e 790 #ifdef __BIG_ENDIAN
TickTock 146:88f7bda79d8e 791 return val;
TickTock 146:88f7bda79d8e 792 #else
TickTock 146:88f7bda79d8e 793 return __REV16(val);
TickTock 146:88f7bda79d8e 794 #endif
TickTock 146:88f7bda79d8e 795 }
TickTock 146:88f7bda79d8e 796
TickTock 146:88f7bda79d8e 797 /*
TickTock 146:88f7bda79d8e 798 **************************************************************************************************************
TickTock 146:88f7bda79d8e 799 * WRITE BE 16U
TickTock 146:88f7bda79d8e 800 *
TickTock 146:88f7bda79d8e 801 * Description: This function is used to write an unsigned short integer into the charecter buffer in the
TickTock 146:88f7bda79d8e 802 * platform containing big endian processor
TickTock 146:88f7bda79d8e 803 *
TickTock 146:88f7bda79d8e 804 * Arguments : pmem Pointer to the charecter buffer
TickTock 146:88f7bda79d8e 805 * val Value to be placed in the charecter buffer
TickTock 146:88f7bda79d8e 806 *
TickTock 146:88f7bda79d8e 807 * Returns : None
TickTock 146:88f7bda79d8e 808 *
TickTock 146:88f7bda79d8e 809 **************************************************************************************************************
TickTock 146:88f7bda79d8e 810 */
TickTock 146:88f7bda79d8e 811
TickTock 146:88f7bda79d8e 812 void WriteBE16U (volatile USB_INT08U *pmem,
TickTock 146:88f7bda79d8e 813 USB_INT16U val)
TickTock 146:88f7bda79d8e 814 {
TickTock 146:88f7bda79d8e 815 #ifdef __BIG_ENDIAN
TickTock 146:88f7bda79d8e 816 *(USB_INT16U*)pmem = val;
TickTock 146:88f7bda79d8e 817 #else
TickTock 146:88f7bda79d8e 818 *(USB_INT16U*)pmem = (__REV16(val) & 0xFFFF);
TickTock 146:88f7bda79d8e 819 #endif
TickTock 146:88f7bda79d8e 820 }