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:
Sun Jul 28 05:32:17 2013 +0000
Revision:
137:70853cf5a30f
Parent:
USBHostLite/usbhost_lpc17xx.c@109:3e6f0e8fca0d
Added update if screen touched on power; Fixed hang on immediate USB access

Who changed what in which revision?

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