class project main.cpp publish

Dependencies:   mbed C12832_lcd USBHost USBHostPTP LCD_Menu

mbed PTP hosting library

USB Device Interface: Architecture, Protocols, and Programming Class Project

/media/uploads/jakowisp/img_20130902_200043_188.jpg

Goal

Provide a generic PTP library to allow the mBed to host a PTP device

Details

  • Main thread configures and displays the Menu system, as Commands are selected in the menu a command value is set.
  • MSD thread blocks until a MSd device is connected, If a device is removed it will try to reconnect
  • PTP thread blocks until a PTP device ois connected. After connection of device, a session is opened, device information is retriewved, and object handles are recieved. As long as a PTP device is connected, the command value is checked for a non-zero value. when a command code is recieved, the statusFunction is changed from NULL, and the command executed. After execution the command code is cleared.

Project Hardware

  • mbed LPC1768 CPU board
  • mbed DEV-11695 application board
  • USB HUB
  • USB Mass Storage Device
  • Camera using PTP Protocol
  • Three USB Cables (normal mbed connection, connection to USB HUB, and connection to camera)

Testing

Test ItemDescriptionStatus
Unit Tests
connected1Test connected with a device.Pass
connected2Test connected without a device.Pass
connect1Test Connect() with no devicePass
connect2Test connect() with a ptp devicePass
connect3Test connect() with multiple PTP devicesNot Tested
connect4Test Connect() with multiple PTP devices and, ClassesNot Tested
cancel1Test CancelRequest() with invalid transactionIDNot Tested
cancel2Test CancelRequest() with valid transactionIDNot Tested
reset1Test DeviceReestRequest on Device that supports the callNot Tested
reset2Test DeviceReestRequest on Device that does not supports the callNot Tested
status1Test GetDeviceStatus returns statusNot Tested
extended1Test if GetExtendedEventData functions on device that does not support it.Not Tested
transaction1Test transaction() with unsupported opcodePass
transaction2Test transaction() with supported opcodePass
transaction3Test transaction() with opcode other than OpenSession or GetDeviceInfo before a session is openned.Pass
transaction4Test transaction() with getDeviceInfo before OpenSessionPass
transaction5Test transaction() with max number parameterPass
transaction6Test transaction() with no parametersPass
transaction7Test transaction() with 1 parameterPass
transaction8Test transaction() with no data stagePass
transaction9Test transaction() with 1 input data stagePass
transaction10Test transaction() with data stage that spans max packet sizePass
transaction11Test transaction() with Response container that has no paramertersPass
transaction12Test transaction() with response container that has parametersPass
operation1Test Operation() call without paramsNot Tested
operation2Test Operation() call with parametersNot Tested
opensession1Test OpenSession opens a sessionPass
close1Test Close Session closes a sessionPass
close2Test Close Session with an invlid sesison numberNot Tested
deviceinfo1Test getDeviceInfo obtains a device Info structurePass
powerdown1Test powerdown() on a device that does not support powerdown.Not Tested
selftest1Test SelfTest on device that does not support selftest.Not Tested
getobjecthandkles1GetObject handles for an empty devicePass
getobjecthandles2GetObjectHandles for all types.Pass
getobjecthandles3Get ObjectHandles filtered by typeNot Tested
getobjecthandles4GetObjectHandles filtered by associationNot Tested
getnumobjects1Test GetNumObjects for all types
getnumobjects2Test GetNumObjects for only image types
getnumobjects3Test GetNumObjects filtered by assoicationNot Tested
getobject1Test getObjectInfo for image types
getobject2Test getObjectInfo for non-image type
getthumb1Test getThumb for an object that has no Thumb
getthumb2Test getThumb for an image object
getstorageids1Test getStorageIDs gets the handles for the storage devices.
copyobject1Test CopyObject can copy an Object to a new locationNot Tested
copyobject2Test CopyObject fails for invalid handleNot Tested
copyobject3Test CopyObject fails for invalid storageIDNot Tested
copyobject4Test CopyObject fails for invalid parentNot Tested
copyobject5Test CopyObject returns a new handle in the varaible providedNot Tested
deleteobject1Test DeleteObject can remove an objectNot Tested
deleteobject2Test DeleteObject fails for invalid handleNot Tested
deleteobject3Test DeleteObject with the Format fieldNot Tested
protect1Test SetObjectProtection on a device that does not support the action.Not Tested
prop1Test GetDevicePropertyDesc functionsNot Tested
prop2Test GetDeviceProperty functionsNot Tested
prop3Test SetDeviceProperty FunctionsNot Tested
prop4Test ResetDeviceProperty funxctionsNot Tested
Functional
flow1"Complete flow-poweron, connect msd, connect PTP, all thumbs and files transferred"Pass
Stress
stress1Contious transfer of same imagePass
stress2Transfer of all images on camera - Continous.FailBuffer Overflow.
Performance
perf1Image transfer time per image
perf2Thumb transfer time per image
Interoperability
compat1Motorola Droid4 in Camera modePass
compat2Cannon Eos 10DFail
compat3Cannon Powershot a1400Pass
power up/ power down
power1No devices presentPass
power2MSD only presentPass
power3PTP Only presentPass
power4Both devices presentPass
USB Compliance
Compliance1Beagle USB trace tool able to track packets and class data.FailUSBHost not compliant.
Compliance2"Verify Control, Bulk_in, bulk_out and Interupt_in endpoints function."Pass

Example of using the USBHostPTP class

Import program

