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_ms.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_ms.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
TickTock 146:88f7bda79d8e 33 USB_INT32U MS_BlkSize;
TickTock 146:88f7bda79d8e 34
TickTock 146:88f7bda79d8e 35 /*
TickTock 146:88f7bda79d8e 36 **************************************************************************************************************
TickTock 146:88f7bda79d8e 37 * INITIALIZE MASS STORAGE INTERFACE
TickTock 146:88f7bda79d8e 38 *
TickTock 146:88f7bda79d8e 39 * Description: This function initializes the mass storage interface
TickTock 146:88f7bda79d8e 40 *
TickTock 146:88f7bda79d8e 41 * Arguments : None
TickTock 146:88f7bda79d8e 42 *
TickTock 146:88f7bda79d8e 43 * Returns : OK if Success
TickTock 146:88f7bda79d8e 44 * ERR_INVALID_BOOTSIG if Failed
TickTock 146:88f7bda79d8e 45 *
TickTock 146:88f7bda79d8e 46 **************************************************************************************************************
TickTock 146:88f7bda79d8e 47 */
TickTock 146:88f7bda79d8e 48
TickTock 146:88f7bda79d8e 49 USB_INT32S MS_Init (USB_INT32U *blkSize, USB_INT32U *numBlks, USB_INT08U *inquiryResult)
TickTock 146:88f7bda79d8e 50 {
TickTock 146:88f7bda79d8e 51 USB_INT08U retry;
TickTock 146:88f7bda79d8e 52 USB_INT32S rc;
TickTock 146:88f7bda79d8e 53
TickTock 146:88f7bda79d8e 54 MS_GetMaxLUN(); /* Get maximum logical unit number */
TickTock 146:88f7bda79d8e 55 retry = 80;
TickTock 146:88f7bda79d8e 56 while(retry) {
TickTock 146:88f7bda79d8e 57 rc = MS_TestUnitReady(); /* Test whether the unit is ready */
TickTock 146:88f7bda79d8e 58 if (rc == OK) {
TickTock 146:88f7bda79d8e 59 break;
TickTock 146:88f7bda79d8e 60 }
TickTock 146:88f7bda79d8e 61 MS_GetSenseInfo(); /* Get sense information */
TickTock 146:88f7bda79d8e 62 retry--;
TickTock 146:88f7bda79d8e 63 }
TickTock 146:88f7bda79d8e 64 if (rc != OK) {
TickTock 146:88f7bda79d8e 65 PRINT_Err(rc);
TickTock 146:88f7bda79d8e 66 return (rc);
TickTock 146:88f7bda79d8e 67 }
TickTock 146:88f7bda79d8e 68 rc = MS_ReadCapacity(numBlks, blkSize); /* Read capacity of the disk */
TickTock 146:88f7bda79d8e 69 MS_BlkSize = *blkSize; // Set global
TickTock 146:88f7bda79d8e 70 rc = MS_Inquire (inquiryResult);
TickTock 146:88f7bda79d8e 71 return (rc);
TickTock 146:88f7bda79d8e 72 }
TickTock 146:88f7bda79d8e 73 /*
TickTock 146:88f7bda79d8e 74 **************************************************************************************************************
TickTock 146:88f7bda79d8e 75 * PARSE THE CONFIGURATION
TickTock 146:88f7bda79d8e 76 *
TickTock 146:88f7bda79d8e 77 * Description: This function is used to parse the configuration
TickTock 146:88f7bda79d8e 78 *
TickTock 146:88f7bda79d8e 79 * Arguments : None
TickTock 146:88f7bda79d8e 80 *
TickTock 146:88f7bda79d8e 81 * Returns : OK if Success
TickTock 146:88f7bda79d8e 82 * ERR_INVALID_BOOTSIG if Failed
TickTock 146:88f7bda79d8e 83 *
TickTock 146:88f7bda79d8e 84 **************************************************************************************************************
TickTock 146:88f7bda79d8e 85 */
TickTock 146:88f7bda79d8e 86
TickTock 146:88f7bda79d8e 87 USB_INT32S MS_ParseConfiguration (void)
TickTock 146:88f7bda79d8e 88 {
TickTock 146:88f7bda79d8e 89 volatile USB_INT08U *desc_ptr;
TickTock 146:88f7bda79d8e 90 USB_INT08U ms_int_found;
TickTock 146:88f7bda79d8e 91
TickTock 146:88f7bda79d8e 92
TickTock 146:88f7bda79d8e 93 desc_ptr = TDBuffer;
TickTock 146:88f7bda79d8e 94 ms_int_found = 0;
TickTock 146:88f7bda79d8e 95
TickTock 146:88f7bda79d8e 96 if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) {
TickTock 146:88f7bda79d8e 97 return (ERR_BAD_CONFIGURATION);
TickTock 146:88f7bda79d8e 98 }
TickTock 146:88f7bda79d8e 99 desc_ptr += desc_ptr[0];
TickTock 146:88f7bda79d8e 100
TickTock 146:88f7bda79d8e 101 while (desc_ptr != TDBuffer + ReadLE16U(&TDBuffer[2])) {
TickTock 146:88f7bda79d8e 102
TickTock 146:88f7bda79d8e 103 switch (desc_ptr[1]) {
TickTock 146:88f7bda79d8e 104
TickTock 146:88f7bda79d8e 105 case USB_DESCRIPTOR_TYPE_INTERFACE: /* If it is an interface descriptor */
TickTock 146:88f7bda79d8e 106 if (desc_ptr[5] == MASS_STORAGE_CLASS && /* check if the class is mass storage */
TickTock 146:88f7bda79d8e 107 desc_ptr[6] == MASS_STORAGE_SUBCLASS_SCSI && /* check if the subclass is SCSI */
TickTock 146:88f7bda79d8e 108 desc_ptr[7] == MASS_STORAGE_PROTOCOL_BO) { /* check if the protocol is Bulk only */
TickTock 146:88f7bda79d8e 109 ms_int_found = 1;
TickTock 146:88f7bda79d8e 110 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
TickTock 146:88f7bda79d8e 111 }
TickTock 146:88f7bda79d8e 112 break;
TickTock 146:88f7bda79d8e 113
TickTock 146:88f7bda79d8e 114 case USB_DESCRIPTOR_TYPE_ENDPOINT: /* If it is an endpoint descriptor */
TickTock 146:88f7bda79d8e 115 if ((desc_ptr[3] & 0x03) == 0x02) { /* If it is Bulk endpoint */
TickTock 146:88f7bda79d8e 116 if (desc_ptr[2] & 0x80) { /* If it is In endpoint */
TickTock 146:88f7bda79d8e 117 EDBulkIn->Control = 1 | /* USB address */
TickTock 146:88f7bda79d8e 118 ((desc_ptr[2] & 0x7F) << 7) | /* Endpoint address */
TickTock 146:88f7bda79d8e 119 (2 << 11) | /* direction */
TickTock 146:88f7bda79d8e 120 (ReadLE16U(&desc_ptr[4]) << 16); /* MaxPkt Size */
TickTock 146:88f7bda79d8e 121 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
TickTock 146:88f7bda79d8e 122 } else { /* If it is Out endpoint */
TickTock 146:88f7bda79d8e 123 EDBulkOut->Control = 1 | /* USB address */
TickTock 146:88f7bda79d8e 124 ((desc_ptr[2] & 0x7F) << 7) | /* Endpoint address */
TickTock 146:88f7bda79d8e 125 (1 << 11) | /* direction */
TickTock 146:88f7bda79d8e 126 (ReadLE16U(&desc_ptr[4]) << 16); /* MaxPkt Size */
TickTock 146:88f7bda79d8e 127 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
TickTock 146:88f7bda79d8e 128 }
TickTock 146:88f7bda79d8e 129 } else { /* If it is not bulk end point */
TickTock 146:88f7bda79d8e 130 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
TickTock 146:88f7bda79d8e 131 }
TickTock 146:88f7bda79d8e 132 break;
TickTock 146:88f7bda79d8e 133
TickTock 146:88f7bda79d8e 134 default: /* If the descriptor is neither interface nor endpoint */
TickTock 146:88f7bda79d8e 135 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
TickTock 146:88f7bda79d8e 136 break;
TickTock 146:88f7bda79d8e 137 }
TickTock 146:88f7bda79d8e 138 }
TickTock 146:88f7bda79d8e 139 if (ms_int_found) {
TickTock 146:88f7bda79d8e 140 PRINT_Log("Mass Storage device connected\n");
TickTock 146:88f7bda79d8e 141 return (OK);
TickTock 146:88f7bda79d8e 142 } else {
TickTock 146:88f7bda79d8e 143 PRINT_Log("Not a Mass Storage device\n");
TickTock 146:88f7bda79d8e 144 return (ERR_NO_MS_INTERFACE);
TickTock 146:88f7bda79d8e 145 }
TickTock 146:88f7bda79d8e 146 }
TickTock 146:88f7bda79d8e 147
TickTock 146:88f7bda79d8e 148 /*
TickTock 146:88f7bda79d8e 149 **************************************************************************************************************
TickTock 146:88f7bda79d8e 150 * GET MAXIMUM LOGICAL UNIT
TickTock 146:88f7bda79d8e 151 *
TickTock 146:88f7bda79d8e 152 * Description: This function returns the maximum logical unit from the device
TickTock 146:88f7bda79d8e 153 *
TickTock 146:88f7bda79d8e 154 * Arguments : None
TickTock 146:88f7bda79d8e 155 *
TickTock 146:88f7bda79d8e 156 * Returns : OK if Success
TickTock 146:88f7bda79d8e 157 * ERR_INVALID_BOOTSIG if Failed
TickTock 146:88f7bda79d8e 158 *
TickTock 146:88f7bda79d8e 159 **************************************************************************************************************
TickTock 146:88f7bda79d8e 160 */
TickTock 146:88f7bda79d8e 161
TickTock 146:88f7bda79d8e 162 USB_INT32S MS_GetMaxLUN (void)
TickTock 146:88f7bda79d8e 163 {
TickTock 146:88f7bda79d8e 164 USB_INT32S rc;
TickTock 146:88f7bda79d8e 165
TickTock 146:88f7bda79d8e 166
TickTock 146:88f7bda79d8e 167 rc = Host_CtrlRecv(USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE,
TickTock 146:88f7bda79d8e 168 MS_GET_MAX_LUN_REQ,
TickTock 146:88f7bda79d8e 169 0,
TickTock 146:88f7bda79d8e 170 0,
TickTock 146:88f7bda79d8e 171 1,
TickTock 146:88f7bda79d8e 172 TDBuffer);
TickTock 146:88f7bda79d8e 173 return (rc);
TickTock 146:88f7bda79d8e 174 }
TickTock 146:88f7bda79d8e 175
TickTock 146:88f7bda79d8e 176 /*
TickTock 146:88f7bda79d8e 177 **************************************************************************************************************
TickTock 146:88f7bda79d8e 178 * GET SENSE INFORMATION
TickTock 146:88f7bda79d8e 179 *
TickTock 146:88f7bda79d8e 180 * Description: This function is used to get sense information from the device
TickTock 146:88f7bda79d8e 181 *
TickTock 146:88f7bda79d8e 182 * Arguments : None
TickTock 146:88f7bda79d8e 183 *
TickTock 146:88f7bda79d8e 184 * Returns : OK if Success
TickTock 146:88f7bda79d8e 185 * ERROR if Failed
TickTock 146:88f7bda79d8e 186 *
TickTock 146:88f7bda79d8e 187 **************************************************************************************************************
TickTock 146:88f7bda79d8e 188 */
TickTock 146:88f7bda79d8e 189
TickTock 146:88f7bda79d8e 190 USB_INT32S MS_GetSenseInfo (void)
TickTock 146:88f7bda79d8e 191 {
TickTock 146:88f7bda79d8e 192 USB_INT32S rc;
TickTock 146:88f7bda79d8e 193
TickTock 146:88f7bda79d8e 194
TickTock 146:88f7bda79d8e 195 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_REQUEST_SENSE, 6);
TickTock 146:88f7bda79d8e 196 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
TickTock 146:88f7bda79d8e 197 if (rc == OK) {
TickTock 146:88f7bda79d8e 198 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, 18);
TickTock 146:88f7bda79d8e 199 if (rc == OK) {
TickTock 146:88f7bda79d8e 200 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
TickTock 146:88f7bda79d8e 201 if (rc == OK) {
TickTock 146:88f7bda79d8e 202 if (TDBuffer[12] != 0) {
TickTock 146:88f7bda79d8e 203 rc = ERR_MS_CMD_FAILED;
TickTock 146:88f7bda79d8e 204 }
TickTock 146:88f7bda79d8e 205 }
TickTock 146:88f7bda79d8e 206 }
TickTock 146:88f7bda79d8e 207 }
TickTock 146:88f7bda79d8e 208 return (rc);
TickTock 146:88f7bda79d8e 209 }
TickTock 146:88f7bda79d8e 210
TickTock 146:88f7bda79d8e 211 /*
TickTock 146:88f7bda79d8e 212 **************************************************************************************************************
TickTock 146:88f7bda79d8e 213 * TEST UNIT READY
TickTock 146:88f7bda79d8e 214 *
TickTock 146:88f7bda79d8e 215 * Description: This function is used to test whether the unit is ready or not
TickTock 146:88f7bda79d8e 216 *
TickTock 146:88f7bda79d8e 217 * Arguments : None
TickTock 146:88f7bda79d8e 218 *
TickTock 146:88f7bda79d8e 219 * Returns : OK if Success
TickTock 146:88f7bda79d8e 220 * ERROR if Failed
TickTock 146:88f7bda79d8e 221 *
TickTock 146:88f7bda79d8e 222 **************************************************************************************************************
TickTock 146:88f7bda79d8e 223 */
TickTock 146:88f7bda79d8e 224
TickTock 146:88f7bda79d8e 225 USB_INT32S MS_TestUnitReady (void)
TickTock 146:88f7bda79d8e 226 {
TickTock 146:88f7bda79d8e 227 USB_INT32S rc;
TickTock 146:88f7bda79d8e 228
TickTock 146:88f7bda79d8e 229
TickTock 146:88f7bda79d8e 230 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_NONE, SCSI_CMD_TEST_UNIT_READY, 6);
TickTock 146:88f7bda79d8e 231 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
TickTock 146:88f7bda79d8e 232 if (rc == OK) {
TickTock 146:88f7bda79d8e 233 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
TickTock 146:88f7bda79d8e 234 if (rc == OK) {
TickTock 146:88f7bda79d8e 235 if (TDBuffer[12] != 0) {
TickTock 146:88f7bda79d8e 236 rc = ERR_MS_CMD_FAILED;
TickTock 146:88f7bda79d8e 237 }
TickTock 146:88f7bda79d8e 238 }
TickTock 146:88f7bda79d8e 239 }
TickTock 146:88f7bda79d8e 240 return (rc);
TickTock 146:88f7bda79d8e 241 }
TickTock 146:88f7bda79d8e 242
TickTock 146:88f7bda79d8e 243 /*
TickTock 146:88f7bda79d8e 244 **************************************************************************************************************
TickTock 146:88f7bda79d8e 245 * READ CAPACITY
TickTock 146:88f7bda79d8e 246 *
TickTock 146:88f7bda79d8e 247 * Description: This function is used to read the capacity of the mass storage device
TickTock 146:88f7bda79d8e 248 *
TickTock 146:88f7bda79d8e 249 * Arguments : None
TickTock 146:88f7bda79d8e 250 *
TickTock 146:88f7bda79d8e 251 * Returns : OK if Success
TickTock 146:88f7bda79d8e 252 * ERROR if Failed
TickTock 146:88f7bda79d8e 253 *
TickTock 146:88f7bda79d8e 254 **************************************************************************************************************
TickTock 146:88f7bda79d8e 255 */
TickTock 146:88f7bda79d8e 256
TickTock 146:88f7bda79d8e 257 USB_INT32S MS_ReadCapacity (USB_INT32U *numBlks, USB_INT32U *blkSize)
TickTock 146:88f7bda79d8e 258 {
TickTock 146:88f7bda79d8e 259 USB_INT32S rc;
TickTock 146:88f7bda79d8e 260
TickTock 146:88f7bda79d8e 261
TickTock 146:88f7bda79d8e 262 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_READ_CAPACITY, 10);
TickTock 146:88f7bda79d8e 263 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
TickTock 146:88f7bda79d8e 264 if (rc == OK) {
TickTock 146:88f7bda79d8e 265 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, 8);
TickTock 146:88f7bda79d8e 266 if (rc == OK) {
TickTock 146:88f7bda79d8e 267 if (numBlks)
TickTock 146:88f7bda79d8e 268 *numBlks = ReadBE32U(&TDBuffer[0]);
TickTock 146:88f7bda79d8e 269 if (blkSize)
TickTock 146:88f7bda79d8e 270 *blkSize = ReadBE32U(&TDBuffer[4]);
TickTock 146:88f7bda79d8e 271 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
TickTock 146:88f7bda79d8e 272 if (rc == OK) {
TickTock 146:88f7bda79d8e 273 if (TDBuffer[12] != 0) {
TickTock 146:88f7bda79d8e 274 rc = ERR_MS_CMD_FAILED;
TickTock 146:88f7bda79d8e 275 }
TickTock 146:88f7bda79d8e 276 }
TickTock 146:88f7bda79d8e 277 }
TickTock 146:88f7bda79d8e 278 }
TickTock 146:88f7bda79d8e 279 return (rc);
TickTock 146:88f7bda79d8e 280 }
TickTock 146:88f7bda79d8e 281
TickTock 146:88f7bda79d8e 282
TickTock 146:88f7bda79d8e 283
TickTock 146:88f7bda79d8e 284 USB_INT32S MS_Inquire (USB_INT08U *response)
TickTock 146:88f7bda79d8e 285 {
TickTock 146:88f7bda79d8e 286 USB_INT32S rc;
TickTock 146:88f7bda79d8e 287 USB_INT32U i;
TickTock 146:88f7bda79d8e 288
TickTock 146:88f7bda79d8e 289 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_INQUIRY, 6);
TickTock 146:88f7bda79d8e 290 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
TickTock 146:88f7bda79d8e 291 if (rc == OK) {
TickTock 146:88f7bda79d8e 292 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, INQUIRY_LENGTH);
TickTock 146:88f7bda79d8e 293 if (rc == OK) {
TickTock 146:88f7bda79d8e 294 if (response) {
TickTock 146:88f7bda79d8e 295 for ( i = 0; i < INQUIRY_LENGTH; i++ )
TickTock 146:88f7bda79d8e 296 *response++ = *TDBuffer++;
TickTock 146:88f7bda79d8e 297 #if 0
TickTock 146:88f7bda79d8e 298 MemCpy (response, TDBuffer, INQUIRY_LENGTH);
TickTock 146:88f7bda79d8e 299 StrNullTrailingSpace (response->vendorID, SCSI_INQUIRY_VENDORCHARS);
TickTock 146:88f7bda79d8e 300 StrNullTrailingSpace (response->productID, SCSI_INQUIRY_PRODUCTCHARS);
TickTock 146:88f7bda79d8e 301 StrNullTrailingSpace (response->productRev, SCSI_INQUIRY_REVCHARS);
TickTock 146:88f7bda79d8e 302 #endif
TickTock 146:88f7bda79d8e 303 }
TickTock 146:88f7bda79d8e 304 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
TickTock 146:88f7bda79d8e 305 if (rc == OK) {
TickTock 146:88f7bda79d8e 306 if (TDBuffer[12] != 0) { // bCSWStatus byte
TickTock 146:88f7bda79d8e 307 rc = ERR_MS_CMD_FAILED;
TickTock 146:88f7bda79d8e 308 }
TickTock 146:88f7bda79d8e 309 }
TickTock 146:88f7bda79d8e 310 }
TickTock 146:88f7bda79d8e 311 }
TickTock 146:88f7bda79d8e 312 return (rc);
TickTock 146:88f7bda79d8e 313 }
TickTock 146:88f7bda79d8e 314
TickTock 146:88f7bda79d8e 315 /*
TickTock 146:88f7bda79d8e 316 **************************************************************************************************************
TickTock 146:88f7bda79d8e 317 * RECEIVE THE BULK DATA
TickTock 146:88f7bda79d8e 318 *
TickTock 146:88f7bda79d8e 319 * Description: This function is used to receive the bulk data
TickTock 146:88f7bda79d8e 320 *
TickTock 146:88f7bda79d8e 321 * Arguments : None
TickTock 146:88f7bda79d8e 322 *
TickTock 146:88f7bda79d8e 323 * Returns : OK if Success
TickTock 146:88f7bda79d8e 324 * ERR_INVALID_BOOTSIG if Failed
TickTock 146:88f7bda79d8e 325 *
TickTock 146:88f7bda79d8e 326 **************************************************************************************************************
TickTock 146:88f7bda79d8e 327 */
TickTock 146:88f7bda79d8e 328
TickTock 146:88f7bda79d8e 329 USB_INT32S MS_BulkRecv ( USB_INT32U block_number,
TickTock 146:88f7bda79d8e 330 USB_INT16U num_blocks,
TickTock 146:88f7bda79d8e 331 volatile USB_INT08U *user_buffer)
TickTock 146:88f7bda79d8e 332 {
TickTock 146:88f7bda79d8e 333 USB_INT32S rc;
TickTock 146:88f7bda79d8e 334 int i;
TickTock 146:88f7bda79d8e 335 volatile USB_INT08U *c = user_buffer;
TickTock 146:88f7bda79d8e 336 for (i=0;i<MS_BlkSize*num_blocks;i++)
TickTock 146:88f7bda79d8e 337 *c++ = 0;
TickTock 146:88f7bda79d8e 338
TickTock 146:88f7bda79d8e 339
TickTock 146:88f7bda79d8e 340 Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_IN, SCSI_CMD_READ_10, 10);
TickTock 146:88f7bda79d8e 341
TickTock 146:88f7bda79d8e 342 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
TickTock 146:88f7bda79d8e 343 if (rc == OK) {
TickTock 146:88f7bda79d8e 344 rc = Host_ProcessTD(EDBulkIn, TD_IN, user_buffer, MS_BlkSize * num_blocks);
TickTock 146:88f7bda79d8e 345 if (rc == OK) {
TickTock 146:88f7bda79d8e 346 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
TickTock 146:88f7bda79d8e 347 if (rc == OK) {
TickTock 146:88f7bda79d8e 348 if (TDBuffer[12] != 0) {
TickTock 146:88f7bda79d8e 349 rc = ERR_MS_CMD_FAILED;
TickTock 146:88f7bda79d8e 350 }
TickTock 146:88f7bda79d8e 351 }
TickTock 146:88f7bda79d8e 352 }
TickTock 146:88f7bda79d8e 353 }
TickTock 146:88f7bda79d8e 354 return (rc);
TickTock 146:88f7bda79d8e 355 }
TickTock 146:88f7bda79d8e 356
TickTock 146:88f7bda79d8e 357 /*
TickTock 146:88f7bda79d8e 358 **************************************************************************************************************
TickTock 146:88f7bda79d8e 359 * SEND BULK DATA
TickTock 146:88f7bda79d8e 360 *
TickTock 146:88f7bda79d8e 361 * Description: This function is used to send the bulk data
TickTock 146:88f7bda79d8e 362 *
TickTock 146:88f7bda79d8e 363 * Arguments : None
TickTock 146:88f7bda79d8e 364 *
TickTock 146:88f7bda79d8e 365 * Returns : OK if Success
TickTock 146:88f7bda79d8e 366 * ERR_INVALID_BOOTSIG if Failed
TickTock 146:88f7bda79d8e 367 *
TickTock 146:88f7bda79d8e 368 **************************************************************************************************************
TickTock 146:88f7bda79d8e 369 */
TickTock 146:88f7bda79d8e 370
TickTock 146:88f7bda79d8e 371 USB_INT32S MS_BulkSend ( USB_INT32U block_number,
TickTock 146:88f7bda79d8e 372 USB_INT16U num_blocks,
TickTock 146:88f7bda79d8e 373 volatile USB_INT08U *user_buffer)
TickTock 146:88f7bda79d8e 374 {
TickTock 146:88f7bda79d8e 375 USB_INT32S rc;
TickTock 146:88f7bda79d8e 376
TickTock 146:88f7bda79d8e 377
TickTock 146:88f7bda79d8e 378 Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_OUT, SCSI_CMD_WRITE_10, 10);
TickTock 146:88f7bda79d8e 379
TickTock 146:88f7bda79d8e 380 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
TickTock 146:88f7bda79d8e 381 if (rc == OK) {
TickTock 146:88f7bda79d8e 382 rc = Host_ProcessTD(EDBulkOut, TD_OUT, user_buffer, MS_BlkSize * num_blocks);
TickTock 146:88f7bda79d8e 383 if (rc == OK) {
TickTock 146:88f7bda79d8e 384 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
TickTock 146:88f7bda79d8e 385 if (rc == OK) {
TickTock 146:88f7bda79d8e 386 if (TDBuffer[12] != 0) {
TickTock 146:88f7bda79d8e 387 rc = ERR_MS_CMD_FAILED;
TickTock 146:88f7bda79d8e 388 }
TickTock 146:88f7bda79d8e 389 }
TickTock 146:88f7bda79d8e 390 }
TickTock 146:88f7bda79d8e 391 }
TickTock 146:88f7bda79d8e 392 return (rc);
TickTock 146:88f7bda79d8e 393 }
TickTock 146:88f7bda79d8e 394
TickTock 146:88f7bda79d8e 395 /*
TickTock 146:88f7bda79d8e 396 **************************************************************************************************************
TickTock 146:88f7bda79d8e 397 * FILL MASS STORAGE COMMAND
TickTock 146:88f7bda79d8e 398 *
TickTock 146:88f7bda79d8e 399 * Description: This function is used to fill the mass storage command
TickTock 146:88f7bda79d8e 400 *
TickTock 146:88f7bda79d8e 401 * Arguments : None
TickTock 146:88f7bda79d8e 402 *
TickTock 146:88f7bda79d8e 403 * Returns : OK if Success
TickTock 146:88f7bda79d8e 404 * ERR_INVALID_BOOTSIG if Failed
TickTock 146:88f7bda79d8e 405 *
TickTock 146:88f7bda79d8e 406 **************************************************************************************************************
TickTock 146:88f7bda79d8e 407 */
TickTock 146:88f7bda79d8e 408
TickTock 146:88f7bda79d8e 409 void Fill_MSCommand (USB_INT32U block_number,
TickTock 146:88f7bda79d8e 410 USB_INT32U block_size,
TickTock 146:88f7bda79d8e 411 USB_INT16U num_blocks,
TickTock 146:88f7bda79d8e 412 MS_DATA_DIR direction,
TickTock 146:88f7bda79d8e 413 USB_INT08U scsi_cmd,
TickTock 146:88f7bda79d8e 414 USB_INT08U scsi_cmd_len)
TickTock 146:88f7bda79d8e 415 {
TickTock 146:88f7bda79d8e 416 USB_INT32U data_len;
TickTock 146:88f7bda79d8e 417 static USB_INT32U tag_cnt = 0;
TickTock 146:88f7bda79d8e 418 USB_INT32U cnt;
TickTock 146:88f7bda79d8e 419
TickTock 146:88f7bda79d8e 420
TickTock 146:88f7bda79d8e 421 for (cnt = 0; cnt < CBW_SIZE; cnt++) {
TickTock 146:88f7bda79d8e 422 TDBuffer[cnt] = 0;
TickTock 146:88f7bda79d8e 423 }
TickTock 146:88f7bda79d8e 424 switch(scsi_cmd) {
TickTock 146:88f7bda79d8e 425
TickTock 146:88f7bda79d8e 426 case SCSI_CMD_TEST_UNIT_READY:
TickTock 146:88f7bda79d8e 427 data_len = 0;
TickTock 146:88f7bda79d8e 428 break;
TickTock 146:88f7bda79d8e 429 case SCSI_CMD_READ_CAPACITY:
TickTock 146:88f7bda79d8e 430 data_len = 8;
TickTock 146:88f7bda79d8e 431 break;
TickTock 146:88f7bda79d8e 432 case SCSI_CMD_REQUEST_SENSE:
TickTock 146:88f7bda79d8e 433 data_len = 18;
TickTock 146:88f7bda79d8e 434 break;
TickTock 146:88f7bda79d8e 435 case SCSI_CMD_INQUIRY:
TickTock 146:88f7bda79d8e 436 data_len = 36;
TickTock 146:88f7bda79d8e 437 break;
TickTock 146:88f7bda79d8e 438 default:
TickTock 146:88f7bda79d8e 439 data_len = block_size * num_blocks;
TickTock 146:88f7bda79d8e 440 break;
TickTock 146:88f7bda79d8e 441 }
TickTock 146:88f7bda79d8e 442 WriteLE32U(TDBuffer, CBW_SIGNATURE);
TickTock 146:88f7bda79d8e 443 WriteLE32U(&TDBuffer[4], tag_cnt);
TickTock 146:88f7bda79d8e 444 WriteLE32U(&TDBuffer[8], data_len);
TickTock 146:88f7bda79d8e 445 TDBuffer[12] = (direction == MS_DATA_DIR_NONE) ? 0 : direction;
TickTock 146:88f7bda79d8e 446 TDBuffer[14] = scsi_cmd_len; /* Length of the CBW */
TickTock 146:88f7bda79d8e 447 TDBuffer[15] = scsi_cmd;
TickTock 146:88f7bda79d8e 448 if ((scsi_cmd == SCSI_CMD_REQUEST_SENSE)
TickTock 146:88f7bda79d8e 449 || (scsi_cmd == SCSI_CMD_INQUIRY)) {
TickTock 146:88f7bda79d8e 450 TDBuffer[19] = (USB_INT08U)data_len;
TickTock 146:88f7bda79d8e 451 } else {
TickTock 146:88f7bda79d8e 452 WriteBE32U(&TDBuffer[17], block_number);
TickTock 146:88f7bda79d8e 453 }
TickTock 146:88f7bda79d8e 454 WriteBE16U(&TDBuffer[22], num_blocks);
TickTock 146:88f7bda79d8e 455 }