Go to the documentation of this file.
00001 /**
00002 *  @file main.cpp
00003 *  @brief Function to call USBHostPTP Library
00004 *  @author Dwayne Dilbeck
00005 *  @date 8/23/2013
00006 * 
00007 * mbed USBHostPTP Library
00008 *
00009 * @par Copyright:
00010 *  Copyright (c) 2013 Dwayne Dilbeck
00011 * @par License:
00012 *  This software is distributed under the terms of the GNU Lesser General Public License
00013 */
00014 #include "mbed.h"
00015 #include "C12832_lcd.h"
00016 #include "USBHostMSD.h"
00017 #include "USBHostPTP.h"
00018 #include "Selection.h"
00019 #include "Menu.h"
00020 #include "Navigator.h"
00021 
00022 /**
00023 * Define codes to represent Test Functions
00024 */
00025 #define GETALLJPG       0x01
00026 #define GETALLJPGTHUMB  0x02
00027 #define GETNUMJPG       0x03
00028 #define GETNUMOBJ       0x04
00029 #define DUMPDEVICEINFO  0x05
00030 #define CLOSESESSION    0xFF
00031 
00032 /**
00033 * Initiate Global variables
00034 */
00035 DigitalOut led(LED1);
00036 FILE * fp2;
00037 C12832_LCD lcd;
00038 USBHostPTP *ptpdev = NULL;
00039 USBHostMSD *msddev = NULL;
00040 char fname[256];
00041 uint8_t command=0x00;
00042 bool commandActive=false;
00043 void (*statusFunction)(void);
00044 
00045 /**
00046 * This function is used to handle the raw data recieved via the bulk pipes
00047 *
00048 * @param ptp Pointer to the PTP device
00049 * @param buffer Pointer to the data recieved
00050 * @param length Total data received to be processed
00051 * 
00052 * @return Void
00053 */
00054 void WriteObjectHandles(void *ptp,uint8_t *buffer,uint16_t length){
00055    int writeResult,errorcode;
00056    uint16_t transferLength=length;
00057    uint8_t *dataPtr=buffer;
00058    
00059    writeResult=fwrite(dataPtr,sizeof(uint8_t),transferLength,fp2);
00060    if( writeResult != transferLength) {
00061        errorcode=ferror(fp2);
00062        if( errorcode )
00063        {
00064           printf("\r\nError in writing to file %d\n",errorcode);
00065           error("Yucky@!");
00066        }
00067    }
00068 }
00069 
00070 /**
00071 * Test function 0x01
00072 *
00073 * @param numberOfImages A pointer to where to write the images on the device
00074 * @param numberOfThumbs A pointer to where to write the images on the device
00075 * @return void
00076 */
00077 void GetNumberOfThumbsAndImages(int *numberOfImages,int *numberOfThumbs){
00078     uint32_t fileHandle=0,numImages=0;
00079     int internalNumberOfImages=0;
00080     int internalNumberOfThumbs=0;
00081     
00082     FILE *fp = fopen("/usb2/objHandles.bin", "rb");
00083     fread(&numImages,sizeof(uint32_t),1,fp);
00084     while(numImages>0){
00085        fread(&fileHandle,sizeof(uint32_t),1,fp);
00086        ptpdev->GetObjectInfo(fileHandle);
00087        
00088        if (ptpdev->objectInfo.thumbFormat == 0x3801 ) {
00089           internalNumberOfThumbs++;
00090        }
00091        if (ptpdev->objectInfo.objectFormat == 0x3801 ) {
00092           internalNumberOfImages++;
00093        }
00094         numImages--;
00095     }
00096     fclose(fp);
00097     *numberOfImages = internalNumberOfImages;
00098     *numberOfThumbs = internalNumberOfThumbs;
00099 
00100 }
00101 
00102 /**
00103 * Retrieve all thumbnail images and real images that are JPG files.
00104 */
00105 void GetAllImagesAndThumbs(void) {
00106     FILE *fp;
00107         
00108     uint32_t fileHandle=0,numImages=0;
00109     
00110             printf("objectid,objectinfosize,imagetype,thumbtype\r\n");
00111             fp = fopen("/usb2/objHandles.bin", "rb");
00112             
00113             fread(&numImages,sizeof(uint32_t),1,fp);
00114             while(numImages>0){
00115                fread(&fileHandle,sizeof(uint32_t),1,fp);
00116                ptpdev->GetObjectInfo(fileHandle);
00117                printf("%ld,%x,%x,%x\r\n",numImages,fileHandle,ptpdev->objectInfo.objectFormat,ptpdev->objectInfo.thumbFormat);
00118 
00119                if (ptpdev->objectInfo.thumbFormat == 0x3801 && numImages < 864 ) {
00120                    sprintf(fname,"/usb2/thumb_%s",ptpdev->objectInfo.filename.getString());
00121                     fp2 = fopen(fname, "wb");                    
00122                     printf("Starting transfer of %s\r\n",fname);
00123                     ptpdev->GetThumb(fileHandle,(void *)&WriteObjectHandles);
00124                     fclose(fp2);
00125                     printf("GetThumb Transaction Complete\r\n");
00126                }
00127                            
00128                if (ptpdev->objectInfo.objectFormat == 0x3801 && numImages < 864 ) {
00129                    sprintf(fname,"/usb2/%s",ptpdev->objectInfo.filename.getString());
00130                    printf("%s -Type: 0x%04x\r\n",fname,ptpdev->objectInfo.objectFormat);
00131                     printf("Starting transfer of %s\r\n",fname);
00132                     fp2 = fopen(fname, "wb");   
00133                     ptpdev->GetObject(fileHandle,(void *)&WriteObjectHandles);
00134                     fclose(fp2);
00135                     printf("GetObject Transaction Complete\r\n");
00136                 }
00137                 numImages--;
00138             }
00139             fclose(fp);
00140 }
00141 
00142 /**
00143 * Thread to Watch for MSD image
00144 */
00145 void msd_task(void const *) {
00146     USBHostMSD msd2("usb2");
00147     
00148     msddev=&msd2;
00149     while(true) {
00150         while(!msd2.connect()) {
00151                 Thread::wait(500);
00152             }
00153             
00154         DIR *dp;
00155         struct dirent *ep;     
00156         dp = opendir ("/usb2");
00157 
00158         if (dp != NULL)
00159         {
00160             ep = readdir (dp);
00161             while (ep!=NULL) {
00162               printf("%s\r\n",ep->d_name);
00163               ep = readdir (dp);
00164             }
00165            (void) closedir (dp);
00166          }
00167          
00168          while(msd2.connect()) {
00169                 Thread::wait(500);
00170          }
00171     }
00172 }
00173 
00174 /**
00175 * Function TO  be called by the menu system to start the execution thread to execute the call.
00176 */ 
00177 void SetCommandGETALLJPG(void) {
00178    command=GETALLJPG;
00179 }
00180 
00181 /**
00182 * Function to display status during image transfers
00183 */
00184 void GetAllJPGStatus(void) {
00185     led=!led;
00186     lcd.cls();
00187     if(ptpdev->dataLeftToTransfer>0) {
00188         lcd.locate(10,0);
00189         lcd.printf("%ld/%ld", ptpdev->dataLeftToTransfer, ptpdev->totalDataToTransfer);
00190         lcd.locate(0,10);
00191         lcd.printf("%s",fname); 
00192     }               
00193 }
00194 
00195 /**
00196 * Thread to watch for the PTP device connected, and commands that need to be executed.
00197 */
00198 void ptp_task2(void const *) {
00199     USBHostPTP ptp;
00200     ptpdev=&ptp;
00201         
00202     int numi,numt;
00203     uint32_t objCount=0;
00204     
00205     while(true) {
00206         while(!ptpdev->connect()) {
00207             Thread::wait(500);
00208         }
00209         
00210         while(!msddev->connected()){
00211             Thread::wait(500);
00212         }
00213         
00214         /* after device connected open a session, get device information, and object handles
00215         */    
00216         ptp.OpenSession();
00217         printf("OpenSession Transaction Complete\r\n\r\n");
00218         ptp.GetDeviceInfo();
00219         printf("GetDeviceInfo Transaction Complete\r\n");
00220         fp2 = fopen("/usb2/objHandles.bin", "wb");
00221         ptp.GetObjectHandles(0xffffffff,0x0000,0x0000,(void *)&WriteObjectHandles);
00222         fclose(fp2);
00223         printf("GetObjecthandles Transaction Complete\r\n");
00224         
00225         //While ptp device connected watch for commands.
00226         while(ptpdev->connected()) {
00227             commandActive=true;
00228             switch(command) {
00229             case GETALLJPG:
00230                 statusFunction=&GetAllJPGStatus;
00231                 GetAllImagesAndThumbs();
00232                 statusFunction=NULL;
00233                 break;
00234             case GETALLJPGTHUMB:
00235                 break;
00236             case GETNUMJPG:
00237                 GetNumberOfThumbsAndImages(&numi,&numt);
00238                 printf("images: %d, thumbs:%d\r\n",numi,numt);
00239                 break;
00240             case GETNUMOBJ:
00241                 ptp.GetNumObjects(&objCount);
00242                 printf("GetNumObjects Transaction Complete - Count:%ld\r\n",objCount);
00243                 break;
00244             case DUMPDEVICEINFO:
00245                 ptp.DumpDeviceInfo();
00246                 break;
00247             case CLOSESESSION:
00248                 ptpdev->CloseSession();
00249                 printf("CloseSession Transaction Complete\r\n");
00250                 break;
00251             default:
00252                 commandActive=false;
00253                 break;
00254             }
00255             command=0x00;
00256             Thread::wait(100);
00257         }
00258     }
00259 }
00260 
00261 ///Menu function to set the Command to be executed. 
00262 void SetCommandGETNUMJPG(void) {
00263    command=GETNUMJPG;
00264 }
00265 
00266 ///Menu function to set the Command to be executed. 
00267 void SetCommandGETNUMOBJ(void) {
00268    command=GETNUMOBJ;
00269 }
00270 
00271 ///Menu function to set the Command to be executed. 
00272 void SetCommandDUMPDEVICEINFO(void) {
00273    command=DUMPDEVICEINFO;
00274 }
00275 
00276 ///Menu function to set the Command to be executed. 
00277 void SetCommandCLOSESESSION(void) {
00278    command=CLOSESESSION;
00279 }
00280 
00281 ///Main fuction to display the Status of the application.
00282 int main() {
00283     lcd.cls();
00284     lcd.locate(10,3);
00285     lcd.printf("Initializing");
00286     Thread ptpTask2(ptp_task2, NULL, osPriorityNormal, 1024 * 4);
00287     Thread msdTask2(msd_task, NULL, osPriorityNormal,  1024 * 4);
00288     Menu rootMenu("root"); 
00289     Menu testMenu("Test menu"); 
00290     testMenu.add(Selection(&SetCommandDUMPDEVICEINFO, 2, NULL, "Dump Device Info")); // The function argument of selection can be added directly
00291     testMenu.add(Selection(&SetCommandGETALLJPG, 2, NULL, "Get All Images")); // The function argument of selection can be added directly
00292     testMenu.add(Selection(&SetCommandGETNUMOBJ, 1, NULL, "Get Number of Objects"));
00293     testMenu.add(Selection(&SetCommandGETNUMJPG, 3, NULL, "Get Number of Images"));
00294     //testMenu.add(Selection(NULL, 4, NULL, "Get Number of Thumbnails"));
00295     //testMenu.add(Selection(NULL, 5, NULL, "Get Number of Thumbnails"));
00296     testMenu.add(Selection(&SetCommandCLOSESESSION, 4, NULL, "Close Session"));
00297     testMenu.add(Selection(NULL, 5, &rootMenu, "  Go back"));  // always add a Selection at the end to point to the parent
00298     Menu aboutMenu("About Menu"); // about menu
00299     aboutMenu.add(Selection(NULL, 0, NULL, "Author:"));
00300     aboutMenu.add(Selection(NULL, 1, NULL, " Dwayne S Dilbeck"));
00301     aboutMenu.add(Selection(NULL, 2, NULL, " 8/29/2013"));
00302     aboutMenu.add(Selection(NULL, 3, NULL, " USB Device Interface:"));
00303     aboutMenu.add(Selection(NULL, 4, NULL, " Architecture,"));
00304     aboutMenu.add(Selection(NULL, 5, NULL, " Protocols,"));
00305     aboutMenu.add(Selection(NULL, 6, NULL, " and programming."));
00306     aboutMenu.add(Selection(NULL, 7, &rootMenu, "  Go back"));
00307     rootMenu.add(Selection(NULL, 0, &testMenu, "TEST MENU"));
00308     rootMenu.add(Selection(NULL, 1, &aboutMenu, "About menu"));   
00309     Navigator navigator(&rootMenu, &lcd);
00310     
00311     while(1) {
00312         if(ptpdev != NULL) {
00313             if(ptpdev->connected()) {
00314                 if(!commandActive) {
00315                     navigator.poll(); 
00316                 } else {
00317                     if(statusFunction != NULL)
00318                        (*statusFunction)();
00319                     else {
00320                         lcd.cls();
00321                         wait_ms(20);
00322                     }
00323                 }
00324                 
00325             } else {
00326                lcd.cls();
00327                lcd.locate(10,3);
00328                lcd.printf("Please connect PTP device.");
00329             }            
00330         }
00331         Thread::wait(200);
00332     }
00333 }
00334 
00335 
00336 
00337 

Known Issues

  • Buffer overflow will halt the mbed device after 6 hours of transfers
  • Method Transaction is unable to SEND Data Containers
  • MSD removal does not change the Data container handler. This should become NULL, when the MSD is removed.

Future Work

  • Find the buffer overflow
  • Implement a PTP Capture Test.
  • Implement send data in method Transaction
  • Implement an Opcode decoder
  • Add Canon extended PTP support.

References

  • PIMA15740
  • PTP Vedor code list
  • Arduino Camera Capture Library
Committer:
jakowisp
Date:
Mon Oct 07 04:58:38 2013 +0000
Revision:
7:ad780ab40f33
Parent:
6:2e2cb26d4079
Child:
9:4ce224f6cfce
Add Code decoder; Change take photo to save the image to storage.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jakowisp 4:a95225ec39ac 1 /**
jakowisp 4:a95225ec39ac 2 * @file main.cpp
jakowisp 4:a95225ec39ac 3 * @brief Function to call USBHostPTP Library
jakowisp 4:a95225ec39ac 4 * @author Dwayne Dilbeck
jakowisp 4:a95225ec39ac 5 * @date 8/23/2013
jakowisp 4:a95225ec39ac 6 *
jakowisp 4:a95225ec39ac 7 * mbed USBHostPTP Library
jakowisp 4:a95225ec39ac 8 *
jakowisp 4:a95225ec39ac 9 * @par Copyright:
jakowisp 4:a95225ec39ac 10 * Copyright (c) 2013 Dwayne Dilbeck
jakowisp 4:a95225ec39ac 11 * @par License:
jakowisp 4:a95225ec39ac 12 * This software is distributed under the terms of the GNU Lesser General Public License
jakowisp 4:a95225ec39ac 13 */
jakowisp 0:ec1356628850 14 #include "mbed.h"
jakowisp 0:ec1356628850 15 #include "C12832_lcd.h"
jakowisp 0:ec1356628850 16 #include "USBHostMSD.h"
jakowisp 0:ec1356628850 17 #include "USBHostPTP.h"
jakowisp 7:ad780ab40f33 18
jakowisp 6:2e2cb26d4079 19 #include "PTPMenu.h"
jakowisp 3:1e2f56de7d5d 20
jakowisp 3:1e2f56de7d5d 21
jakowisp 7:ad780ab40f33 22
jakowisp 4:a95225ec39ac 23 /**
jakowisp 4:a95225ec39ac 24 * Initiate Global variables
jakowisp 4:a95225ec39ac 25 */
jakowisp 0:ec1356628850 26 DigitalOut led(LED1);
jakowisp 0:ec1356628850 27 FILE * fp2;
jakowisp 0:ec1356628850 28 C12832_LCD lcd;
jakowisp 3:1e2f56de7d5d 29 USBHostPTP *ptpdev = NULL;
jakowisp 3:1e2f56de7d5d 30 USBHostMSD *msddev = NULL;
jakowisp 0:ec1356628850 31 char fname[256];
jakowisp 6:2e2cb26d4079 32 PTPMenu *menuobj = NULL;
jakowisp 3:1e2f56de7d5d 33 bool commandActive=false;
jakowisp 3:1e2f56de7d5d 34 void (*statusFunction)(void);
jakowisp 0:ec1356628850 35
jakowisp 7:ad780ab40f33 36
jakowisp 7:ad780ab40f33 37 bool CheckForCode(uint16_t code, char *buffer){
jakowisp 7:ad780ab40f33 38 FILE *fp;
jakowisp 7:ad780ab40f33 39 struct {
jakowisp 7:ad780ab40f33 40 char str[60];
jakowisp 7:ad780ab40f33 41 uint16_t code;
jakowisp 7:ad780ab40f33 42 } temp;
jakowisp 7:ad780ab40f33 43 bool found=false;
jakowisp 7:ad780ab40f33 44
jakowisp 7:ad780ab40f33 45 if( code < 0x9000) {
jakowisp 7:ad780ab40f33 46 fp = fopen("/usb2/PIMACODE.bin", "rb");
jakowisp 7:ad780ab40f33 47 } else {
jakowisp 7:ad780ab40f33 48 fp = fopen("/usb2/canon.bin", "rb");
jakowisp 7:ad780ab40f33 49 }
jakowisp 7:ad780ab40f33 50 if (fp != NULL) {
jakowisp 7:ad780ab40f33 51 while( !found && fread(&temp.code,sizeof(uint16_t),1,fp) >0 ) {
jakowisp 7:ad780ab40f33 52 fread(&temp.str,sizeof(char),60,fp);
jakowisp 7:ad780ab40f33 53 if (code == temp.code) {
jakowisp 7:ad780ab40f33 54 found=true;
jakowisp 7:ad780ab40f33 55 strcpy(buffer,temp.str);
jakowisp 7:ad780ab40f33 56 }
jakowisp 7:ad780ab40f33 57 }
jakowisp 7:ad780ab40f33 58 fclose(fp);
jakowisp 7:ad780ab40f33 59 }
jakowisp 7:ad780ab40f33 60
jakowisp 7:ad780ab40f33 61 return found;
jakowisp 7:ad780ab40f33 62 }
jakowisp 4:a95225ec39ac 63 /**
jakowisp 4:a95225ec39ac 64 * This function is used to handle the raw data recieved via the bulk pipes
jakowisp 4:a95225ec39ac 65 *
jakowisp 4:a95225ec39ac 66 * @param ptp Pointer to the PTP device
jakowisp 4:a95225ec39ac 67 * @param buffer Pointer to the data recieved
jakowisp 4:a95225ec39ac 68 * @param length Total data received to be processed
jakowisp 4:a95225ec39ac 69 *
jakowisp 4:a95225ec39ac 70 * @return Void
jakowisp 4:a95225ec39ac 71 */
jakowisp 0:ec1356628850 72 void WriteObjectHandles(void *ptp,uint8_t *buffer,uint16_t length){
jakowisp 0:ec1356628850 73 int writeResult,errorcode;
jakowisp 0:ec1356628850 74 uint16_t transferLength=length;
jakowisp 0:ec1356628850 75 uint8_t *dataPtr=buffer;
jakowisp 0:ec1356628850 76
jakowisp 0:ec1356628850 77 writeResult=fwrite(dataPtr,sizeof(uint8_t),transferLength,fp2);
jakowisp 0:ec1356628850 78 if( writeResult != transferLength) {
jakowisp 0:ec1356628850 79 errorcode=ferror(fp2);
jakowisp 0:ec1356628850 80 if( errorcode )
jakowisp 0:ec1356628850 81 {
jakowisp 0:ec1356628850 82 printf("\r\nError in writing to file %d\n",errorcode);
jakowisp 0:ec1356628850 83 error("Yucky@!");
jakowisp 0:ec1356628850 84 }
jakowisp 0:ec1356628850 85 }
jakowisp 0:ec1356628850 86 }
jakowisp 0:ec1356628850 87
jakowisp 4:a95225ec39ac 88 /**
jakowisp 4:a95225ec39ac 89 * Test function 0x01
jakowisp 4:a95225ec39ac 90 *
jakowisp 4:a95225ec39ac 91 * @param numberOfImages A pointer to where to write the images on the device
jakowisp 4:a95225ec39ac 92 * @param numberOfThumbs A pointer to where to write the images on the device
jakowisp 4:a95225ec39ac 93 * @return void
jakowisp 4:a95225ec39ac 94 */
jakowisp 2:912d86148549 95 void GetNumberOfThumbsAndImages(int *numberOfImages,int *numberOfThumbs){
jakowisp 2:912d86148549 96 uint32_t fileHandle=0,numImages=0;
jakowisp 2:912d86148549 97 int internalNumberOfImages=0;
jakowisp 2:912d86148549 98 int internalNumberOfThumbs=0;
jakowisp 2:912d86148549 99
jakowisp 2:912d86148549 100 FILE *fp = fopen("/usb2/objHandles.bin", "rb");
jakowisp 2:912d86148549 101 fread(&numImages,sizeof(uint32_t),1,fp);
jakowisp 2:912d86148549 102 while(numImages>0){
jakowisp 2:912d86148549 103 fread(&fileHandle,sizeof(uint32_t),1,fp);
jakowisp 3:1e2f56de7d5d 104 ptpdev->GetObjectInfo(fileHandle);
jakowisp 3:1e2f56de7d5d 105
jakowisp 3:1e2f56de7d5d 106 if (ptpdev->objectInfo.thumbFormat == 0x3801 ) {
jakowisp 2:912d86148549 107 internalNumberOfThumbs++;
jakowisp 2:912d86148549 108 }
jakowisp 3:1e2f56de7d5d 109 if (ptpdev->objectInfo.objectFormat == 0x3801 ) {
jakowisp 2:912d86148549 110 internalNumberOfImages++;
jakowisp 2:912d86148549 111 }
jakowisp 2:912d86148549 112 numImages--;
jakowisp 2:912d86148549 113 }
jakowisp 2:912d86148549 114 fclose(fp);
jakowisp 2:912d86148549 115 *numberOfImages = internalNumberOfImages;
jakowisp 2:912d86148549 116 *numberOfThumbs = internalNumberOfThumbs;
jakowisp 2:912d86148549 117
jakowisp 2:912d86148549 118 }
jakowisp 2:912d86148549 119
jakowisp 4:a95225ec39ac 120 /**
jakowisp 4:a95225ec39ac 121 * Retrieve all thumbnail images and real images that are JPG files.
jakowisp 4:a95225ec39ac 122 */
jakowisp 3:1e2f56de7d5d 123 void GetAllImagesAndThumbs(void) {
jakowisp 0:ec1356628850 124 FILE *fp;
jakowisp 0:ec1356628850 125
jakowisp 0:ec1356628850 126 uint32_t fileHandle=0,numImages=0;
jakowisp 0:ec1356628850 127
jakowisp 3:1e2f56de7d5d 128 printf("objectid,objectinfosize,imagetype,thumbtype\r\n");
jakowisp 3:1e2f56de7d5d 129 fp = fopen("/usb2/objHandles.bin", "rb");
jakowisp 0:ec1356628850 130
jakowisp 0:ec1356628850 131 fread(&numImages,sizeof(uint32_t),1,fp);
jakowisp 0:ec1356628850 132 while(numImages>0){
jakowisp 3:1e2f56de7d5d 133 fread(&fileHandle,sizeof(uint32_t),1,fp);
jakowisp 3:1e2f56de7d5d 134 ptpdev->GetObjectInfo(fileHandle);
jakowisp 4:a95225ec39ac 135 printf("%ld,%x,%x,%x\r\n",numImages,fileHandle,ptpdev->objectInfo.objectFormat,ptpdev->objectInfo.thumbFormat);
jakowisp 3:1e2f56de7d5d 136
jakowisp 3:1e2f56de7d5d 137 if (ptpdev->objectInfo.thumbFormat == 0x3801 && numImages < 864 ) {
jakowisp 3:1e2f56de7d5d 138 sprintf(fname,"/usb2/thumb_%s",ptpdev->objectInfo.filename.getString());
jakowisp 3:1e2f56de7d5d 139 fp2 = fopen(fname, "wb");
jakowisp 0:ec1356628850 140 printf("Starting transfer of %s\r\n",fname);
jakowisp 3:1e2f56de7d5d 141 ptpdev->GetThumb(fileHandle,(void *)&WriteObjectHandles);
jakowisp 0:ec1356628850 142 fclose(fp2);
jakowisp 0:ec1356628850 143 printf("GetThumb Transaction Complete\r\n");
jakowisp 0:ec1356628850 144 }
jakowisp 0:ec1356628850 145
jakowisp 3:1e2f56de7d5d 146 if (ptpdev->objectInfo.objectFormat == 0x3801 && numImages < 864 ) {
jakowisp 3:1e2f56de7d5d 147 sprintf(fname,"/usb2/%s",ptpdev->objectInfo.filename.getString());
jakowisp 3:1e2f56de7d5d 148 printf("%s -Type: 0x%04x\r\n",fname,ptpdev->objectInfo.objectFormat);
jakowisp 0:ec1356628850 149 printf("Starting transfer of %s\r\n",fname);
jakowisp 2:912d86148549 150 fp2 = fopen(fname, "wb");
jakowisp 3:1e2f56de7d5d 151 ptpdev->GetObject(fileHandle,(void *)&WriteObjectHandles);
jakowisp 0:ec1356628850 152 fclose(fp2);
jakowisp 2:912d86148549 153 printf("GetObject Transaction Complete\r\n");
jakowisp 0:ec1356628850 154 }
jakowisp 0:ec1356628850 155 numImages--;
jakowisp 0:ec1356628850 156 }
jakowisp 0:ec1356628850 157 fclose(fp);
jakowisp 3:1e2f56de7d5d 158 }
jakowisp 2:912d86148549 159
jakowisp 4:a95225ec39ac 160 /**
jakowisp 4:a95225ec39ac 161 * Thread to Watch for MSD image
jakowisp 4:a95225ec39ac 162 */
jakowisp 3:1e2f56de7d5d 163 void msd_task(void const *) {
jakowisp 3:1e2f56de7d5d 164 USBHostMSD msd2("usb2");
jakowisp 3:1e2f56de7d5d 165
jakowisp 3:1e2f56de7d5d 166 msddev=&msd2;
jakowisp 3:1e2f56de7d5d 167 while(true) {
jakowisp 3:1e2f56de7d5d 168 while(!msd2.connect()) {
jakowisp 3:1e2f56de7d5d 169 Thread::wait(500);
jakowisp 3:1e2f56de7d5d 170 }
jakowisp 7:ad780ab40f33 171
jakowisp 7:ad780ab40f33 172 Thread::wait(200);
jakowisp 3:1e2f56de7d5d 173 DIR *dp;
jakowisp 3:1e2f56de7d5d 174 struct dirent *ep;
jakowisp 3:1e2f56de7d5d 175 dp = opendir ("/usb2");
jakowisp 3:1e2f56de7d5d 176
jakowisp 3:1e2f56de7d5d 177 if (dp != NULL)
jakowisp 3:1e2f56de7d5d 178 {
jakowisp 3:1e2f56de7d5d 179 ep = readdir (dp);
jakowisp 3:1e2f56de7d5d 180 while (ep!=NULL) {
jakowisp 3:1e2f56de7d5d 181 printf("%s\r\n",ep->d_name);
jakowisp 3:1e2f56de7d5d 182 ep = readdir (dp);
jakowisp 3:1e2f56de7d5d 183 }
jakowisp 3:1e2f56de7d5d 184 (void) closedir (dp);
jakowisp 3:1e2f56de7d5d 185 }
jakowisp 7:ad780ab40f33 186 if(ptpdev!=NULL)
jakowisp 7:ad780ab40f33 187 ptpdev->CodeDecoderFunction= &CheckForCode;
jakowisp 3:1e2f56de7d5d 188
jakowisp 3:1e2f56de7d5d 189 while(msd2.connect()) {
jakowisp 3:1e2f56de7d5d 190 Thread::wait(500);
jakowisp 7:ad780ab40f33 191
jakowisp 3:1e2f56de7d5d 192 }
jakowisp 3:1e2f56de7d5d 193 }
jakowisp 3:1e2f56de7d5d 194 }
jakowisp 3:1e2f56de7d5d 195
jakowisp 6:2e2cb26d4079 196
jakowisp 6:2e2cb26d4079 197 void genericStatus(void) {
jakowisp 6:2e2cb26d4079 198 led=!led;
jakowisp 6:2e2cb26d4079 199 lcd.cls();
jakowisp 6:2e2cb26d4079 200 lcd.locate(10,0);
jakowisp 6:2e2cb26d4079 201 lcd.printf("Please wait....");
jakowisp 3:1e2f56de7d5d 202 }
jakowisp 3:1e2f56de7d5d 203
jakowisp 6:2e2cb26d4079 204 void getAllObjectHandles(void) {
jakowisp 6:2e2cb26d4079 205 fp2 = fopen("/usb2/objHandles.bin", "wb");
jakowisp 6:2e2cb26d4079 206 ptpdev->GetObjectHandles(0xffffffff,0x0000,0x0000,(void *)&WriteObjectHandles);
jakowisp 6:2e2cb26d4079 207 fclose(fp2);
jakowisp 6:2e2cb26d4079 208 printf("GetObjecthandles Transaction Complete\r\n");
jakowisp 6:2e2cb26d4079 209 }
jakowisp 6:2e2cb26d4079 210
jakowisp 6:2e2cb26d4079 211
jakowisp 4:a95225ec39ac 212 /**
jakowisp 4:a95225ec39ac 213 * Function to display status during image transfers
jakowisp 4:a95225ec39ac 214 */
jakowisp 3:1e2f56de7d5d 215 void GetAllJPGStatus(void) {
jakowisp 3:1e2f56de7d5d 216 led=!led;
jakowisp 3:1e2f56de7d5d 217 lcd.cls();
jakowisp 3:1e2f56de7d5d 218 if(ptpdev->dataLeftToTransfer>0) {
jakowisp 3:1e2f56de7d5d 219 lcd.locate(10,0);
jakowisp 3:1e2f56de7d5d 220 lcd.printf("%ld/%ld", ptpdev->dataLeftToTransfer, ptpdev->totalDataToTransfer);
jakowisp 3:1e2f56de7d5d 221 lcd.locate(0,10);
jakowisp 3:1e2f56de7d5d 222 lcd.printf("%s",fname);
jakowisp 3:1e2f56de7d5d 223 }
jakowisp 3:1e2f56de7d5d 224 }
jakowisp 3:1e2f56de7d5d 225
jakowisp 4:a95225ec39ac 226 /**
jakowisp 4:a95225ec39ac 227 * Thread to watch for the PTP device connected, and commands that need to be executed.
jakowisp 6:2e2cb26d4079 228 */void ptp_task2(void const *) {
jakowisp 6:2e2cb26d4079 229
jakowisp 6:2e2cb26d4079 230
jakowisp 3:1e2f56de7d5d 231 USBHostPTP ptp;
jakowisp 6:2e2cb26d4079 232
jakowisp 6:2e2cb26d4079 233
jakowisp 3:1e2f56de7d5d 234 ptpdev=&ptp;
jakowisp 3:1e2f56de7d5d 235
jakowisp 3:1e2f56de7d5d 236 int numi,numt;
jakowisp 3:1e2f56de7d5d 237 uint32_t objCount=0;
jakowisp 3:1e2f56de7d5d 238
jakowisp 3:1e2f56de7d5d 239 while(true) {
jakowisp 3:1e2f56de7d5d 240 while(!ptpdev->connect()) {
jakowisp 3:1e2f56de7d5d 241 Thread::wait(500);
jakowisp 3:1e2f56de7d5d 242 }
jakowisp 3:1e2f56de7d5d 243
jakowisp 3:1e2f56de7d5d 244 while(!msddev->connected()){
jakowisp 3:1e2f56de7d5d 245 Thread::wait(500);
jakowisp 3:1e2f56de7d5d 246 }
jakowisp 6:2e2cb26d4079 247
jakowisp 6:2e2cb26d4079 248 //Thread::wait(500);
jakowisp 6:2e2cb26d4079 249 //ptr=(uint8_t *)&(dev->buffer);
jakowisp 6:2e2cb26d4079 250 //ptr+=1008;
jakowisp 6:2e2cb26d4079 251 //dev->DumpBuffer(ptr,0x20);
jakowisp 3:1e2f56de7d5d 252 ptp.OpenSession();
jakowisp 3:1e2f56de7d5d 253 printf("OpenSession Transaction Complete\r\n\r\n");
jakowisp 3:1e2f56de7d5d 254 ptp.GetDeviceInfo();
jakowisp 3:1e2f56de7d5d 255 printf("GetDeviceInfo Transaction Complete\r\n");
jakowisp 7:ad780ab40f33 256
jakowisp 6:2e2cb26d4079 257
jakowisp 6:2e2cb26d4079 258
jakowisp 6:2e2cb26d4079 259
jakowisp 6:2e2cb26d4079 260
jakowisp 3:1e2f56de7d5d 261
jakowisp 6:2e2cb26d4079 262 /*
jakowisp 6:2e2cb26d4079 263 sprintf(fname,"/usb2/thumb.jpg");
jakowisp 6:2e2cb26d4079 264 fp2 = fopen(fname, "wb");
jakowisp 6:2e2cb26d4079 265 printf("Starting transfer of %s\r\n",fname);
jakowisp 6:2e2cb26d4079 266 ptp.GetObjectInfo(0x00013178);
jakowisp 6:2e2cb26d4079 267 ptp.GetObject(0x00013178,(void *)&WriteObjectHandles);
jakowisp 6:2e2cb26d4079 268 fclose(fp2);
jakowisp 6:2e2cb26d4079 269 printf("GetThumb Transaction Complete\r\n");
jakowisp 6:2e2cb26d4079 270 */
jakowisp 6:2e2cb26d4079 271
jakowisp 6:2e2cb26d4079 272
jakowisp 6:2e2cb26d4079 273
jakowisp 6:2e2cb26d4079 274
jakowisp 6:2e2cb26d4079 275
jakowisp 3:1e2f56de7d5d 276 while(ptpdev->connected()) {
jakowisp 6:2e2cb26d4079 277 if(menuobj->command!=0x00)
jakowisp 6:2e2cb26d4079 278 commandActive=true;
jakowisp 6:2e2cb26d4079 279 switch(menuobj->command) {
jakowisp 3:1e2f56de7d5d 280 case GETALLJPG:
jakowisp 3:1e2f56de7d5d 281 statusFunction=&GetAllJPGStatus;
jakowisp 6:2e2cb26d4079 282 getAllObjectHandles();
jakowisp 3:1e2f56de7d5d 283 GetAllImagesAndThumbs();
jakowisp 3:1e2f56de7d5d 284 break;
jakowisp 3:1e2f56de7d5d 285 case GETALLJPGTHUMB:
jakowisp 3:1e2f56de7d5d 286 break;
jakowisp 3:1e2f56de7d5d 287 case GETNUMJPG:
jakowisp 6:2e2cb26d4079 288 getAllObjectHandles();
jakowisp 3:1e2f56de7d5d 289 GetNumberOfThumbsAndImages(&numi,&numt);
jakowisp 3:1e2f56de7d5d 290 printf("images: %d, thumbs:%d\r\n",numi,numt);
jakowisp 3:1e2f56de7d5d 291 break;
jakowisp 3:1e2f56de7d5d 292 case GETNUMOBJ:
jakowisp 3:1e2f56de7d5d 293 ptp.GetNumObjects(&objCount);
jakowisp 3:1e2f56de7d5d 294 printf("GetNumObjects Transaction Complete - Count:%ld\r\n",objCount);
jakowisp 3:1e2f56de7d5d 295 break;
jakowisp 3:1e2f56de7d5d 296 case DUMPDEVICEINFO:
jakowisp 7:ad780ab40f33 297 statusFunction=&genericStatus;
jakowisp 6:2e2cb26d4079 298 ptp.GetDeviceInfo();
jakowisp 3:1e2f56de7d5d 299 ptp.DumpDeviceInfo();
jakowisp 3:1e2f56de7d5d 300 break;
jakowisp 6:2e2cb26d4079 301 case CAPTUREMODEON:
jakowisp 6:2e2cb26d4079 302 statusFunction=&genericStatus;
jakowisp 6:2e2cb26d4079 303 ptp.Operation(0x9008);
jakowisp 6:2e2cb26d4079 304 ptp.GetDeviceInfo();
jakowisp 6:2e2cb26d4079 305 break;
jakowisp 6:2e2cb26d4079 306 case CAPTUREMODEOFF:
jakowisp 6:2e2cb26d4079 307 statusFunction=&genericStatus;
jakowisp 6:2e2cb26d4079 308 ptp.Operation(0x9009);
jakowisp 6:2e2cb26d4079 309 ptp.GetDeviceInfo();
jakowisp 6:2e2cb26d4079 310 break;
jakowisp 6:2e2cb26d4079 311 case VFINDERON:
jakowisp 6:2e2cb26d4079 312 ptp.Operation(0x900b);
jakowisp 6:2e2cb26d4079 313 break;
jakowisp 6:2e2cb26d4079 314 case VFINDEROFF:
jakowisp 6:2e2cb26d4079 315 ptp.Operation(0x900c);
jakowisp 6:2e2cb26d4079 316 break;
jakowisp 6:2e2cb26d4079 317 case TAKEPHOTO:
jakowisp 6:2e2cb26d4079 318 statusFunction=&genericStatus;
jakowisp 7:ad780ab40f33 319 printf("Set Prop: %x\r\n",ptp.SetDevicePropValue(0xd029,0xd));
jakowisp 6:2e2cb26d4079 320 printf("Focus Lock: %x\r\n",ptp.Operation(0x9014));
jakowisp 6:2e2cb26d4079 321 printf("Image Capture: %x\r\n",ptp.Operation(0x901a));
jakowisp 6:2e2cb26d4079 322 break;
jakowisp 3:1e2f56de7d5d 323 case CLOSESESSION:
jakowisp 3:1e2f56de7d5d 324 ptpdev->CloseSession();
jakowisp 3:1e2f56de7d5d 325 printf("CloseSession Transaction Complete\r\n");
jakowisp 3:1e2f56de7d5d 326 break;
jakowisp 3:1e2f56de7d5d 327 default:
jakowisp 3:1e2f56de7d5d 328 commandActive=false;
jakowisp 3:1e2f56de7d5d 329 break;
jakowisp 3:1e2f56de7d5d 330 }
jakowisp 6:2e2cb26d4079 331 statusFunction=NULL;
jakowisp 6:2e2cb26d4079 332 menuobj->command=0x00;
jakowisp 3:1e2f56de7d5d 333 Thread::wait(100);
jakowisp 0:ec1356628850 334 }
jakowisp 0:ec1356628850 335 }
jakowisp 0:ec1356628850 336 }
jakowisp 0:ec1356628850 337
jakowisp 4:a95225ec39ac 338 ///Main fuction to display the Status of the application.
jakowisp 0:ec1356628850 339 int main() {
jakowisp 0:ec1356628850 340 lcd.cls();
jakowisp 0:ec1356628850 341 lcd.locate(10,3);
jakowisp 0:ec1356628850 342 lcd.printf("Initializing");
jakowisp 3:1e2f56de7d5d 343 Thread ptpTask2(ptp_task2, NULL, osPriorityNormal, 1024 * 4);
jakowisp 3:1e2f56de7d5d 344 Thread msdTask2(msd_task, NULL, osPriorityNormal, 1024 * 4);
jakowisp 6:2e2cb26d4079 345 menuobj = new PTPMenu(&lcd);
jakowisp 3:1e2f56de7d5d 346
jakowisp 0:ec1356628850 347 while(1) {
jakowisp 6:2e2cb26d4079 348 if(ptpdev!=NULL) {
jakowisp 3:1e2f56de7d5d 349 if(ptpdev->connected()) {
jakowisp 3:1e2f56de7d5d 350 if(!commandActive) {
jakowisp 6:2e2cb26d4079 351 menuobj->poll();
jakowisp 3:1e2f56de7d5d 352 } else {
jakowisp 6:2e2cb26d4079 353 if(statusFunction!=NULL)
jakowisp 6:2e2cb26d4079 354 (*statusFunction)();
jakowisp 3:1e2f56de7d5d 355 }
jakowisp 3:1e2f56de7d5d 356 } else {
jakowisp 3:1e2f56de7d5d 357 lcd.cls();
jakowisp 3:1e2f56de7d5d 358 lcd.locate(10,3);
jakowisp 3:1e2f56de7d5d 359 lcd.printf("Please connect PTP device.");
jakowisp 3:1e2f56de7d5d 360 }
jakowisp 3:1e2f56de7d5d 361 }
jakowisp 6:2e2cb26d4079 362 Thread::wait(20);
jakowisp 0:ec1356628850 363 }
jakowisp 0:ec1356628850 364 }
jakowisp 7:ad780ab40f33 365